--- /dev/null
+django-cas-provider
+
+Chris Williams <chris@nitron.org>
+
+TODO: Write documentation
--- /dev/null
+from django.conf import settings
+
+__all__ = []
+
+_DEFAULTS = {
+ 'CAS_TICKET_EXPIRATION': 5, # In minutes
+}
+
+for key, value in _DEFAULTS.iteritems():
+ try:
+ getattr(settings, key)
+ except AttributeError:
+ setattr(settings, key, value)
+ except ImportError:
+ pass
\ No newline at end of file
--- /dev/null
+from django.contrib import admin
+
+from models import ServiceTicket, LoginTicket
+
+class ServiceTicketAdmin(admin.ModelAdmin):
+ pass
+admin.site.register(ServiceTicket, ServiceTicketAdmin)
+
+class LoginTicketAdmin(admin.ModelAdmin):
+ pass
+admin.site.register(LoginTicket, LoginTicketAdmin)
\ No newline at end of file
--- /dev/null
+from django import forms
+from django.contrib.auth.forms import AuthenticationForm
+from django.contrib.auth import authenticate
+
+from utils import create_login_ticket
+
+class LoginForm(forms.Form):
+ username = forms.CharField(max_length=30)
+ password = forms.CharField(widget=forms.PasswordInput)
+ #warn = forms.BooleanField(required=False) # TODO: Implement
+ lt = forms.CharField(widget=forms.HiddenInput, initial=create_login_ticket)
+ def __init__(self, service=None, renew=None, gateway=None, request=None, *args, **kwargs):
+ super(LoginForm, self).__init__(*args, **kwargs)
+ self.request = request
+ if service is not None:
+ self.fields['service'] = forms.CharField(widget=forms.HiddenInput, initial=service)
\ No newline at end of file
--- /dev/null
+K 25
+svn:wc:ra_dav:version-url
+V 47
+/svn/!svn/ver/170/trunk/registration/management
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/svn/!svn/ver/170/trunk/registration/management/__init__.py
+END
--- /dev/null
+9
+
+dir
+170
+http://django-registration.googlecode.com/svn/trunk/registration/management
+http://django-registration.googlecode.com/svn
+
+
+
+2008-09-22T10:00:14.397881Z
+170
+ubernostrum
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+b970a8a1-db28-0410-9b79-8b7e580363d3
+\f
+commands
+dir
+\f
+__init__.py
+file
+
+
+
+
+2009-02-18T02:12:14.000000Z
+d41d8cd98f00b204e9800998ecf8427e
+2008-09-22T10:00:14.397881Z
+170
+ubernostrum
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+\f
--- /dev/null
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/svn/!svn/ver/170/trunk/registration/management/commands
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/svn/!svn/ver/170/trunk/registration/management/commands/__init__.py
+END
+cleanupregistration.py
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/svn/!svn/ver/170/trunk/registration/management/commands/cleanupregistration.py
+END
--- /dev/null
+9
+
+dir
+170
+http://django-registration.googlecode.com/svn/trunk/registration/management/commands
+http://django-registration.googlecode.com/svn
+
+
+
+2008-09-22T10:00:14.397881Z
+170
+ubernostrum
+
+
+svn:special svn:externals svn:needs-lock
+
+
+
+
+
+
+
+
+
+
+
+b970a8a1-db28-0410-9b79-8b7e580363d3
+\f
+__init__.py
+file
+
+
+
+
+2009-02-18T02:12:14.000000Z
+d41d8cd98f00b204e9800998ecf8427e
+2008-09-22T10:00:14.397881Z
+170
+ubernostrum
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+\f
+cleanupregistration.py
+file
+
+
+
+
+2009-02-18T02:12:14.000000Z
+2fc6dce3e47cc12aafd11130c6c8b45e
+2008-09-22T10:00:14.397881Z
+170
+ubernostrum
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+630
+\f
--- /dev/null
+"""
+A management command which deletes expired accounts (e.g.,
+accounts which signed up but never activated) from the database.
+
+Calls ``RegistrationProfile.objects.delete_expired_users()``, which
+contains the actual logic for determining which accounts are deleted.
+
+"""
+
+from django.core.management.base import NoArgsCommand
+from django.core.management.base import CommandError
+
+from registration.models import RegistrationProfile
+
+
+class Command(NoArgsCommand):
+ help = "Delete expired user registrations from the database"
+
+ def handle_noargs(self, **options):
+ RegistrationProfile.objects.delete_expired_users()
--- /dev/null
+"""
+A management command which deletes expired service tickets (e.g.,
+from the database.
+
+Calls ``ServiceTickets.objects.delete_expired_users()``, which
+contains the actual logic for determining which accounts are deleted.
+
+"""
+
+from django.core.management.base import NoArgsCommand
+from django.core.management.base import CommandError
+from django.conf import settings
+
+import datetime
+
+from cas_provider.models import ServiceTicket
+
+class Command(NoArgsCommand):
+ help = "Delete expired service tickets from the database"
+
+ def handle_noargs(self, **options):
+ tickets = ServiceTicket.objects.all()
+ for ticket in tickets:
+ expiration = datetime.timedelta(minutes=settings.CAS_TICKET_EXPIRATION)
+ if datetime.datetime.now() > ticket.created + expiration:
+ print "Deleting %s..." % ticket.ticket
+ ticket.delete()
+ else:
+ print "%s not expired..." % ticket.ticket
\ No newline at end of file
--- /dev/null
+from django.db import models
+from django.contrib.auth.models import User
+
+class ServiceTicket(models.Model):
+ user = models.ForeignKey(User)
+ service = models.URLField(verify_exists=False)
+ ticket = models.CharField(max_length=256)
+ created = models.DateTimeField(auto_now=True)
+
+ def __unicode__(self):
+ return "%s (%s) - %s" % (self.user.username, self.service, self.created)
+
+class LoginTicket(models.Model):
+ ticket = models.CharField(max_length=32)
+ created = models.DateTimeField(auto_now=True)
+
+ def __unicode__(self):
+ return "%s - %s" % (self.ticket, self.created)
\ No newline at end of file
--- /dev/null
+from django.conf.urls.defaults import *
+
+from views import *
+
+urlpatterns = patterns('',
+ url(r'^login/', login),
+ url(r'^validate/', validate),
+ url(r'^logout/', logout),
+)
\ No newline at end of file
--- /dev/null
+from random import Random
+import string
+
+from models import ServiceTicket, LoginTicket
+
+def _generate_string(length=8, chars=string.letters + string.digits):
+ return ''.join(Random().sample(string.letters+string.digits, length))
+
+def create_service_ticket(user, service):
+ ticket_string = 'ST-' + _generate_string(29) # Total ticket length = 29 + 3 = 32
+ ticket = ServiceTicket(service=service, user=user, ticket=ticket_string)
+ ticket.save()
+ return ticket
+
+def create_login_ticket():
+ ticket_string = 'LT-' + _generate_string(29)
+ ticket = LoginTicket(ticket=ticket_string)
+ ticket.save()
+ return ticket_string
\ No newline at end of file
--- /dev/null
+from django.http import HttpResponse, HttpResponseForbidden, HttpResponseRedirect
+from django.shortcuts import get_object_or_404, render_to_response, get_list_or_404
+from django.core.urlresolvers import reverse
+from django.core.exceptions import SuspiciousOperation
+from django.template import RequestContext
+from django.contrib.auth.models import User
+from django.contrib.auth import authenticate
+from django.contrib.auth import login as auth_login, logout as auth_logout
+
+from forms import LoginForm
+from models import ServiceTicket, LoginTicket
+from utils import create_service_ticket
+
+__all__ = ['login', 'validate', 'logout']
+
+def login(request, template_name='cas/login.html', success_redirect='/accounts/'):
+ service = request.GET.get('service', None)
+ if request.user.is_authenticated():
+ if service is not None:
+ ticket = create_service_ticket(request.user, service)
+ if service.find('?') == -1:
+ return HttpResponseRedirect(service + '?ticket=' + ticket.ticket)
+ else:
+ return HttpResponseRedirect(service + '&ticket=' + ticket.ticket)
+ else:
+ return HttpResponseRedirect(success_redirect)
+ errors = []
+ if request.method == 'POST':
+ username = request.POST.get('username', None)
+ password = request.POST.get('password', None)
+ service = request.POST.get('service', None)
+ lt = request.POST.get('lt', None)
+
+ try:
+ login_ticket = LoginTicket.objects.get(ticket=lt)
+ except:
+ errors.append('Login ticket expired. Please try again.')
+ else:
+ login_ticket.delete()
+ user = authenticate(username=username, password=password)
+ if user is not None:
+ if user.is_active:
+ auth_login(request, user)
+ if service is not None:
+ ticket = create_service_ticket(user, service)
+ return HttpResponseRedirect(service + '?ticket=' + ticket.ticket)
+ else:
+ return HttpResponseRedirect(success_redirect)
+ else:
+ errors.append('This account is disabled.')
+ else:
+ errors.append('Incorrect username and/or password.')
+ form = LoginForm(service)
+ return render_to_response(template_name, {'form': form, 'errors': errors}, context_instance=RequestContext(request))
+
+def validate(request):
+ service = request.GET.get('service', None)
+ ticket_string = request.GET.get('ticket', None)
+ if service is not None and ticket_string is not None:
+ try:
+ ticket = ServiceTicket.objects.get(ticket=ticket_string)
+ username = ticket.user.username
+ ticket.delete()
+ return HttpResponse("yes\n\r%s\n\r" % username)
+ except:
+ pass
+ return HttpResponse("no\n\r\n\r")
+
+def logout(request, template_name='cas/logout.html'):
+ url = request.GET.get('url', None)
+ auth_logout(request)
+ return render_to_response(template_name, {'url': url}, context_instance=RequestContext(request))
\ No newline at end of file
--- /dev/null
+
+from setuptools import setup, find_packages
+
+setup(
+ name='django-cas-provider',
+ version='0.1dev',
+ description='A "provider" for the Central Authentication Service (http://jasig.org/cas)',
+ author='Chris Williams',
+ author_email='chris@nitron.org',
+ url='http://nitron.org/',
+ packages=find_packages(),
+ zip_safe=False,
+ install_requires=['setuptools'],
+)