diff --git a/jsc_custom/authenticator/oauthenticator.py b/jsc_custom/authenticator/oauthenticator.py index e330360006c18a893b09744fd2aaaeb87860fdde..3dde5236a1f782c1f74a701a1e05527414a2a9fc 100644 --- a/jsc_custom/authenticator/oauthenticator.py +++ b/jsc_custom/authenticator/oauthenticator.py @@ -40,6 +40,17 @@ res_pattern = re.compile( r"(?P<accounttype>[^:]+)$" ) +res_groups_pattern = re.compile( + r"^urn:" + r"(?P<namespace>.+?(?=:res:)):" + r"res:" + r"(?P<parentgroup>[^:]+)?" + r"(?::(?!role=)(?P<childgroup>[^:#]+))?" + r"(?::(?!role=)(?P<grandchildgroup>[^:#]+))?" + r"(?::role=(?P<role>[^#]+))?" + r"#(?P<authority>.+)$" +) + group_pattern = re.compile( r"^urn:" r"(?P<namespace>.+?(?=:group:)):" @@ -81,7 +92,9 @@ def get_groups_default(user_info): - urn:<namespace>:group:parentgroup#authority - default """ - entitlements = user_info.get("entitlements", []) + entitlements = user_info.get( + "entitlements", user_info.get("oauth_user", {}).get("entitlements", []) + ) groups = [] def add_sub_groups(group, role, authority, rightmost_group=True): @@ -126,9 +139,47 @@ def get_groups_default(user_info): groups.append(group) add_sub_groups(group, role, authority, rightmost_group) rightmost_group = False + else: + match = res_groups_pattern.match(entry) + if match: + namespace = match.group("namespace") + grandchildgroup = match.group("grandchildgroup") + childgroup = match.group("childgroup") + parentgroup = match.group("parentgroup") + role = match.group("role") + authority = match.group("authority") + rightmost_group = True + if grandchildgroup: + group = f"urn:{namespace}:group:{parentgroup}:{childgroup}:{grandchildgroup}" + if group not in groups: + groups.append(group) + add_sub_groups(group, role, authority, rightmost_group) + rightmost_group = False + if childgroup: + group = f"{namespace}:{parentgroup}:{childgroup}" + if group not in groups: + groups.append(group) + add_sub_groups(group, role, authority, rightmost_group) + rightmost_group = False + if parentgroup: + group = f"{namespace}:{parentgroup}" + if group not in groups: + groups.append(group) + add_sub_groups(group, role, authority, rightmost_group) + rightmost_group = False if "default" not in groups: groups.append("default") + + for attribute in ["org_domain", "voperson_external_affiliation"]: + value = user_info.get( + attribute, user_info.get("oauth_user", {}).get(attribute, None) + ) + if value and type(value) == list: + groups.extend(value) + elif value and type(value) == str: + groups.append(value) + return list(set(groups)) @@ -550,23 +601,26 @@ class CustomGenericOAuthenticator(GenericOAuthenticator): # - last login (additional information for the user) # - used authenticator (to classify user) # - hpc_list (allowed systems, projects, partitions, etc.) - access_token = authentication["auth_state"]["access_token"] - headers = { - "Accept": "application/json", - "User-Agent": "JupyterHub", - "Authorization": f"Bearer {access_token}", - } - req = HTTPRequest(self.tokeninfo_url, method="GET", headers=headers) - try: - resp = await authenticator.fetch(req) - except HTTPClientError as e: - authenticator.log.warning( - "{name} - Could not request user information - {e}".format( - name=authentication.get("name", "unknownName"), e=e + if self.tokeninfo_url: + access_token = authentication["auth_state"]["access_token"] + headers = { + "Accept": "application/json", + "User-Agent": "JupyterHub", + "Authorization": f"Bearer {access_token}", + } + req = HTTPRequest(self.tokeninfo_url, method="GET", headers=headers) + try: + resp = await authenticator.fetch(req) + except HTTPClientError as e: + authenticator.log.warning( + "{name} - Could not request user information - {e}".format( + name=authentication.get("name", "unknownName"), e=e + ) ) - ) - raise Exception(e) - authentication["auth_state"]["exp"] = resp.get("exp") + raise Exception(e) + authentication["auth_state"]["exp"] = resp.get("exp") + else: + authentication["auth_state"]["exp"] = time.time() + 1200 preferred_username = ( authentication["auth_state"]