Created
December 18, 2012 22:03
-
-
Save birkin/4332476 to your computer and use it in GitHub Desktop.
Handles authN & authZ, with shib & for development, creates user, & assigns permissions. Adding this class to your models.py allows gives your app a login url handled by view code like that shown below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import json, logging | |
log = logging.getLogger(__name__) | |
class LoginManager( object ): | |
''' | |
# Handles authN & authZ, with shib & for development, creates user, & assigns permissions. | |
# Adding this class to your models.py allows gives your app a login url handled by view code like: | |
def login( request ): | |
log_man = models.LoginManager( | |
REQUEST_META_DICT = request.META, | |
ADMIN_CONTACT = settings_app.ADMIN_CONTACT, | |
SPOOFED_SHIB_JSON = settings_app.SPOOFED_SHIB_JSON, # for local development | |
PERMITTED_ADMINS = settings_app.PERMITTED_ADMINS, | |
GROUP_NAME = settings_app.GROUP_NAME # to assign permissions-group if user is created | |
) | |
if log_man.check_authN() == u'failure': | |
return HttpResponseForbidden( log_man.forbidden_response ) | |
if log_man.check_authZ() == u'failure': | |
return HttpResponseForbidden( log_man.forbidden_response ) | |
if log_man.login_user( request ) == u'failure': # request passed in because its session-object is updated | |
return HttpResponseForbidden( log_man.forbidden_response ) | |
else: | |
return HttpResponseRedirect( u'../../admin/your_app/model/' ) | |
''' | |
def __init__( self, REQUEST_META_DICT, ADMIN_CONTACT, SPOOFED_SHIB_JSON, PERMITTED_ADMINS, GROUP_NAME ): | |
u'''upper-case attributes passed in''' | |
self.REQUEST_META_DICT = REQUEST_META_DICT | |
self.ADMIN_CONTACT = ADMIN_CONTACT | |
self.SPOOFED_SHIB_JSON = SPOOFED_SHIB_JSON | |
self.PERMITTED_ADMINS = PERMITTED_ADMINS | |
self.GROUP_NAME = GROUP_NAME # if user needs to be created | |
self.forbidden_response = u'You are not authorized to use the admin. If you believe you should be, please contact "%s".' % self.ADMIN_CONTACT | |
self.login_name = None # eppn | |
self.first_name, self.last_name, self.email = ( None, None, None ) | |
self.user = None # django user-object | |
self.authN_check, self.authZ_check, self.login_check = ( u'failure', u'failure', u'failure' ) | |
try: | |
self.login_name = self.REQUEST_META_DICT[ u'Shibboleth-eppn' ] | |
self.first_name, self.last_name, self.email = ( self.REQUEST_META_DICT[u'Shibboleth-givenName'], self.REQUEST_META_DICT[u'Shibboleth-sn'], self.REQUEST_META_DICT[u'Shibboleth-mail'].lower() ) | |
log.debug( u'shib info used' ) | |
except Exception as e: | |
log.debug( u'error trying real shib info: %s' % repr(e).decode(u'utf-8', u'replace') ) | |
try: | |
d = json.loads( self.SPOOFED_SHIB_JSON ) | |
log.debug( u'd is: %s' % d ) | |
self.login_name = d[ u'Shibboleth-eppn' ] | |
self.first_name, self.last_name, self.email = ( d[u'Shibboleth-givenName'], d[u'Shibboleth-sn'], d[u'Shibboleth-mail'].lower() ) | |
log.debug( u'spoofed shib info used' ) | |
except Exception as e2: | |
self.login_name = None | |
log.debug( u'error using SPOOFED_SHIB_JSON (formatted badly?): %s' % repr(e2).decode(u'utf-8', u'replace') ) | |
log.debug( u'LoginManager init() end' ) | |
def check_authN( self ): | |
if self.login_name != None: | |
self.authN_check = u'success' | |
log.debug( u'self.authN_check: %s' % self.authN_check ) | |
return self.authN_check | |
def check_authZ( self ): | |
assert self.authN_check == u'success' | |
if self.login_name in self.PERMITTED_ADMINS: | |
self.authZ_check = u'success' | |
log.debug( u'self.authZ_check: %s' % self.authZ_check ) | |
return self.authZ_check | |
def login_user( self, request ): # request passed in because its session-object is updated | |
from django.contrib import auth | |
assert self.authN_check == u'success'; assert self.authZ_check == u'success' | |
## get or make user | |
try: | |
self.user = auth.models.User.objects.get( username=self.login_name ) | |
except Exception as e: | |
log.debug( u'user-object not found: %s -- will create it' % repr(e).decode(u'utf-8', u'replace') ) | |
self.create_user() | |
## assign group permissions if necessary | |
self.check_permissions() | |
## login | |
self.user.backend = u'django.contrib.auth.backends.ModelBackend' | |
auth.login( request, self.user ) | |
self.login_check = u'success' | |
log.debug( u'self.login_check: %s' % self.login_check ) | |
return self.login_check | |
def create_user( self ): | |
from django.contrib.auth.models import User | |
user = User( username=self.login_name ) | |
user.set_unusable_password() | |
user.first_name, user.last_name, user.email = ( self.first_name, self.last_name, self.email ) | |
user.is_staff = True # allows admin access | |
user.save() | |
self.user = user | |
log.debug( u'user created' ) | |
def check_permissions( self ): | |
from django.contrib.auth.models import Group | |
group = Group.objects.get( name=self.GROUP_NAME ) | |
if not group in self.user.groups.all(): | |
self.user.groups.add( group ) | |
log.debug( u'self.user.groups.all(): %s' % self.user.groups.all() ) | |
# end class LoginManager() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment