2075c2e8ab25d5232d82f04d52f7022f0f44ff77
[django-cas-provider.git] / cas_provider / models.py
1 from django.contrib.auth.models import User
2 from django.db import models
3 from django.utils.translation import ugettext_lazy as _
4 from random import Random
5 import string
6 import urllib
7 import urlparse
8
9 if hasattr(urlparse, 'parse_qs'):
10     parse_qs = urlparse.parse_qs
11 else:
12     # Python <2.6 compatibility
13     from cgi import parse_qs
14
15
16 __all__ = ['ServiceTicket', 'LoginTicket']
17
18
19 class BaseTicket(models.Model):
20     ticket = models.CharField(_('ticket'), max_length=32)
21     created = models.DateTimeField(_('created'), auto_now=True)
22
23     class Meta:
24         abstract = True
25
26     def __init__(self, *args, **kwargs):
27         if 'ticket' not in kwargs:
28             kwargs['ticket'] = self._generate_ticket()
29         super(BaseTicket, self).__init__(*args, **kwargs)
30
31     def __unicode__(self):
32         return self.ticket
33
34     def _generate_ticket(self, length=29, chars=string.ascii_letters + string.digits):
35         """ Generates a random string of the requested length. Used for creation of tickets. """
36         return u"%s-%s" % (self.prefix, ''.join(Random().sample(chars, length)))
37
38
39 class ServiceTicket(BaseTicket):
40     user = models.ForeignKey(User, verbose_name=_('user'))
41     service = models.URLField(_('service'), verify_exists=False)
42
43     prefix = 'ST'
44
45     class Meta:
46         verbose_name = _('Service Ticket')
47         verbose_name_plural = _('Service Tickets')
48
49     def get_redirect_url(self):
50         parsed = urlparse.urlparse(self.service)
51         query = parse_qs(parsed.query)
52         query['ticket'] = [self.ticket]
53         query = [ ((k, v) if len(v) > 1 else (k, v[0])) for k, v in query.iteritems()]
54         parsed = urlparse.ParseResult(parsed.scheme, parsed.netloc,
55                                   parsed.path, parsed.params,
56                                   urllib.urlencode(query), parsed.fragment)
57         return parsed.geturl()
58
59
60 class LoginTicket(BaseTicket):
61
62     prefix = 'LT'
63
64     class Meta:
65         verbose_name = _('Login Ticket')
66         verbose_name_plural = _('Login Tickets')