From 27cdbda145b6602e87e641f3f1c9c3b6514ee205 Mon Sep 17 00:00:00 2001 From: FracassandoCasualmente Date: Tue, 31 Oct 2023 11:34:25 +0000 Subject: [PATCH] Fixed registered-level access based on Visas --- permissions/auth.py | 6 +++--- permissions/plugins.py | 2 +- permissions/tokens.py | 29 +++++++++++++++++++++++------ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/permissions/auth.py b/permissions/auth.py index bdaac0d0..1cd9b58f 100644 --- a/permissions/auth.py +++ b/permissions/auth.py @@ -17,9 +17,6 @@ from aiohttp import ClientSession, BasicAuth, FormData from aiohttp import web -from permissions.db import search_token -from permissions.tokens import verify_registered - LOG = logging.getLogger(__name__) idp_client_id = config('CLIENT_ID') @@ -46,6 +43,9 @@ REMS_BEACON_RESOURCE_PREFIX = config('REMS_BEACON_RESOURCE_PREFIX') REMS_PUB_URL = config('REMS_PUB_URL') +from permissions.db import search_token +from permissions.tokens import verify_registered + async def get_user_info(access_token): ''' We use the access_token to get the user info. diff --git a/permissions/plugins.py b/permissions/plugins.py index 46ffdfe3..2cab1fe7 100644 --- a/permissions/plugins.py +++ b/permissions/plugins.py @@ -165,7 +165,7 @@ async def get(self, username, requested_datasets=None): except Exception as e: - LOG.error(f"Error while parsing passport from REMS:{str(e)}\n") + LOG.error(f"Error while parsing passport from REMS: {str(e)}\n") return [] # remove duplicates diff --git a/permissions/tokens.py b/permissions/tokens.py index a7c5b982..f87ca20c 100644 --- a/permissions/tokens.py +++ b/permissions/tokens.py @@ -61,14 +61,23 @@ def verify_access_token(access_token) -> Tuple[bool, int, int]: # raises Exception if error occurs def parse_visa(visa, user_id): + visa_type = "Unknown" + try: - payload = jwt.decode_jwt(visa) + payload = decode_jwt(visa) + + visa_type = payload.get("ga4gh_visa_v1",{}).get("type", "Unknown") if payload['exp'] < time.time(): raise web.HTTPUnauthorized(text="Visa is expired") - if payload["sub"] != user_id: - raise web.HTTPUnauthorized(text="Visa is not for the right user") + # unify @lifescience and @elixir-europe user ids + jwt_sub = payload["sub"].replace("@lifescience-ri.eu","@elixir-europe.org") + + if jwt_sub != user_id: + raise web.HTTPUnauthorized(text=f"Visa is not for the right user.\n" + f"Visa is for user {payload['sub']}\n" + f"Expected user {user_id}\n") # verify that it has the expected value and that it is not empty if not payload["ga4gh_visa_v1"]["value"].strip(): @@ -86,8 +95,10 @@ def parse_visa(visa, user_id): except Exception as e: - LOG.error(f"Error while verifying visa.\n{str(e)}") - LOG.debug(f"visa:\n\n{visa}\n") + LOG.error(f"Error while verifying visa:") + LOG.error(f"Type of Visa: {visa_type}") + LOG.error(f"{e} - {e.text}") + LOG.debug(f"visa: {visa}\n") raise web.HTTPUnauthorized(text=f"Error while verifying visa.") return payload @@ -104,6 +115,7 @@ def verify_registered(passport:List[str], user_id) -> bool: for encoded_visa in passport: try: decoded_visa = parse_visa(encoded_visa, user_id)["ga4gh_visa_v1"] + LOG.debug(f"Visa type = {decoded_visa['type']}") if decoded_visa["type"] == "ResearcherStatus": found_researcher_status = True elif decoded_visa["type"] == "AcceptedTermsAndPolicies": @@ -111,8 +123,13 @@ def verify_registered(passport:List[str], user_id) -> bool: except Exception as e: LOG.error(f"Error verifying visa: {e}") + continue + + LOG.debug(f"Visa ok!") if found_researcher_status and found_accepted_terms: + LOG.debug(f"Bonadide OK!") return True - + + LOG.debug(f"No Bonafide") return False \ No newline at end of file