Back to index

plone3  3.1.7
store.py
Go to the documentation of this file.
00001 from openid.store.interface import OpenIDStore
00002 from openid.store.nonce import SKEW
00003 from openid.association import Association
00004 from persistent.list import PersistentList
00005 from BTrees.OOBTree import OOBTree
00006 from BTrees.OIBTree import OITreeSet
00007 import time
00008 
00009 class ZopeStore(OpenIDStore):
00010     """Zope OpenID store.
00011 
00012     This class implements an OpenID store which uses the ZODB.
00013     """
00014     def __init__(self):
00015         self.associations=OOBTree()
00016         self.handles=OOBTree()
00017         self.nonces=OITreeSet()
00018 
00019         self.noncetimeline=PersistentList()
00020         self.assoctimeline=PersistentList()
00021 
00022 
00023     def getAssociationKey(self, server_url, handle):
00024         """Generate a key used to identify an association in our storage.
00025         """
00026         if handle is None:
00027             return self.handles[server_url][0]
00028 
00029         return (server_url, handle)
00030 
00031 
00032     def storeAssociation(self, server_url, association):
00033         key=self.getAssociationKey(server_url, association.handle)
00034         self.associations[key]=association.serialize()
00035 
00036         now=time.time()
00037         def getKey(item):
00038             return self.getAssociation(item[0], item[1], remove=False).getExpiresIn(now)
00039 
00040         lst=self.handles.get(server_url, [])
00041         lst.append(key)
00042         lst.sort(key=getKey)
00043         self.handles[server_url]=lst
00044 
00045         if not hasattr(self, "assoctimeline"):
00046             # BBB for versions < 1.0b2
00047             self.assoctimeline=PersistentList()
00048 
00049         self.assoctimeline.append((association.issued+association.lifetime, key))
00050 
00051 
00052     def getAssociation(self, server_url, handle=None, remove=True):
00053         try:
00054             key=self.getAssociationKey(server_url, handle)
00055             assoc=Association.deserialize(self.associations[key])
00056         except KeyError:
00057             return None
00058 
00059         if remove and assoc.getExpiresIn()==0:
00060             self.removeAssociation(server_url, handle)
00061             return None
00062 
00063         return assoc
00064 
00065 
00066     def removeAssociation(self, server_url, handle):
00067         key=self.getAssociationKey(server_url, handle)
00068         try:
00069             assoc=Association.deserialize(self.associations[key])
00070             del self.associations[key]
00071 
00072             lst=self.handles[server_url]
00073             lst.remove(key)
00074             self.handles[server_url]=lst
00075 
00076             self.assoctimeline.remove((assoc.issued+assoc.lifetime, key))
00077             return True
00078         except KeyError:
00079             return False
00080 
00081 
00082     def useNonce(self, server_url, timestamp, salt):
00083         nonce = (salt, server_url)
00084         if nonce in self.nonces:
00085             return False
00086 
00087         self.nonces.insert(nonce)
00088 
00089         if not hasattr(self, "noncetimeline"):
00090             # BBB for store instances from before 1.0b2
00091             self.noncetimeline=PersistentList()
00092         self.noncetimeline.append((timestamp, nonce))
00093 
00094         return True
00095 
00096 
00097     def cleanupNonces(self):
00098         if not hasattr(self, "noncetimeline"):
00099             return 0
00100 
00101         cutoff=time.time()+SKEW
00102         count=0
00103         for (timestamp,nonce) in self.noncetimeline:
00104             if timestamp<cutoff:
00105                 self.noncetimeline.remove((timestamp,nonce))
00106                 self.nonces.remove(nonce)
00107                 count+=1
00108 
00109         return count
00110 
00111 
00112     def cleanupAssociations(self):
00113         if not hasattr(self, "assoctimeline"):
00114             return 0
00115 
00116         now=time.time()
00117         count=0
00118 
00119         expired=(key for (timestamp,key) in self.assoctimeline
00120                 if timestamp<=now)
00121         for key in expired:
00122             self.removeAssociation(*key)
00123             count+=1
00124 
00125         return count
00126