def test_getAssociation_no_handle(self): timestamp = int(time.time()) self.store.storeAssociation( 'server-url', Association('handle1', 'secret', timestamp, 600, 'HMAC-SHA1')) self.store.storeAssociation( 'server-url', Association('handle2', 'secret', timestamp + 1, 600, 'HMAC-SHA1')) # The most recent handle is returned. assoc = self.store.getAssociation('server-url', None) self.assertNotEqual(assoc, None) self.assertEqual(assoc.handle, 'handle2')
def test_cleanupAssociations(self): timestamp = int(time.time()) - 100 self.store.storeAssociation( 'server-url', Association('handle1', 'secret', timestamp, 50, 'HMAC-SHA1')) self.store.storeAssociation( 'server-url', Association('handle2', 'secret', timestamp, 200, 'HMAC-SHA1')) self.assertEqual(self.store.cleanupAssociations(), 1) # The second (non-expired) association is left behind. self.assertNotEqual(self.store.getAssociation('server-url', 'handle2'), None)
def test_storeAssociation_update_existing(self): self.store.storeAssociation( 'server-url', Association('handle', 'secret', 42, 600, 'HMAC-SHA1')) db_assoc = IMasterStore(self.store.Association).get( self.store.Association, (u'server-url', u'handle')) self.assertNotEqual(db_assoc, None) # Now update the association with new information. self.store.storeAssociation( 'server-url', Association('handle', 'secret2', 420, 900, 'HMAC-SHA256')) self.assertEqual(db_assoc.secret, 'secret2') self.assertEqual(db_assoc.issued, 420) self.assertEqual(db_assoc.lifetime, 900) self.assertEqual(db_assoc.assoc_type, u'HMAC-SHA256')
def getAssociation(self, server_url, handle=None): q = (OpenIDAssociationData .all() .filter('idp_server_url =', server_url) .order('-issued')) if handle: q.filter('handle', handle) results = q.fetch(1) if not results: return None r = results[0] association = Association(r.handle, r.secret, r.issued, r.lifetime, r.assoc_type) if association.getExpiresIn(self.current_timestamp()) > 0: return association else: return None
def getAssociation(self, server_url, handle=None): stored_assocs = OpenIDStoreModel.objects.filter(server_url=server_url) if handle: stored_assocs = stored_assocs.filter(handle=handle) stored_assocs.order_by('-issued') if stored_assocs.count() == 0: return None return_val = None for stored_assoc in stored_assocs: assoc = Association(stored_assoc.handle, base64.decodestring(stored_assoc.secret), stored_assoc.issued, stored_assoc.lifetime, stored_assoc.assoc_type) if assoc.getExpiresIn() == 0: stored_assoc.delete() else: if return_val is None: return_val = assoc return return_val
def txn_getAssociation(self, server_url, handle=None): """Get the most recent association that has been set for this server URL and handle. @type server_url: six.text_type, six.binary_type is deprecated @rtype: Optional[Association] """ server_url = string_to_text(server_url, "Binary values for server_url are deprecated. Use text input instead.") if handle is not None: self.db_get_assoc(server_url, handle) else: self.db_get_assocs(server_url) rows = self.cur.fetchall() if len(rows) == 0: return None else: associations = [] for values in rows: # Decode secret before association is created handle, secret, issued, lifetime, assoc_type = values secret = self.blobDecode(secret) assoc = Association(handle, secret, issued, lifetime, assoc_type) if assoc.getExpiresIn() == 0: self.txn_removeAssociation(server_url, assoc.handle) else: associations.append((assoc.issued, assoc)) if associations: associations.sort() return associations[-1][1] else: return None
def getAssociation(self, server_url, handle = None): associations = None if handle is not None: associations = OidStoreAssociation.objects.filter(server_url = server_url, handle = handle) else: associations = OidStoreAssociation.objects.filter(server_url = server_url) if associations.count() == 0: return None else: assocs = [] for a in associations: adata = [a.handle, self.blobDecode(a.secret), a.issued, a.lifetime, a.assoc_type] assoc = Association(*adata) if assoc.getExpiresIn() == 0: self.removeAssociation(server_url, assoc.handle) else: assocs.append((assoc.issued, assoc)) if assocs: assocs.sort() return assocs[-1][1] else: return None
def test_storeAssociation(self): """Tests the NDBOpenIDStore.storeAssociation(server_url, association) method.""" # create association association = Association(handle='handle', secret='secret', issued=int(time.time()), lifetime=3600, assoc_type='HMAC-SHA1') server_url = 'server_url_abc' # store association NDBOpenIDStore.storeAssociation(server_url, association) # retrieve association key = ndb.Key('ServerUrl', server_url, NDBOpenIDStore, association.handle) entity = key.get() # check if entity exists assert entity is not None # check whether serialized match assert entity.serialized == association.serialize() # check whether expiration_date match issued = datetime.datetime.fromtimestamp(association.issued) lifetime = datetime.timedelta(0, association.lifetime) expiration_date = issued + lifetime assert entity.expiration_date == expiration_date # check whether the original and deserialized associations match assert association == Association.deserialize(entity.serialized)
def test_removeAssociation(self): # create and store some associations associations = [] for i in range(3): assoc = Association(handle='handle-{}'.format(i), secret='secret', issued=int(time.time()), lifetime=3600, assoc_type='HMAC-SHA1') associations.append(assoc) NDBOpenIDStore.storeAssociation('server_url', assoc) # remove existing association removed = NDBOpenIDStore.removeAssociation('server_url', 'handle-1') # check whether the method returned True assert removed is True # check whether there is one less association in the datastore assert NDBOpenIDStore.query().count() == 2 # check whether the right association was deleted assert NDBOpenIDStore.getAssociation('server_url', 'handle-1') is None # check whether the remaining are there assert NDBOpenIDStore.getAssociation('server_url', 'handle-0') == associations[0] assert NDBOpenIDStore.getAssociation('server_url', 'handle-2') == associations[2]
def txn_getAssociation(self, server_url, handle=None): """Get the most recent association that has been set for this server URL and handle. str -> NoneType or Association """ if handle is not None: self.db_get_assoc(server_url, handle) else: self.db_get_assocs(server_url) rows = self.cur.fetchall() if len(rows) == 0: return None else: associations = [] for values in rows: assoc = Association(*values) assoc.secret = self.blobDecode(assoc.secret) if assoc.expiresIn == 0: self.txn_removeAssociation(server_url, assoc.handle) else: associations.append((assoc.issued, assoc)) if associations: associations.sort() return associations[-1][1] else: return None
def getAssociation(self, server_url, handle=None): assoc = self._get(server_url, handle) if assoc: return Association(handle=assoc.handle, secret=assoc.secret, issued=assoc.issued, lifetime=assoc.lifetime, assoc_type=assoc.assoc_type)
def test_removeAssociation(self): timestamp = int(time.time()) self.store.storeAssociation( 'server-url', Association('handle', 'secret', timestamp, 600, 'HMAC-SHA1')) self.assertEqual(self.store.removeAssociation('server-url', 'handle'), True) self.assertEqual(self.store.getAssociation('server-url', 'handle'), None)
def test_storeAssociation(self): self.store.storeAssociation( 'server-url\xC2\xA9', Association('handle', 'secret', 42, 600, 'HMAC-SHA1')) db_assoc = IMasterStore(self.store.Association).get( self.store.Association, (u'server-url\xA9', u'handle')) self.assertEqual(db_assoc.server_url, u'server-url\xA9') self.assertEqual(db_assoc.handle, u'handle') self.assertEqual(db_assoc.secret, 'secret') self.assertEqual(db_assoc.issued, 42) self.assertEqual(db_assoc.lifetime, 600) self.assertEqual(db_assoc.assoc_type, u'HMAC-SHA1')
def test_getAssociation(self): timestamp = int(time.time()) self.store.storeAssociation( 'server-url', Association('handle', 'secret', timestamp, 600, 'HMAC-SHA1')) assoc = self.store.getAssociation('server-url', 'handle') self.assertIsInstance(assoc, Association) self.assertEqual(assoc.handle, 'handle') self.assertEqual(assoc.secret, 'secret') self.assertEqual(assoc.issued, timestamp) self.assertEqual(assoc.lifetime, 600) self.assertEqual(assoc.assoc_type, 'HMAC-SHA1')
def getAssociation(self, server_url, handle=None): q = OpenIDAssociation.query.filter_by(server_url=server_url) if handle is not None: q = q.filter_by(handle=handle) result_assoc = None for item in q.all(): assoc = Association(item.handle, item.secret.decode('base64'), item.issued, item.lifetime, item.assoc_type) if assoc.getExpiresIn() <= 0: self.removeAssociation(server_url, assoc.handle) else: result_assoc = assoc return result_assoc
def test_getAssociation_expired(self): lifetime = 600 timestamp = int(time.time()) - 2 * lifetime self.store.storeAssociation( 'server-url', Association('handle', 'secret', timestamp, lifetime, 'HMAC-SHA1')) # The association is not returned because it is out of date. # Further more, it is removed from the database. assoc = self.store.getAssociation('server-url', 'handle') self.assertEqual(assoc, None) store = IMasterStore(self.store.Association) db_assoc = store.get(self.store.Association, (u'server-url', u'handle')) self.assertEqual(db_assoc, None)
def getAssociation(self, server_url, handle=None): filter = openid_association.c.server_url == server_url if handle is not None: filter &= openid_association.c.handle == handle with self.connection() as con: result = con.execute(openid_association.select(filter)) result_assoc = None for row in result.fetchall(): assoc = Association(row.handle, row.secret.decode('base64'), row.issued, row.lifetime, row.assoc_type) if assoc.getExpiresIn() <= 0: self.removeAssociation(server_url, assoc.handle) else: result_assoc = assoc return result_assoc
def test_store_retrieve_association(self): assoc = Association( 'handle', 'secret', 0, 10000, 'HMAC-SHA1') self.store.storeAssociation('http://provider.com', assoc) retrieved = self.store.getAssociation('http://provider.com', 'handle') self.assertTrue(retrieved is not None) self.assertEqual(assoc.handle, retrieved.handle) self.assertEqual(assoc.secret, retrieved.secret) self.assertEqual(assoc.issued, retrieved.issued) self.assertEqual(assoc.lifetime, retrieved.lifetime) self.assertEqual(assoc.assoc_type, retrieved.assoc_type)
def getAssociation(self, server_url, handle=None): iden = '%s-%s' % (server_url, handle) data = self.get_unique_data('association', iden) if len(data) < 1: return None datum = data[iden] assoc = Association(handle, oidutil.fromBase64(datum['secret']), int(datum['issued']), int(datum['lifetime']), datum['assoc_type']) if assoc.expiresIn == 0: self.del_unique_data('association', iden) return None return assoc
def test_store_retrieve_expired_association(self): assoc = Association( 'handle', 'secret', 0, 10, 'HMAC-SHA1') self.store.storeAssociation('http://provider.com', assoc) self.test_time = 9 retrieved = self.store.getAssociation('http://provider.com', 'handle') self.assertTrue(retrieved is not None) self.test_time = 11 retrieved = self.store.getAssociation('http://provider.com', 'handle') # the association has now expired, so we should not get anything back self.assertTrue(retrieved is None)
def getAssociation(self, server_uri, handle=None): assert (server_uri is not None) objs = self._db_getAssocs(server_uri, handle) try: a = objs.latest('issued') except db_models.OpenID_Association.DoesNotExist: return None # expired? if timezone.now() >= a.expires: # if latest is expired, all older are expired as well # so clean them all up objs.delete() return None return Association(a.handle, base64.b64decode(a.secret), calendar.timegm(a.issued.utctimetuple()), int((a.expires - a.issued).total_seconds()), a.assoc_type)
def getAssociation(self, server_url, handle=None): """ Return the association for server_url and handle. If handle is not None return the latests associations for that server_url. Return None if no association can be found. """ db = self.database query = (db.oid_associations.server_url == server_url) if handle: query &= (db.oid_associations.handle == handle) rows = db(query).select(orderby=db.oid_associations.issued) keep_assoc, _ = self._removeExpiredAssocations(rows) if len(keep_assoc) == 0: return None else: assoc = keep_assoc.pop( ) # pop the last one as it should be the latest one return Association(assoc['handle'], assoc['secret'], assoc['issued'], assoc['lifetime'], assoc['assoc_type'])
def getAssociation(self, server_url, handle=None): """ Gets a server url and the handle and finds a matching association that has not expired. Expired associations are deleted. The association returned is the one with the most recent issuing timestamp. """ query = {'server_url': server_url} if handle: query.update({'handle': handle.hex()}) try: mist_associations = MistAssociation.objects(**query) except me.DoesNotExist: mist_associations = [] filtered_mist_assocs = [] for assoc in mist_associations: if assoc.is_expired(): assoc.delete() else: filtered_mist_assocs.append(assoc) filtered_mist_assocs = sorted(filtered_mist_assocs, key=lambda assoc: assoc.issued, reverse=True) if len(filtered_mist_assocs) > 0: mist_assoc = filtered_mist_assocs[0] association = Association(handle=mist_assoc.handle.decode('hex'), secret=mist_assoc.secret.decode('hex'), issued=mist_assoc.issued, lifetime=mist_assoc.lifetime, assoc_type=mist_assoc.assoc_type) return association return None
def genAssoc(issued, lifetime=600): sec = generateSecret(20) hdl = generateHandle(128) return Association(hdl, sec, now + issued, lifetime, 'HMAC-SHA1')
def test_cleanupAssociations(self): """Tests the NDBOpenIDStore._delete_expired() method.""" number_of_valid = 5 number_of_expired = 5 # populate datastore with valid associations for i in range(number_of_valid): url = 'url-{}'.format(i) association = Association(handle='handle_{}'.format(i), secret='secret', issued=int(time.time()), lifetime=3600, assoc_type='HMAC-SHA1') NDBOpenIDStore.storeAssociation(url, association) # check whether the valid ones are there assert NDBOpenIDStore.query().count() == number_of_valid # populate datastore with expired associations for i in range(number_of_valid, number_of_expired + number_of_valid): url = 'url-{}'.format(i) # create association mock beyond expiration association = Association(handle='handle_{}'.format(i), secret='secret', issued=int(time.time()) - 3600, lifetime=1000, assoc_type='HMAC-SHA1') NDBOpenIDStore.storeAssociation(url, association) # check whether the expired ones were added assert NDBOpenIDStore.query().count( ) == number_of_expired + number_of_valid # call the tested method removed = NDBOpenIDStore.cleanupAssociations() # check whether the method returned the correct number of deleted assert removed == number_of_expired # get remaining remaining = NDBOpenIDStore.query().fetch() # check the number of remaining assert len(remaining) == number_of_valid # check whether all the remaining are valid for entity in remaining: assert entity.expiration_date >= datetime.datetime.now() # call the tested method again removed = NDBOpenIDStore.cleanupAssociations() # removed should now be 0 assert removed == 0 # valid should still be there assert NDBOpenIDStore.query().count() == number_of_valid
def test_getAssociation(self): # prepare associations for "url_a" url_a_associations = [] # add some valid associations with ascending issue times and descending expiration # so the most recently issued is url_b_associations[4] # and the longest valid is url_b_associations[0] url_a_associations += [ Association(handle='handle-{}'.format(i), secret='secret', issued=int(time.time()) + i, lifetime=3600 - i * 10, assoc_type='HMAC-SHA1') for i in range(5) ] # add some expired associations url_a_associations += [ Association(handle='handle-{}'.format(i), secret='secret', issued=int(time.time()) - 3600, lifetime=1, assoc_type='HMAC-SHA1') for i in range(5, 10) ] # store them for assoc in url_a_associations: NDBOpenIDStore.storeAssociation('url_a', assoc) # prepare associations for "url_b" url_b_associations = [] # add some valid associations with ascending issue times and descending expiration # so the most recently issued is url_b_associations[4] # and the longest valid is url_b_associations[0] url_b_associations += [ Association(handle='handle-{}'.format(i), secret='secret', issued=int(time.time()) + i, lifetime=3600 - i * 10, assoc_type='HMAC-SHA1') for i in range(5) ] # add some expired associations url_b_associations += [ Association(handle='handle-{}'.format(i), secret='secret', issued=int(time.time()) - 3600, lifetime=1, assoc_type='HMAC-SHA1') for i in range(5, 10) ] # store them under "url_a" for assoc in url_b_associations: NDBOpenIDStore.storeAssociation('url_b', assoc) # check whether they are all there assert len(url_a_associations + url_b_associations) == NDBOpenIDStore.query().count() # call the tested method # test for "url_a" # get a valid association with url and handle association = NDBOpenIDStore.getAssociation('url_a', 'handle-3') assert association == url_a_associations[3] # get a valid association with url only # should return the most recent association association = NDBOpenIDStore.getAssociation('url_a') assert association == url_a_associations[4] # test for "url_b" # get a valid association with url and handle association = NDBOpenIDStore.getAssociation('url_b', 'handle-2') assert association == url_b_associations[2] # get a valid association with url only # should return the most recent association association = NDBOpenIDStore.getAssociation('url_b') assert association == url_b_associations[4] # test for non existent url association = NDBOpenIDStore.getAssociation('non_existent_url') assert association is None
def as_association(self): """Return an equivalent openid-python `Association` object.""" return Association( self.handle.encode('ASCII'), self.secret, self.issued, self.lifetime, self.assoc_type.encode('ASCII'))