2603e9939721964ca6e18527e6c0d7c22cd9064a
[cascardo/ipsilon.git] / ipsilon / providers / openid / store.py
1 # Copyright (C) 2014  Ipsilon project Contributors, for licensee see COPYING
2
3 from ipsilon.util.data import Store
4
5 from openid import oidutil
6 from openid.association import Association
7 from openid.store.nonce import SKEW as NonceSKEW
8 from openid.store.interface import OpenIDStore as OpenIDStoreInterface
9
10 from time import time
11
12
13 class OpenIDStore(Store, OpenIDStoreInterface):
14     def __init__(self, database_url):
15         Store.__init__(self, database_url=database_url)
16
17     def storeAssociation(self, server_url, assoc):
18         iden = '%s-%s' % (server_url, assoc.handle)
19         datum = {'secret': oidutil.toBase64(assoc.secret),
20                  'issued': str(assoc.issued),
21                  'lifetime': str(assoc.lifetime),
22                  'assoc_type': assoc.assoc_type}
23
24         data = {iden: datum}
25         self.save_unique_data('association', data)
26
27     def getAssociation(self, server_url, handle=None):
28         iden = '%s-%s' % (server_url, handle)
29         data = self.get_unique_data('association', iden)
30
31         if len(data) < 1:
32             return None
33
34         datum = data[iden]
35         assoc = Association(handle,
36                             oidutil.fromBase64(datum['secret']),
37                             int(datum['issued']),
38                             int(datum['lifetime']),
39                             datum['assoc_type'])
40
41         if assoc.expiresIn == 0:
42             self.del_unique_data('association', iden)
43             return None
44
45         return assoc
46
47     def removeAssociation(self, server_url, handle):
48         iden = '%s-%s' % (server_url, handle)
49         self.del_unique_data('association', iden)
50
51     def useNonce(self, server_url, timestamp, salt):
52         if abs(timestamp - time()) > NonceSKEW:
53             return False
54
55         iden = '%s-%s-%s' % (server_url, timestamp, salt)
56         data = self.get_unique_data('nonce', iden)
57
58         if len(data) > 0:
59             # This server_url, timestamp, salt combination is already seen
60             return False
61
62         datum = {'timestamp': timestamp}
63         data = {iden: datum}
64         self.save_unique_data('nonce', data)
65
66         return True
67
68     def cleanupNonces(self):
69         nonces = self.get_unique_data('nonce')
70         for iden in nonces:
71             if nonces[iden]['timestamp'] < (time() - NonceSKEW):
72                 self.del_unique_data('nonce', iden)
73
74     def cleanupAssociations(self):
75         assocs = self.get_unique_data('association')
76         for iden in assocs:
77             if ((int(assocs[iden]['issued']) + int(assocs[iden]['lifetime']))
78                     < time()):
79                 self.del_unique_data('association', iden)