Skip to content

Instantly share code, notes, and snippets.

@rslinckx
Created October 14, 2010 20:49
Show Gist options
  • Save rslinckx/627023 to your computer and use it in GitHub Desktop.
Save rslinckx/627023 to your computer and use it in GitHub Desktop.
Suggested improvements of Flask-Principal
import logging
log = logging.getLogger(__name__)
from functools import wraps
from flask import session, request, g
from flaskext.principal import Principal as RealPrincipal, identity_loaded, Identity, AnonymousIdentity
__all__ = ['Principal']
class UserIdentity(Identity):
def __init__(self, user, auth_type=''):
super(UserIdentity, self).__init__(user.id, auth_type=auth_type)
self.user = user
@property
def id(self):
return self.name
def wrap_identity(f):
@wraps(f)
def decorate(*args, **kwargs):
result = f(*args, **kwargs)
user, auth_type = result or (None, None)
if user is not None:
return UserIdentity(user, auth_type)
return decorate
class Principal(RealPrincipal):
def __init__(self, app=None):
super(Principal, self).__init__(use_sessions=False)
if app is not None:
self.init_app(app)
self.get_user_by_id = lambda id: None
self.get_user_by_login = lambda login, password: None
def init_app(self, app):
self._init_app(app)
self.lowercase_login = app.config.get('AUTHENTIFIER_LOWERCASE_LOGIN', False)
loaders = app.config.get('AUTHENTIFIER_AUTH_TYPES', ['form', 'http-basic', 'session'])
if 'form' in loaders:
self.login_paths = app.config['AUTHENTIFIER_LOGIN_PATHS']
self.identity_loader(self.authenticate_form)
if 'http-basic' in loaders:
self.identity_loader(self.authenticate_http_basic)
if 'session' in loaders:
self.identity_loader(self.authenticate_session)
self.identity_saver(self.remember_session)
app.before_request(lambda: self.ensure_user(g.identity))
identity_loaded.connect_via(app)(lambda app, identity: self.ensure_user(identity))
# Decorators
def user_by_id(self, f):
self.get_user_by_id = f
return f
def user_by_login(self, f):
self.get_user_by_login = f
return f
# Public API
def logout(self):
self.set_identity(AnonymousIdentity())
def login(self, user):
self.set_identity(UserIdentity(user, 'manual'))
# Helpers for events
@wrap_identity
def authenticate_form(self):
if request.path in self.login_paths and request.method == 'POST':
login, password = request.form.get('login', u''), request.form.get('password', u'')
if self.lowercase_login:
login = login.lower()
if login:
return (self.get_user_by_login(login, password), 'form')
@wrap_identity
def authenticate_http_basic(self):
a = request.authorization
if a and a['username']:
return (self.get_user_by_login(a['username'], a['password']), 'http-basic')
@wrap_identity
def authenticate_session(self):
uid = session.get('uid')
if uid:
return (self.get_user_by_id(uid), 'session')
def remember_session(self, identity):
if not isinstance(identity, AnonymousIdentity):
session['uid'] = identity.id
elif 'uid' in session:
del session['uid']
session.modified = True
def ensure_user(self, identity):
g.user = getattr(identity, 'user', None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment