2009-08-13 6 views
6

Je ne peux pas comprendre pourquoi la permission requise décorateur ne fonctionne pas. Je voudrais autoriser l'accès à une vue uniquement pour les membres du personnel. J'ai essayépermission_required décorateur ne fonctionne pas pour moi

@permission_required('request.user.is_staff',login_url="../admin") 
def series_info(request): 
    ... 

et aussi

@permission_required('user.is_staff',login_url="../admin") 
def series_info(request): 
    ... 

En tant que super-utilisateur, je peux accéder à la vue, mais tous les utilisateurs que je crée que le personnel ne peut y accéder et sont redirigés vers la page URL de connexion. J'ai testé le décorateur login_required et ça marche bien.

Répondre

22

permission_required() doit être passé un nom d'autorisation, pas une expression Python dans une chaîne. Essayez ceci:

from contrib.auth.decorators import user_passes_test 
def staff_required(login_url=None): 
    return user_passes_test(lambda u: u.is_staff, login_url=login_url) 

@staff_required(login_url="../admin") 
def series_info(request) 
... 

Merci. Cela fonctionne. Avez-vous un exemple de comment utiliser permission_required? De la documentation docs.djangoproject.com/fr/1.0/... et djangobook.com/fr/2.0/chapter14 Je pensé que ce que je devais devrait fonctionner.

Relisez les liens que vous avez publiés; permission_required() testera si un utilisateur a reçu une autorisation particulière. Il ne teste pas les attributs de l'objet utilisateur.

De http://www.djangobook.com/en/2.0/chapter14/:

def vote(request): 
    if request.user.is_authenticated() and request.user.has_perm('polls.can_vote')): 
     # vote here 
    else: 
     return HttpResponse("You can't vote in this poll.") 

    # 
    # 
# # # 
    ### 
    # 

def user_can_vote(user): 
    return user.is_authenticated() and user.has_perm("polls.can_vote") 

@user_passes_test(user_can_vote, login_url="/login/") 
def vote(request): 
    # vote here 

    # 
    # 
# # # 
    ### 
    # 

from django.contrib.auth.decorators import permission_required 

@permission_required('polls.can_vote', login_url="/login/") 
def vote(request): 
    # vote here 
+0

Merci. Cela fonctionne. Avez-vous un exemple d'utilisation de permission_required? De la documentation http://docs.djangoproject.com/fr/1.0/topics/auth/#the-permission-required-decorator et http://www.djangobook.com/fr/2.0/chapter14/ Je pensais ce que je a dû travailler. – Mitch

+0

Ah. Je vois. Merci d'avoir persévéré. – Mitch

+2

Pourriez-vous expliquer ce qui se passe avec le paramètre ** 'polls.can_vote' ** à la fin? Quel est le but et à quoi cela fait-il référence? Est-ce peut-être le nom du groupe, le doit être un membre de? –

1

Voici un exemple de comportement que je ne comprends pas. Je crée un utilisateur, demande et décore une fonction de test avec la permission permission_required pour 'is_staff'. Si l'utilisateur est superutilisateur, l'accès est accordé à la fonction de test. Si l'utilisateur n'a que is_staff = True, l'accès n'est pas accordé.

from django.http import HttpRequest 
from django.contrib.auth.models import User 
from django.contrib.auth.decorators import permission_required 

@permission_required('is_staff') 
def test(dummy='dummy'): 
    print 'In test' 

mb_user = User.objects.create_user('mitch', '[email protected]', 'mbpassword') 
mb_user.is_staff = True 

req = HttpRequest() 
req.user = mb_user 

test(req) # access to test denied - redirected 

req.user.is_staff = False 

test(req) # same as when is_staff is True 

req.user.is_superuser = True 
test(req) # access to test allowed 
+1

is_staff est un attribut de l'objet utilisateur, pas une permission. –

3

Voilà comment je le ferais:

from django.contrib.admin.views.decorators import staff_member_required 

@staff_member_required 
def series_info(request): 
    ... 

La documentation dit à propos staff_member_required:

Décorateur pour des vues qui vérifie que l'utilisateur est connecté et est un membre du personnel , affichant la page de connexion si nécessaire.

0

Par ailleurs, si vous utilisez des vues de classe, vous devez envelopper votre décorateur dans le décorateur method_decorator (allez comprendre):

class MyView(DetailView): 
    ... 
    @method_decorator(permission_required('polls.can_vote', login_url=reverse_lazy('my_login'))) 
    def dispatch(self, request, *args, **kwargs): 
     .... blah .... 

class MyModel(models.Model): 
    ... 
    def has_perm(self perm, obj=None): 
     if perm == 'polls.canvote': 
      return self.can_vote() 
+1

pour 'Django> = 1.9' vous pouvez utiliser [PermissionRequiredMixin] (https://docs.djangoproject.com/en/dev/topics/auth/default/#the-permissionrequiredmixin-mixin) avec' Class Based Views' –

0

Cela fonctionne pour moi sur mon « projet » table/modèle:

@permission_required('myApp.add_project') 
def create(request): 
    # python code etc... 

De toute évidence, changez le add_project en add_ [quel que soit votre modèle/table]. Pour l'éditer serait:

@permission_required ('myApp.edit_project ')

et supprimer:

@permission_required (' myApp.delete_project ')

Mais je trouve que la chose clé est de vous assurer que vos tables auth sont correctement configurés. C'est ce qui m'a causé des problèmes. Voici une requête SQL MySQL que j'ai écrite pour vérifier les permissions si vous utilisez des groupes. Cela devrait fonctionner dans la plupart des dBs:

select usr.id as 'user id',usr.username,grp.id as 'group id',grp.name as 'group name',grpu.id as 'auth_user_groups',grpp.id as 'auth_group_permissions',perm.name,perm.codename 
from auth_user usr 
left join auth_user_groups grpu on usr.id = grpu.user_id 
left join auth_group grp on grpu.group_id = grp.id 
left join auth_group_permissions grpp on grp.id = grpp.group_id 
left join auth_permission perm on grpp.permission_id = perm.id 
order by usr.id; 

J'ai trouvé que mes autorisations ne sont pas mis en place correctement, et regardez également pour la table django_content_type qui doit avoir des lignes pour chaque application et table pour chacun ajouter, modifier, supprimer . Donc, si vous avez une table de projet, vous devriez voir ceci dans django_content_type:

id   [generated by dB] 
app_label myApp 
model  project 

Si vous rencontrez des problèmes Une autre bonne idée est de permettre et d'utiliser l'application admin django. Cela vous montrera où vos problèmes sont, et en mettant en place des autorisations de test, les utilisateurs et les groupes, vous pouvez ensuite examiner les tables discutées ci-dessus pour voir ce qui est inséré où. Cela vous donnera une bonne idée du fonctionnement des autorisations auth. J'écris ceci pour peut-être sauver quelqu'un de devoir passer quelques heures à déterminer ce que j'ai fait!