tsunami

log in
history

Understanding Pyramid's authenticated userid

Luke Breuer
2014-02-07 00:37 UTC

def username(request):
    if authenticated_userid(request):
        log.debug('get_username')
        return Person.by_id(authenticated_userid(request)).username
    else:
        return None

@view_config(...)
def threadlist(request):
    log.debug('view_begin')
    threads = DBSession.query(...)
    log.debug('done_query')
    return {
        'threads': threads, 
        'username' : username(request),
        'nothing': log.debug('view_end'),
    }

def groupfinder(userid, request):
    log.debug('groupfinder')
    p = Person.by_id(userid)
    if p:
        return ['g:%d' % p.permission_group_id, 'g:0']

Truncated logger output:
view_begin
SELECT "Thread".id
done_query
get_username
groupfinder
SELECT "Person".id   <-- username(...) authenticated_userid 1st call
groupfinder
SELECT "Person".id   <-- username(...) authenticated_userid 2nd call
SELECT "Person".id   <-- username(...) Person.by_id
view_end

If I remove the call to username(request) in threadlist:
view_begin
SELECT "Thread".id
done_query
view_end

authenticated_userid(...) calls the callback function:
    authn_policy = AuthTktAuthenticationPolicy(
        settings['auth.secret'],
        callback=groupfinder,
        hashalg='sha512',
    )

Note that authenticated_userid(...) contains:
        If no callback is registered, this will be the same as
        unauthenticated_userid.

Note that unauthenticated_userid(...) just checks a cookie:
    def unauthenticated_userid(self, request):
        """ The userid key within the auth_tkt cookie."""
        result = self.cookie.identify(request)
        if result:
            return result['userid']

Note that once remember is called to save the cookie, and as long as that cookie is valid, further actual authentication is done by callback, typically called groupfinder—but only if authenticated_userid is called, not if unauthenticated_userid is called.

Note that auth ticket cookies are signed.
links