From 21bf6af02e33865f00319467ba4670fa3d872961 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Fri, 29 Oct 2021 08:33:37 +0300 Subject: Add auth module --- gn3/authentication.py | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 gn3/authentication.py (limited to 'gn3') diff --git a/gn3/authentication.py b/gn3/authentication.py new file mode 100644 index 0000000..baf2c7a --- /dev/null +++ b/gn3/authentication.py @@ -0,0 +1,94 @@ +import functools +import json +import redis +import requests + +from typing import Dict +from enum import Enum, unique +from urllib.parse import urljoin + + +@functools.total_ordering +class OrderedEnum(Enum): + @classmethod + @functools.lru_cache(None) + def _member_list(cls): + return list(cls) + + def __lt__(self, other): + if self.__class__ is other.__class__: + member_list = self.__class__._member_list() + return member_list.index(self) < member_list.index(other) + return NotImplemented + + +@unique +class DataRole(OrderedEnum): + NO_ACCESS = "no-access" + VIEW = "view" + EDIT = "edit" + + +@unique +class AdminRole(OrderedEnum): + NOT_ADMIN = "not-admin" + EDIT_ACCESS = "edit-access" + EDIT_ADMINS = "edit-admins" + + +def get_user_membership(conn: redis.Redis, user_id: str, + group_id: str) -> Dict: + """Return a dictionary that indicates whether the `user_id` is a + member or admin of `group_id`. + + Args: + - conn: a Redis Connection with the responses decoded. + - user_id: a user's unique id + e.g. '8ad942fe-490d-453e-bd37-56f252e41603' + - group_id: a group's unique id + e.g. '7fa95d07-0e2d-4bc5-b47c-448fdc1260b2' + + Returns: + A dict indicating whether the user is an admin or a member of + the group: {"member": True, "admin": False} + + """ + results = {"member": False, "admin": False} + for key, value in conn.hgetall('groups').items(): + if key == group_id: + group_info = json.loads(value) + if user_id in group_info.get("admins"): + results["admin"] = True + if user_id in group_info.get("members"): + results["member"] = True + break + return results + + +def get_highest_user_access_role( + resource_id: str, + user_id: str, + gn_proxy_url: str = "http://localhost:8080") -> Dict: + """Get the highest access roles for a given user + + Args: + - resource_id: The unique id of a given resource. + - user_id: The unique id of a given user. + - gn_proxy_url: The URL where gn-proxy is running. + + Returns: + A dict indicating the highest access role the user has. + + """ + role_mapping = {} + for x, y in zip(DataRole, AdminRole): + role_mapping.update({x.value: x, }) + role_mapping.update({y.value: y, }) + access_role = {} + for key, value in json.loads( + requests.get(urljoin( + gn_proxy_url, + ("available?resource=" + f"{resource_id}&user={user_id}"))).content).items(): + access_role[key] = max(map(lambda x: role_mapping[x], value)) + return access_role -- cgit v1.2.3