Skip to content

Instantly share code, notes, and snippets.

@birkin
Created December 18, 2012 22:03
Show Gist options
  • Save birkin/4332476 to your computer and use it in GitHub Desktop.
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.
# -*- 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