def add_nonce(cls, actor_id, nonce): """ Atomically append a new nonce to the nonce_store for an actor. The actor_id parameter should be the db_id and the nonce parameter should be a nonce object created from the contructor. """ try: nonce_store.update(actor_id, nonce.id, nonce) logger.debug("nonce {} appended to nonces for actor {}".format(nonce.id, actor_id)) except KeyError: nonce_store[actor_id] = {nonce.id: nonce} logger.debug("nonce {} added for actor {}".format(nonce.id, actor_id))
def _transaction(nonces): """ This function can be passed to nonce_store.within_transaction() to atomically check whether a nonce is expired and, if not, redeem a use. The parameter, nonces, should be the value under the key `actor_id` associated with the nonce. """ # first pull the nonce from the nonces parameter try: nonce = nonces[nonce_id] except KeyError: raise errors.PermissionsException("Nonce does not exist.") # check if the nonce level is sufficient try: if PermissionLevel(nonce['level']) < level: raise errors.PermissionsException( "Nonce does not have sufficient permissions level.") except KeyError: raise errors.PermissionsException( "Nonce did not have an associated level.") # check if there are remaining uses try: if nonce['remaining_uses'] == -1: logger.debug("nonce has infinite uses. updating nonce.") nonce['current_uses'] += 1 nonce['last_use_time'] = get_current_utc_time() nonce_store.update(actor_id, nonce_id, nonce) elif nonce['remaining_uses'] > 0: logger.debug( "nonce still has uses remaining. updating nonce.") nonce['current_uses'] += 1 nonce['remaining_uses'] -= 1 nonce_store.update(actor_id, nonce_id, nonce) else: logger.debug( "nonce did not have at least 1 use remaining.") raise errors.PermissionsException( "No remaining uses left for this nonce.") except KeyError: logger.debug("nonce did not have a remaining_uses attribute.") raise errors.PermissionsException( "No remaining uses left for this nonce.")