webfaction and repo.or.cz deployment done
[worddb.git] / libs / django_authopenid / .svn / text-base / util.py.svn-base
blob841a81c7b53972fd412b6b7a7cd232966bbd1a05
1 # -*- coding: utf-8 -*-
2 from openid.store.interface import OpenIDStore
3 from openid.association import Association as OIDAssociation
4 from openid.extensions import sreg
5 import openid.store
7 from django.db.models.query import Q
8 from django.conf import settings
9 from django.http import str_to_unicode
12 # needed for some linux distributions like debian
13 try:
14     from openid.yadis import xri
15 except:
16     from yadis import xri
18 import time, base64, md5, operator
19 import urllib
21 from models import Association, Nonce
23 __all__ = ['OpenID', 'DjangoOpenIDStore', 'from_openid_response', 'clean_next']
25 DEFAULT_NEXT = getattr(settings, 'OPENID_REDIRECT_NEXT', '/')
26 def clean_next(next):
27     if next is None:
28         return DEFAULT_NEXT
29     next = str_to_unicode(urllib.unquote(next), 'utf-8')
30     next = next.strip()
31     if next.startswith('/'):
32         return next
33     return DEFAULT_NEXT
35 class OpenID:
36     def __init__(self, openid_, issued, attrs=None, sreg_=None):
37         self.openid = openid_
38         self.issued = issued
39         self.attrs = attrs or {}
40         self.sreg = sreg_ or {}
41         self.is_iname = (xri.identifierScheme(openid_) == 'XRI')
42     
43     def __repr__(self):
44         return '<OpenID: %s>' % self.openid
45     
46     def __str__(self):
47         return self.openid
49 class DjangoOpenIDStore(OpenIDStore):
50     def __init__(self):
51         self.max_nonce_age = 6 * 60 * 60 # Six hours
52     
53     def storeAssociation(self, server_url, association):
54         assoc = Association(
55             server_url = server_url,
56             handle = association.handle,
57             secret = base64.encodestring(association.secret),
58             issued = association.issued,
59             lifetime = association.issued,
60             assoc_type = association.assoc_type
61         )
62         assoc.save()
63     
64     def getAssociation(self, server_url, handle=None):
65         assocs = []
66         if handle is not None:
67             assocs = Association.objects.filter(
68                 server_url = server_url, handle = handle
69             )
70         else:
71             assocs = Association.objects.filter(
72                 server_url = server_url
73             )
74         if not assocs:
75             return None
76         associations = []
77         for assoc in assocs:
78             association = OIDAssociation(
79                 assoc.handle, base64.decodestring(assoc.secret), assoc.issued,
80                 assoc.lifetime, assoc.assoc_type
81             )
82             if association.getExpiresIn() == 0:
83                 self.removeAssociation(server_url, assoc.handle)
84             else:
85                 associations.append((association.issued, association))
86         if not associations:
87             return None
88         return associations[-1][1]
89     
90     def removeAssociation(self, server_url, handle):
91         assocs = list(Association.objects.filter(
92             server_url = server_url, handle = handle
93         ))
94         assocs_exist = len(assocs) > 0
95         for assoc in assocs:
96             assoc.delete()
97         return assocs_exist
99     def useNonce(self, server_url, timestamp, salt):
100         if abs(timestamp - time.time()) > openid.store.nonce.SKEW:
101             return False
102         
103         query = [
104                 Q(server_url__exact=server_url),
105                 Q(timestamp__exact=timestamp),
106                 Q(salt__exact=salt),
107         ]
108         try:
109             ononce = Nonce.objects.get(reduce(operator.and_, query))
110         except Nonce.DoesNotExist:
111             ononce = Nonce(
112                     server_url=server_url,
113                     timestamp=timestamp,
114                     salt=salt
115             )
116             ononce.save()
117             return True
118         
119         ononce.delete()
121         return False
122    
123     def cleanupNonce(self):
124         Nonce.objects.filter(timestamp<int(time.time()) - nonce.SKEW).delete()
126     def cleanupAssociations(self):
127         Association.objects.extra(where=['issued + lifetimeint<(%s)' % time.time()]).delete()
129     def getAuthKey(self):
130         # Use first AUTH_KEY_LEN characters of md5 hash of SECRET_KEY
131         return md5.new(settings.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
132     
133     def isDumb(self):
134         return False
136 def from_openid_response(openid_response):
137     """ return openid object from response """
138     issued = int(time.time())
139     sreg_resp = sreg.SRegResponse.fromSuccessResponse(openid_response) \
140             or []
141     
142     return OpenID(
143         openid_response.identity_url, issued, openid_response.signed_fields, 
144          dict(sreg_resp)
145     )