Paul Yin
Paul Yin

Reputation: 1759

Authentication/Authorization implement in pyramid

I have follow the documentation Group-Level Security
write these:

def groupfinder(userid, request):
    print '#'*80
    print userid
    role = DBSession.query(Role)....

    if role.name == "Admin":
        return ['g:admin']


class RootFactory(object):
        __acl__ = [
            (Allow, Everyone, 'view'),
            (Allow, Authenticated, 'edit'),
            (Allow, 'g:admin', 'admin')
        ]

        def __init__(self, request):
            pass


authn_policy = AuthTktAuthenticationPolicy(
    settings['auth.secret'],
    callback=groupfinder,
)

it worked, but every page loaded it query the DB repeatedly
shoud it be just return the permission first time when user login?
or maybe I'm doing the wrong way...

and how do I know the permission "g:admin" in templates like mako

Upvotes: 1

Views: 794

Answers (1)

Michael Merickel
Michael Merickel

Reputation: 23331

Your groupfinder has a subtle bug right now. It should always return a list if the user is valid. Only if there is no user should it return None. Right now you only return a list if the user is an admin, so normal users will never be recognized.

def groupfinder(userid, request):
    print '#'*80
    print userid
    role = DBSession.query(Role)....

    if role is not None:
        principals = []
        if role.name == "Admin":
            principals.append('g:admin')
        return principals

Notice how we always return a list, unless role is None.

Next, you asked about performance. Pyramid doesn't attempt to cache anything. You can, however, handle this easily yourself. The typical way of doing this is adding a cached (reified) property on your request object that contains the role or user. That way every time the groupfinder is invoked, you'll use the cached role instead of querying for it again. This pattern is demonstrated here.

how do I know the permission "g:admin" in templates like mako

Well 'g:admin' is actually a principal in the authentication jargon of Pyramid. 'admin' (the third element of your access control entry) is the permission. Principals are treated as an implementation detail that just helps us map things to permissions. In the end we really just care about the permission when dealing with access/authorization.

To see if a user has that permission in your template you can use pyramid.security.has_permission('admin', request.context, request). You can replace request.context with any object that has an __acl__ on it, but request.context will be your RootFactory in this scenario (which is what you want).

Upvotes: 6

Related Questions