| import time |
| from copy import deepcopy |
| from datetime import datetime, timedelta |
| |
| from openid.store import nonce |
| from openid.association import Association |
| |
| from ming.orm import FieldProperty |
| from ming.orm.declarative import MappedClass |
| from .session import main_doc_session, main_orm_session |
| from .session import project_doc_session, project_orm_session |
| |
| class OpenIdAssociation(MappedClass): |
| class __mongometa__: |
| name='oid_store_assoc' |
| session = main_orm_session |
| |
| _id = FieldProperty(str) # server url |
| assocs = FieldProperty([dict( |
| key=str, value=str)]) |
| |
| # Mimic openid.store.memstore.ServerAssocs |
| def set_assoc(self, assoc): |
| for a in self.assocs: |
| if a['key'] == assoc.handle: |
| a['value'] = assoc.serialize() |
| return |
| self.assocs.append(dict(key=assoc.handle, value=assoc.serialize())) |
| |
| def get_assoc(self, handle): |
| for a in self.assocs: |
| if a['key'] == handle: |
| return Association.deserialize(a['value']) |
| return None |
| |
| def remove_assoc(self, handle): |
| old_len = len(self.assocs) |
| self.assocs = [ |
| a for a in self.assocs |
| if a['key'] != handle ] |
| return old_len != len(self.assocs) |
| |
| def best_assoc(self): |
| best = None |
| for assoc in self.assocs: |
| assoc = Association.deserialize(assoc['value']) |
| if best is None or best.issued < assoc.issued: |
| best = assoc |
| if best: |
| return best |
| else: |
| return None |
| |
| def cleanup_assocs(self): |
| old_len = len(self.assocs) |
| self.assocs = [ a for a in self.assocs |
| if Association.deserialize(a['value']).getExpiresIn() != 0 ] |
| new_len = len(self.assocs) |
| return (old_len - new_len), new_len |
| |
| class OpenIdNonce(MappedClass): |
| class __mongometa__: |
| name='oid_store_nonce' |
| session = main_orm_session |
| |
| _id = FieldProperty(str) # Nonce value |
| timestamp = FieldProperty(datetime, if_missing=datetime.utcnow) |
| |
| class OpenIdStore(object): |
| |
| def _get_assocs(self, server_url): |
| assoc = OpenIdAssociation.query.get(_id=server_url) |
| if assoc is None: |
| assoc = OpenIdAssociation(_id=server_url) |
| return assoc |
| |
| def storeAssociation(self, server_url, association): |
| assocs = self._get_assocs(server_url) |
| assocs.set_assoc(deepcopy(association)) |
| |
| def getAssociation(self, server_url, handle=None): |
| assocs = self._get_assocs(server_url) |
| if handle is None: |
| return assocs.best_assoc() |
| else: |
| return assocs.get_assoc(handle) |
| |
| def removeAssociation(self, server_url, handle): |
| assocs = self._get_assocs(server_url) |
| return assocs.remove_assoc(handle) |
| |
| def useNonce(self, server_url, timestamp, salt): |
| if abs(timestamp - time.time()) > nonce.SKEW: |
| return False |
| key = str((server_url, timestamp, salt)) |
| if OpenIdNonce.query.get(_id=key) is None: |
| OpenIdNonce(_id=key) |
| return True |
| else: |
| return False |
| |
| def cleanupNonces(self): |
| now = datetime.utcnow() |
| cutoff = now - timedelta(seconds=nonce.SKEW) |
| num_removed = OpenIdNonce.query.remove(dict( |
| timestamp={'$lt': cutoff})) |
| return num_removed |
| |