def __init__(self): self.handles = OOBTree() self.nonces = OITreeSet() self.associations = OOBTree() self.noncetimeline = BList() self.assoctimeline = BList()
class ZopeStore(OpenIDStore): """Zope OpenID store. This class implements an OpenID store which uses the ZODB.""" def __init__(self): self.handles = OOBTree() self.nonces = OITreeSet() self.associations = OOBTree() self.noncetimeline = BList() self.assoctimeline = BList() def getAssociationKey(self, server_url, handle): """Generate a key used to identify an association in our storage.""" if handle is None: return self.handles[server_url][0] return (server_url, handle) def storeAssociation(self, server_url, association): key = self.getAssociationKey(server_url, association.handle) self.associations[key] = association.serialize() now = time.time() def getKey(item): return self.getAssociation(item[0], item[1], remove=False).getExpiresIn(now) lst = self.handles.get(server_url, []) lst.append(key) lst.sort(key=getKey) self.handles[server_url] = lst self.assoctimeline.append((association.issued + association.lifetime, key)) def getAssociation(self, server_url, handle=None, remove=True): try: key = self.getAssociationKey(server_url, handle) assoc = Association.deserialize(self.associations[key]) except KeyError: return None if remove and assoc.getExpiresIn() == 0: self.removeAssociation(server_url, handle) return None return assoc def removeAssociation(self, server_url, handle): key = self.getAssociationKey(server_url, handle) try: assoc = Association.deserialize(self.associations[key]) del self.associations[key] lst = self.handles[server_url] lst.remove(key) self.handles[server_url] = lst self.assoctimeline.remove((assoc.issued + assoc.lifetime, key)) return True except KeyError: return False def useNonce(self, server_url, timestamp, salt): nonce = (salt, server_url) if nonce in self.nonces: return False self.nonces.insert(nonce) self.noncetimeline.append((timestamp, nonce)) return True def cleanupNonces(self): cutoff = time.time() + SKEW count = 0 for (timestamp, nonce) in self.noncetimeline: if timestamp < cutoff: self.noncetimeline.remove((timestamp, nonce)) self.nonces.remove(nonce) count += 1 return count def cleanupAssociations(self): now = time.time() count = 0 expired = (key for (timestamp, key) in self.assoctimeline if timestamp <= now) for key in expired: self.removeAssociation(*key) count += 1 return count