Created
September 4, 2018 06:49
-
-
Save darrenjs/2505df8ad6ab2782b2f0e6f4c811a65c to your computer and use it in GitHub Desktop.
Revisions
-
darrenjs renamed this gist
Sep 4, 2018 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
darrenjs created this gist
Sep 4, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,80 @@ import redis import redis.sentinel import logging # TODO: would be useful to also def discover_redis_master(sentinel_addrs, redis_name): """Use listed sentinels to find the redis master """ sentinel = redis.sentinel.Sentinel(sentinel_addrs, socket_timeout=0.1) master_addr = sentinel.discover_master(redis_name) redis_client = sentinel.master_for(redis_name, socket_timeout=0.1) if redis_client.ping(): return redis_client, master_addr else: raise Exception("failed to ping redis master") class SignupState: CHKSUM_FAILED = "chksum mismatch" NO_SUCH_REQUEST = "no such request" ALREADY_VERIFIED = "already verified" BACKEND_ERROR = "backend error" SUCCESS = "success" NOT_PENDING = "not pending" # TODO: add enum here (as class) for signup status # Attempt to update a redis signup record, to indicate that the user has clicked # in order to verify the signup. def update_signup_record_to_verified(r, user_key, user_chksum): stored_obj = r.hgetall(user_key) if not stored_obj: logging.warning("{}: signup request not found".format(user_key)) return SignupState.NO_SUCH_REQUEST status = stored_obj[b'status'].decode('utf-8') chksum = stored_obj[b'chksum'].decode('utf-8') # Check the user provided checksum matches the signup checksum. This is # needed so that an invalid (spoofing?) attempt to validate a signup account # can be detected. So for signup to be successful, the user needs to new the # signup key (which is guessable), the encoding key, and the original record # checksum. if user_chksum != chksum: logging.warn("verify failed; chksum mismatch") return SignupState.CHKSUM_FAILED # TODO: return error codes in here, instead of exceptions if (status == 'pending'): rv = r.hset(user_key, 'status', 'verified') if rv == 0: logging.info("{}: signup status set to verified".format(user_key)) # TODO: here, set the state to 'verified' return SignupState.SUCCESS else: logging.warn("hset expectedly returned value {}".format(rv)) return SignupState.BACKEND_ERROR else: logging.warn( "{}: sign-up request is not in pending state, so cannot progress to verified; current state is '{}'".format(user_key, status)) return SignupState.NOT_PENDING def get_global_id_block(r, key, blocksize=100): """Reserve a block of global id numbers. The usable inclusive range is returned in the tuple as (lower,upper). """ assert isinstance(key, str) assert isinstance(blocksize, int) upper = r.incrby(key, max(blocksize, 1)) #lower = max(1, upper-blocksize) # min valid id is 1 return (upper-blocksize, upper-1)