Back to index

moin  1.9.0~rc2
moinoid.py
Go to the documentation of this file.
00001 """
00002     MoinMoin - OpenID utils
00003 
00004     @copyright: 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
00005     @license: GNU GPL, see COPYING for details.
00006 """
00007 
00008 from random import randint
00009 import time
00010 
00011 from openid import oidutil
00012 from openid.store.interface import OpenIDStore
00013 from openid.association import Association
00014 from openid.store import nonce
00015 
00016 from MoinMoin import caching
00017 from MoinMoin.support.python_compatibility import hash_new
00018 
00019 from MoinMoin import log
00020 logging = log.getLogger(__name__)
00021 
00022 # redirect openid logging to moin log
00023 def log(msg, level=0):
00024     logging.log(level, msg)
00025 
00026 oidutil.log = log
00027 
00028 def strbase64(value):
00029     from base64 import encodestring
00030     return encodestring(str(value)).replace('\n', '')
00031 
00032 
00033 def _cleanup_nonces(request):
00034     cachelist = caching.get_cache_list(request, 'openid-nonce', 'farm')
00035     # really openid should have a method to check this...
00036     texpired = time.time() - nonce.SKEW
00037     for name in cachelist:
00038         entry = caching.CacheEntry(request, 'openid-nonce', name,
00039                                    scope='farm', use_pickle=False)
00040         try:
00041             timestamp = int(entry.content())
00042             if timestamp < texpired:
00043                 entry.remove()
00044         except caching.CacheError:
00045             pass
00046 
00047 
00048 class MoinOpenIDStore(OpenIDStore):
00049     '''OpenIDStore for MoinMoin'''
00050     def __init__(self, request):
00051         self.request = request
00052         OpenIDStore.__init__(self)
00053 
00054     def key(self, url):
00055         '''return cache key'''
00056         return hash_new('sha1', url).hexdigest()
00057 
00058     def storeAssociation(self, server_url, association):
00059         ce = caching.CacheEntry(self.request, 'openid', self.key(server_url),
00060                                 scope='wiki', use_pickle=True)
00061         if ce.exists():
00062             assocs = ce.content()
00063         else:
00064             assocs = []
00065         assocs += [association.serialize()]
00066         ce.update(assocs)
00067 
00068     def getAssociation(self, server_url, handle=None):
00069         ce = caching.CacheEntry(self.request, 'openid', self.key(server_url),
00070                                 scope='wiki', use_pickle=True)
00071         if not ce.exists():
00072             return None
00073         assocs = ce.content()
00074         found = False
00075         for idx in xrange(len(assocs)-1, -1, -1):
00076             assoc_str = assocs[idx]
00077             association = Association.deserialize(assoc_str)
00078             if association.getExpiresIn() == 0:
00079                 del assocs[idx]
00080             else:
00081                 if handle is None or association.handle == handle:
00082                     found = True
00083                     break
00084         ce.update(assocs)
00085         if found:
00086             return association
00087         return None
00088 
00089     def removeAssociation(self, server_url, handle):
00090         ce = caching.CacheEntry(self.request, 'openid', self.key(server_url),
00091                                 scope='wiki', use_pickle=True)
00092         if not ce.exists():
00093             return
00094         assocs = ce.content()
00095         for idx in xrange(len(assocs)-1, -1, -1):
00096             assoc_str = assocs[idx]
00097             association = Association.deserialize(assoc_str)
00098             if association.handle == handle:
00099                 del assocs[idx]
00100         if len(assocs):
00101             ce.update(assocs)
00102         else:
00103             ce.remove()
00104 
00105     def useNonce(self, server_url, timestamp, salt):
00106         val = ''.join([str(server_url), str(timestamp), str(salt)])
00107         csum = hash_new('sha1', val).hexdigest()
00108         ce = caching.CacheEntry(self.request, 'openid-nonce', csum,
00109                                 scope='farm', use_pickle=False)
00110         if ce.exists():
00111             # nonce already used!
00112             return False
00113         ce.update(str(timestamp))
00114         if randint(0, 999) == 0:
00115             self.request.add_finisher(_cleanup_nonces)
00116         return True