1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# vim:fileencoding=utf8:et:ts=4:sts=4:sw=4:ft=python
import base64
import calendar
import datetime
from django.db import IntegrityError
from django.utils import timezone
from openid.store.interface import OpenIDStore
from openid.association import Association
from openid.store import nonce
from okupy.accounts import models as db_models
class DjangoDBOpenIDStore(OpenIDStore):
def storeAssociation(self, server_uri, assoc):
issued_dt = datetime.datetime.utcfromtimestamp(assoc.issued)
issued_dt = timezone.make_aware(issued_dt, timezone.utc)
expire_delta = datetime.timedelta(seconds=assoc.lifetime)
a = db_models.OpenID_Association(
server_uri=server_uri,
handle=assoc.handle,
secret=base64.b64encode(assoc.secret),
issued=issued_dt,
expires=issued_dt + expire_delta,
assoc_type=assoc.assoc_type)
a.save()
def _db_getAssocs(self, server_uri, handle=None):
objs = db_models.OpenID_Association.objects
objs = objs.filter(server_uri=server_uri)
if handle is not None:
objs = objs.filter(handle=handle)
return objs
def getAssociation(self, server_uri, handle=None):
assert(server_uri is not None)
objs = self._db_getAssocs(server_uri, handle)
try:
a = objs.latest('issued')
except db_models.OpenID_Association.DoesNotExist:
return None
# expired?
if timezone.now() >= a.expires:
# if latest is expired, all older are expired as well
# so clean them all up
objs.delete()
return None
return Association(
a.handle,
base64.b64decode(a.secret),
calendar.timegm(a.issued.utctimetuple()),
int((a.expires - a.issued).total_seconds()),
a.assoc_type)
def removeAssociation(self, server_uri, handle):
assert(server_uri is not None)
assert(handle is not None)
self._db_getAssocs(server_uri, handle)
# determining whether something was deleted is a waste of time
# and django doesn't give us explicit 'affected rows'
return True
def useNonce(self, server_uri, ts, salt):
nonce_dt = datetime.datetime.utcfromtimestamp(ts)
nonce_dt = timezone.make_aware(nonce_dt, timezone.utc)
# copy-paste from python-openid's sqlstore
if abs((nonce_dt - timezone.now()).total_seconds()) > nonce.SKEW:
return False
n = db_models.OpenID_Nonce(
server_uri=server_uri,
ts=nonce_dt,
salt=salt)
try:
n.save()
except IntegrityError:
# non-unique
return False
return True
def cleanupNonces(self):
skew_td = datetime.timedelta(seconds=nonce.SKEW)
expire_dt = timezone.now() - skew_td
db_models.OpenID_Nonce.objects.filter(ts__lt=expire_dt).delete()
return 0
def cleanupAssociations(self):
db_models.OpenID_Association.objects.filter(
expires__lt=timezone.now()).delete()
return 0
|