diff options
Diffstat (limited to 'gn2/utility/redis_tools.py')
-rw-r--r-- | gn2/utility/redis_tools.py | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/gn2/utility/redis_tools.py b/gn2/utility/redis_tools.py new file mode 100644 index 00000000..b3d197a9 --- /dev/null +++ b/gn2/utility/redis_tools.py @@ -0,0 +1,285 @@ +import uuid +import simplejson as json +import datetime + +import redis # used for collections + +from gn2.utility.hmac import hmac_creation + + +def get_redis_conn(): + Redis = redis.StrictRedis(port=6379) + return Redis + + +Redis = get_redis_conn() + + +def is_redis_available(): + try: + Redis.ping() + except: + return False + return True + + +def load_json_from_redis(item_list, column_value): + if type(column_value) == str: + column_value = str.encode(column_value) + try: + return json.loads(item_list[column_value]) + except: + return None + + +def get_user_id(column_name, column_value): + user_list = Redis.hgetall("users") + key_list = [] + for key in user_list: + user_ob = json.loads(user_list[key]) + if column_name in user_ob and user_ob[column_name] == column_value: + return key + + return None + + +def get_user_by_unique_column(column_name, column_value): + item_details = None + + user_list = Redis.hgetall("users") + if column_name != "user_id": + for key in user_list: + user_ob = json.loads(user_list[key]) + if column_name in user_ob and user_ob[column_name] == column_value: + item_details = user_ob + else: + item_details = load_json_from_redis(user_list, column_value) + + return item_details + + +def set_user_attribute(user_id, column_name, column_value): + user_info = json.loads(Redis.hget("users", user_id)) + user_info[column_name] = column_value + + Redis.hset("users", user_id, json.dumps(user_info)) + + +def get_user_collections(user_id): + collections = None + collections = Redis.hget("collections", user_id) + + if collections: + return json.loads(collections) + else: + return [] + + +def save_user(user, user_id): + Redis.hset("users", user_id, json.dumps(user)) + + +def save_collections(user_id, collections_ob): + Redis.hset("collections", user_id, collections_ob) + + +def save_verification_code(user_email, code): + Redis.hset("verification_codes", code, user_email) + + +def check_verification_code(code): + email_address = None + user_details = None + email_address = Redis.hget("verification_codes", code) + + if email_address: + user_details = get_user_by_unique_column( + 'email_address', email_address) + if user_details: + return user_details + else: + return None + else: + return None + + +def get_user_groups(user_id): + # Get the groups where a user is an admin or a member and + # return lists corresponding to those two sets of groups + admin_group_ids = [] # Group IDs where user is an admin + user_group_ids = [] # Group IDs where user is a regular user + groups_list = Redis.hgetall("groups") + for group_id, group_details in groups_list.items(): + try: + _details = json.loads(group_details) + group_admins = set([this_admin if this_admin else None for this_admin in _details['admins']]) + group_members = set([this_member if this_member else None for this_member in _details['members']]) + if user_id in group_admins: + admin_group_ids.append(group_id) + elif user_id in group_members: + user_group_ids.append(group_id) + else: + continue + except: + continue + + admin_groups = [] + user_groups = [] + for the_id in admin_group_ids: + admin_groups.append(get_group_info(the_id)) + for the_id in user_group_ids: + user_groups.append(get_group_info(the_id)) + + return admin_groups, user_groups + + +def get_group_info(group_id): + group_json = Redis.hget("groups", group_id) + group_info = None + if group_json: + group_info = json.loads(group_json) + + return group_info + + +def create_group(admin_user_ids, member_user_ids=[], + group_name="Default Group Name"): + group_id = str(uuid.uuid4()) + new_group = { + "id": group_id, + "admins": admin_user_ids, + "members": member_user_ids, + "name": group_name, + "created_timestamp": datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p'), + "changed_timestamp": datetime.datetime.utcnow().strftime('%b %d %Y %I:%M%p') + } + + Redis.hset("groups", group_id, json.dumps(new_group)) + + return new_group + + +def delete_group(user_id, group_id): + # ZS: If user is an admin of a group, remove it from the groups hash + group_info = get_group_info(group_id) + if user_id in group_info["admins"]: + Redis.hdel("groups", group_id) + return get_user_groups(user_id) + else: + None + + +# ZS "admins" is just to indicate whether the users should be added to +# the groups admins or regular users set +def add_users_to_group(user_id, group_id, user_emails=[], admins=False): + group_info = get_group_info(group_id) + # ZS: Just to make sure that the user is an admin for the group, + # even though they shouldn't be able to reach this point unless + # they are + if user_id in group_info["admins"]: + if admins: + group_users = set(group_info["admins"]) + else: + group_users = set(group_info["members"]) + + for email in user_emails: + user_id = get_user_id("email_address", email) + group_users.add(user_id) + + if admins: + group_info["admins"] = list(group_users) + else: + group_info["members"] = list(group_users) + + group_info["changed_timestamp"] = datetime.datetime.utcnow().strftime( + '%b %d %Y %I:%M%p') + Redis.hset("groups", group_id, json.dumps(group_info)) + return group_info + else: + return None + + +# ZS: User type is because I assume admins can remove other admins +def remove_users_from_group(user_id, + users_to_remove_ids, + group_id, + user_type="members"): + group_info = get_group_info(group_id) + + if user_id in group_info["admins"]: + users_to_remove_set = set(users_to_remove_ids) + # ZS: Make sure an admin can't remove themselves from a group, + # since I imagine we don't want groups to be able to become + # admin-less + if user_type == "admins" and user_id in users_to_remove_set: + users_to_remove_set.remove(user_id) + group_users = set(group_info[user_type]) + group_users -= users_to_remove_set + group_info[user_type] = list(group_users) + group_info["changed_timestamp"] = datetime.datetime.utcnow().strftime( + '%b %d %Y %I:%M%p') + Redis.hset("groups", group_id, json.dumps(group_info)) + + +def change_group_name(user_id, group_id, new_name): + group_info = get_group_info(group_id) + if user_id in group_info["admins"]: + group_info["name"] = new_name + Redis.hset("groups", group_id, json.dumps(group_info)) + return group_info + else: + return None + + +def get_resources(): + resource_list = Redis.hgetall("resources") + return resource_list + + +def get_resource_id(dataset, trait_id=None): + resource_id = False + if dataset.type == "Publish": + if trait_id: + resource_id = hmac_creation("{}:{}:{}".format( + 'dataset-publish', dataset.id, trait_id)) + elif dataset.type == "ProbeSet": + resource_id = hmac_creation( + "{}:{}".format('dataset-probeset', dataset.id)) + elif dataset.type == "Geno": + resource_id = hmac_creation( + "{}:{}".format('dataset-geno', dataset.id)) + + return resource_id + + +def get_resource_info(resource_id): + resource_info = Redis.hget("resources", resource_id) + if resource_info: + return json.loads(resource_info) + else: + return None + + +def add_resource(resource_info, update=True): + if 'trait' in resource_info['data']: + resource_id = hmac_creation('{}:{}:{}'.format( + str(resource_info['type']), str( + resource_info['data']['dataset']), + str(resource_info['data']['trait']))) + else: + resource_id = hmac_creation('{}:{}'.format( + str(resource_info['type']), str(resource_info['data']['dataset']))) + + if update or not Redis.hexists("resources", resource_id): + Redis.hset("resources", resource_id, json.dumps(resource_info)) + + return resource_info + + +def add_access_mask(resource_id, group_id, access_mask): + the_resource = get_resource_info(resource_id) + the_resource['group_masks'][group_id] = access_mask + + Redis.hset("resources", resource_id, json.dumps(the_resource)) + + return the_resource |