Commit 49700ef6 by Brian Beck

added django-cas code

parent ee6b7d4f
from urllib import urlopen, urlencode
from urlparse import urljoin
from django.conf import settings
defaults = {'CAS_SERVER_URL': None,
'CAS_POPULATE_USER': None,
'CAS_ADMIN_PREFIX': None,
'CAS_LOGIN_URL': '/accounts/login/',
'CAS_LOGOUT_URL': '/accounts/logout/',
'CAS_REDIRECT_URL': '/',
'CAS_REDIRECT_FIELD_NAME': 'next',
}
for key, value in defaults.iteritems():
try:
getattr(settings, key)
except AttributeError:
setattr(settings, key, value)
def get_populate_callback(callback):
if callable(callback):
return callback
try:
dot = callback.rindex('.')
except ValueError:
from django.core import exceptions
error = "Error importing CAS_POPULATE_USER callback: %s" % callback
raise exceptions.ImproperlyConfigured(error)
module_name, func_name = callback[:dot], callback[dot + 1:]
module = __import__(module_name, {}, {}, [''])
try:
func = getattr(module, func_name)
except AttributeError:
from django.core import exceptions
error = "Error importing CAS_POPULATE_USER callback: %s" % callback
raise exceptions.ImproperlyConfigured(error)
assert callable(func)
return func
def populate_user(user):
if settings.CAS_POPULATE_USER:
callback = get_populate_callback(settings.CAS_POPULATE_USER)
return callback(user)
def service_url(request, redirect_to=None):
from django.http import get_host
host = get_host(request)
protocol = request.is_secure() and 'https://' or 'http://'
service = protocol + host + request.path
if redirect_to:
if '?' in service:
service += '&'
else:
service += '?'
service += urlencode({settings.CAS_REDIRECT_FIELD_NAME: redirect_to})
return service
def redirect_url(request):
next = request.GET.get(settings.CAS_REDIRECT_FIELD_NAME)
if not next:
next = request.META.get('HTTP_REFERER', settings.CAS_REDIRECT_URL)
return next
def login_url(service):
params = {'service': service}
url = urljoin(settings.CAS_SERVER_URL, 'login') + '?' + urlencode(params)
if settings.DEBUG: print "Logging in: %s" % url
return url
def validate_url():
return urljoin(settings.CAS_SERVER_URL, 'validate')
def verify(ticket, service):
params = {'ticket': ticket, 'service': service}
url = validate_url() + '?' + urlencode(params)
if settings.DEBUG: print "Verifying ticket: %s" % url
page = urlopen(url)
verified = page.readline().strip()
username = page.readline().strip()
if verified == 'yes':
return username
return None
\ No newline at end of file
from django_cas import verify, populate_user
from models import User
class CASBackend(object):
def authenticate(self, ticket, service):
username = verify(ticket, service)
if username:
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
# Password doesn't matter, it won't be used
password = User.objects.make_random_password()
user = User.objects.create_user(username, '', password)
populate_user(user)
user.save()
else:
# User has logged in before
if not (user.first_name and user.last_name and user.email):
populate_user(user)
user.save()
return user
return None
def get_user(self, user_id):
"""Retrieve the user's entry in the User model if it exists."""
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
from os import path
from django.http import HttpResponseRedirect, HttpResponseForbidden, urlencode
from django.conf import settings
class CASMiddleware(object):
def process_request(self, request):
error = "The Django CAS middleware requires authentication "
"middleware to be installed. Edit your MIDDLEWARE_CLASSES "
"setting to insert 'django.contrib.auth.middleware."
"AuthenticationMiddleware'."
assert hasattr(request, 'user'), error
def process_view(self, request, view_func, view_args, view_kwargs):
admin_prefix = settings.CAS_ADMIN_PREFIX
if admin_prefix:
if not request.path.startswith(admin_prefix):
return None
else:
admin_path = ['django', 'contrib', 'admin', 'views']
view_file = view_func.func_code.co_filename
view_path = path.split(view_file)[0].split(path.sep)[-4:]
if view_path != admin_path:
return None
if request.user.is_authenticated():
if request.user.is_staff:
return None
else:
error = "<h1>Forbidden</h1>"
"<p>You do not have staff privileges.</p>"
return HttpResponseForbidden(error)
field, url = settings.CAS_REDIRECT_FIELD_NAME, settings.CAS_LOGIN_URL
params = urlencode({field: request.get_full_path()})
return HttpResponseRedirect(url + '?' + params)
\ No newline at end of file
from django.db import models
from django.contrib.auth.models import User
\ No newline at end of file
from django.http import HttpResponseRedirect, HttpResponseForbidden, urlencode
from django.conf import settings
from django_cas import redirect_url, service_url
def login(request, next_page=None):
if not next_page:
next_page = redirect_url(request)
if request.user.is_authenticated():
message = "You are logged in as %s." % request.user.username
request.user.message_set.create(message=message)
return HttpResponseRedirect(next_page)
ticket = request.GET.get('ticket')
service = service_url(request, next_page)
if ticket:
from django.contrib.auth import authenticate, login
user = authenticate(ticket=ticket, service=service)
if user is not None:
login(request, user)
name = user.first_name or user.username
message = "Login succeeded. Welcome, %s." % name
user.message_set.create(message=message)
if settings.DEBUG:
print "Please welcome %s to the system." % user
return HttpResponseRedirect(next_page)
else:
error = "<h1>Forbidden</h1><p>Login failed.</p>"
return HttpResponseForbidden(error)
else:
url = login_url(service)
return HttpResponseRedirect(url)
def logout(request, next_page=None):
from django.contrib.auth import logout
logout(request)
if not next_page:
next_page = redirect_url(request)
return HttpResponseRedirect(next_page)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment