Django-guardian: Autorisations globales vs autorisations d'objet

Créé le 22 déc. 2015  ·  16Commentaires  ·  Source: django-guardian/django-guardian

Il semble y avoir un certain nombre de bogues dus à certaines routines utilisant des autorisations globales et d'autres utilisant uniquement des autorisations d'objet. Ferme les bogues associés et les référence ici.

API change Enhancement

Tous les 16 commentaires

Oui à ça !

permission_required_or_403 a le paramètre accept_global_perms, mais il n'y a aucun moyen de faire la même chose avec get_obj_perms

Je propose une balise get_obj_perms_with_global qui inclut des perms globales.

Je ne sais pas si vous avez déjà commencé dans cette voie, mais je vais commencer à travailler sur un patch pour le faire ; si vous avez déjà commencé n'hésitez pas à m'arrêter :)

PS Je pense qu'il y a un argument à faire valoir que le comportement par défaut devrait être d'inclure des autorisations globales, il me semble que lorsque vous demandez "l'utilisateur X peut-il faire Y à l'objet Z" cela implique de vérifier tous les utilisateurs/objets, groupes/objets , autorisations utilisateur/globales, de groupe/globales. Mais c'est peut-être juste à cause de la façon dont je l'utilise.

Cela dit, il est assez simple de vérifier les autorisations globales séparément... Hrmmm.

Pesticules : il y a suffisamment de problèmes sur le tuteur pour montrer à quel point cela est déroutant. Nous en obtenons un peu tous les six mois ... si request.user.has_access('foo', obj) devrait être vrai s'ils ont des autorisations globales mais pas des autorisations au niveau de l'objet. Écrire le chèque deux fois, c'est dégoûtant.

Que doit-il se passer pour que cela change ?

Je pense que quelqu'un a besoin d'écrire une pull request... Idéalement de manière à ne pas casser le code existant (si c'est sain et faisable ou non, je ne sais pas).

Ancien problème, mais je ne vois pas encore de pull request. Des nouvelles de celui-ci ? Je rencontre le même comportement, qui je pense n'est pas très prévisible. Merci beaucoup !

J'ai ajouté quelques commentaires à #49 car cela avait plus d'informations sur la question de savoir si et comment se replier sur les globales lorsque le niveau de l'objet échoue. Je ne sais pas si les problèmes clos soulèvent une notification, alors j'ajoute ceci ici.

En fonction des décisions de conception prises, j'ai l'intention de travailler sur certaines de ces questions.

Je serais heureux d'aider avec ces problèmes.

327 me semble fixe.

```
brandon=Person.objects.get(first_name='BRANDON')
brandon.is_superuser
Faux

ecole=Ecole.objects.get(pk=1)

get_users_with_perms(school, attach_perms=True, with_superusers=False, with_group_users=False)
{}

assign_perm('add_school', brandon, école)

get_users_with_perms(school, attach_perms=True, with_superusers=False, with_group_users=False)
{: ['add_school']}

mehmet=Person.objects.get(first_name='Mehmet')
mehmet.is_superuser
Vrai

get_users_with_perms(school, attach_perms=True, with_superusers=True, with_group_users=False)
{: [],: ['add_school', 'change_school', 'delete_school']}

assign_perm('add_school', mehmet, école)

get_users_with_perms(school, attach_perms=True, with_superusers=True, with_group_users=False)
{: [],: ['add_school', 'change_school', 'delete_school']}

get_users_with_perms(school, attach_perms=True, with_superusers=False, with_group_users=False)
{: ['add_school'],: ['add_school']}

Sur #155 :

L'addition des deux lignes suivantes est demandée à get_obj_perms_field_choices (self) :

        if self.exclude_default:
            choices = list(set(choices).intersection(self.obj._meta.permissions))

pour exclure les autorisations par défaut du modèle. Tout d'abord, je ne sais pas comment intersection ferait cela. Deuxièmement, cela ne semble pas être lié aux autorisations objet vs modèle. Merci de me corriger si j'oublie quelque chose.

Mais, en examinant cela, j'ai remarqué qu'il doit y avoir une séparation des autorisations d'objet et de modèle dans :

    def save_obj_perms(self):
        """
        Saves selected object permissions by creating new ones and removing
        those which were not selected but already exists.

        Should be called *after* form is validated.
        """
        perms = self.cleaned_data[self.get_obj_perms_field_name()]
        model_perms = [c[0] for c in self.get_obj_perms_field_choices()]

        to_remove = set(model_perms) - set(perms)
        for perm in to_remove:
            remove_perm(perm, self.user, self.obj)

        for perm in perms:
            assign_perm(perm, self.user, self.obj)

Il semble qu'il enregistre au niveau de l'objet quelle que soit l'autorisation manquante, alors qu'à mon avis, toute autorisation disponible au niveau du modèle doit être ignorée ou une option à cette fin doit être fournie.

Je pense qu'un paramètre global tel que GUARDIAN_FALLBACK_TO_MODEL=False et un argument aux méthodes applicables telles que fallback_to_model=False nécessaires pour délimiter correctement les autorisations d'objet et les autorisations de modèle. La valeur par défaut de False assure la rétrocompatibilité. Si l'un des paramètres global ou de l'argument est True, le repli doit avoir lieu.

+1 pour GUARDIAN_FALLBACK_TO_MODEL.

Selon la discussion sur # 49, je pense que ce paramètre fonctionnerait également bien pour contrôler si ObjectPermissionBackend était explicite ou non.

J'ai créé une pull request (#546). Il permet aux fonctions de vérification dans l'option core.py de se replier sur (ou d'inclure) les autorisations au niveau du modèle. D'autres modules doivent également être revus. Je prévois de les revoir au fur et à mesure que je les utilise. Si quelqu'un souhaite se lancer, le bienvenu.

Il semble que le #327 n'existe plus. #332 est corrigé par la pull request ci-dessus si elle est acceptée. Il ne reste qu'un seul problème secondaire lié au #155 (mentionné ci-dessus). Si cela était également réglé (ou déplacé vers un problème distinct), ce problème pourrait être clos, je pense.

Les autorisations globales ne sont toujours pas respectées pour les autorisations au niveau de l'objet si elles sont définies, ai-je tort ici ?

u = User.objects.get(id=1)
c = Client.objects.get(id=1)
assign_perm('core.change_client', u)
u = User.objects.get(id=1)  # reloading user for perm refresh
u.has_perm('core.change_client')  # True
u.has_perm('core.change_client', c)  # False
u.has_perm('change_client', c)  # False
get_perms(u, c)  # []

Et à quoi sert le paramètre GUARDIAN_GLOBAL_PERMISSIONS_CARRY_OVER ou FALLBACK_TO_MODEL ? Ni l'un ni l'autre ne semble être documenté.

Ne suffirait-il pas d'ajouter ceci à core.py ?

get_user_perms:126 qui semble être le centre de toutes les vérifications des autorisations des utilisateurs ; alternativement déclenchable à l'aide d'un indicateur booléen

def get_user_perms(self, obj):
    # ....
    user_global_perms = Permission.objects.filter(content_type=ctype)\
                                        .filter(user=self.user)\
                                        .values_list('codename', flat=True)
    user_object_perms = user_perms_qs.values_list("codename", flat=True)
    user_perms = list(chain(user_global_perms, user_object_perms))
    return user_perms
Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

Dzejkob picture Dzejkob  ·  28Commentaires

g-as picture g-as  ·  10Commentaires

johnthagen picture johnthagen  ·  9Commentaires

xuhcc picture xuhcc  ·  10Commentaires

lukaszb picture lukaszb  ·  14Commentaires