comparison MoinMoin/util/moinoid.py @ 2298:c81b9c983b1d

OpenID storage for moin session
author Johannes Berg <johannes AT sipsolutions DOT net>
date Tue, 10 Jul 2007 19:09:14 +0200
parents
children c6e39279f83b
comparison
equal deleted inserted replaced
2297:84aad7171a56 2298:c81b9c983b1d
1 """
2 MoinMoin - OpenID utils
3
4 @copyright: 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
5 @license: GNU GPL, see COPYING for details.
6 """
7
8 from MoinMoin import caching
9 from openid import oidutil
10 from openid.store.interface import OpenIDStore
11 from openid.association import Association
12 from openid.store import nonce
13 import logging
14 from sha import sha
15 from random import randint
16 import time
17
18 # redirect openid logging to moin log
19 def log(msg, level=0):
20 logging.log(level, msg)
21
22 oidutil.log = log
23
24 def strbase64(value):
25 from base64 import encodestring
26 return encodestring(str(value)).replace('\n', '')
27
28
29 def _cleanup_nonces(request):
30 cachelist = caching.get_cache_list(request, 'openid-nonce', 'farm')
31 # really openid should have a method to check this...
32 texpired = time.time() - nonce.SKEW
33 for name in cachelist:
34 entry = caching.CacheEntry(request, 'openid-nonce', name,
35 scope='farm', use_pickle=False)
36 try:
37 timestamp = int(entry.content())
38 if timestamp < texpired:
39 entry.remove()
40 except caching.CacheError:
41 pass
42
43
44 class MoinOpenIDStore(OpenIDStore):
45 '''OpenIDStore for MoinMoin'''
46 def __init__(self, request):
47 self.request = request
48 OpenIDStore.__init__(self)
49
50 def key(self, url):
51 '''return cache key'''
52 return sha(url).hexdigest()
53
54 def storeAssociation(self, server_url, association):
55 ce = caching.CacheEntry(self.request, 'openid', self.key(server_url),
56 scope='wiki', use_pickle=True)
57 if ce.exists():
58 assocs = ce.content()
59 else:
60 assocs = []
61 assocs += [association.serialize()]
62 ce.update(assocs)
63
64 def getAssociation(self, server_url, handle=None):
65 ce = caching.CacheEntry(self.request, 'openid', self.key(server_url),
66 scope='wiki', use_pickle=True)
67 if not ce.exists():
68 return None
69 assocs = ce.content()
70 found = False
71 for idx in xrange(len(assocs)-1, -1, -1):
72 assoc_str = assocs[idx]
73 association = Association.deserialize(assoc_str)
74 if association.getExpiresIn() == 0:
75 del assocs[idx]
76 else:
77 if handle is None or association.handle == handle:
78 found = True
79 break
80 ce.update(assocs)
81 if found:
82 return association
83 return None
84
85 def removeAssociation(self, server_url, handle):
86 ce = caching.CacheEntry(self.request, 'openid', self.key(server_url),
87 scope='wiki', use_pickle=True)
88 if not ce.exists():
89 return
90 assocs = ce.content()
91 for idx in xrange(len(assocs)-1, -1, -1):
92 assoc_str = assocs[idx]
93 association = Association.deserialize(assoc_str)
94 if association.handle == handle:
95 del assocs[idx]
96 if len(assocs):
97 ce.update(assocs)
98 else:
99 ce.remove()
100
101 def useNonce(self, server_url, timestamp, salt):
102 val = ''.join([str(server_url), str(timestamp), str(salt)])
103 csum = sha(val).hexdigest()
104 ce = caching.CacheEntry(self.request, 'openid-nonce', csum,
105 scope='farm', use_pickle=False)
106 if ce.exists():
107 # nonce already used!
108 return False
109 ce.update(str(timestamp))
110 if randint(0, 999) == 0:
111 self.request.add_finisher(_cleanup_nonces)
112 return True