From f9e26efeb7b21ad90892ded13f229a58e4f77335 Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Tue, 2 Jun 2026 06:37:43 -0500 Subject: [PATCH 01/14] Remove assertion that collection_id matches item.collection --- src/client.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/client.py b/src/client.py index 4ef26d1..503041b 100644 --- a/src/client.py +++ b/src/client.py @@ -65,14 +65,17 @@ def allowed_groups(self, properties, acp) -> list: return groups return [] - def globus_authorize(self, item: Item, request: Request, collection_id: str) -> dict: + def globus_authorize( + self, + collection_id: str, + item: Item, + role: str, + request: Request, + request_id: str, + event_id: str, + ) -> dict: properties = item.properties - if item.collection != collection_id: - raise ValueError("Item collection must match path collection_id") - if getattr(properties, "project", None) != collection_id: - raise ValueError("Item project must match path collection_id") - allowed_groups = self.allowed_groups(properties, settings.client.access_control_policy) allowed_groups_uuid = [g.get("uuid") for g in allowed_groups] @@ -151,7 +154,14 @@ def authorize( ) -> Auth: if settings.authorizer == "globus": - return self.globus_authorize(collection_id=collection_id, item=item, request=request) + return self.globus_authorize( + collection_id=collection_id, + item=item, + role=role, + request=request, + request_id=request_id, + event_id=event_id, + ) else: return self.egi_authorize( collection_id=collection_id, From 7ecfae315fa347f2fefa2c9459b4ac27be3eece1 Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Tue, 2 Jun 2026 07:47:36 -0500 Subject: [PATCH 02/14] Use item_id to extract institute_id from PATCH request --- src/client.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/client.py b/src/client.py index 503041b..c6d5bfe 100644 --- a/src/client.py +++ b/src/client.py @@ -73,8 +73,18 @@ def globus_authorize( request: Request, request_id: str, event_id: str, + item_id: str = None, ) -> dict: - properties = item.properties + if role == "CREATE": + properties = item.properties + elif role == "UPDATE" and item_id: + facets = item_id.split(".") + properties = { + "project": collection_id, + "institute_id": facets[2], + } + else: + properties = item.properties allowed_groups = self.allowed_groups(properties, settings.client.access_control_policy) allowed_groups_uuid = [g.get("uuid") for g in allowed_groups] @@ -151,6 +161,7 @@ def authorize( request: Request, request_id: str, event_id: str, + item_id: str = None, ) -> Auth: if settings.authorizer == "globus": @@ -161,6 +172,7 @@ def authorize( request=request, request_id=request_id, event_id=event_id, + item_id=item_id, ) else: return self.egi_authorize( @@ -352,6 +364,7 @@ async def patch_item( request=request, request_id=request_id, event_id=event_id, + item_id=item_id, ) item_extensions = item.stac_extensions if item.stac_extensions else [] From 06cec60054826671e18b5d435f4c2cd72824dc28 Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Tue, 2 Jun 2026 07:55:42 -0500 Subject: [PATCH 03/14] Use item_id to extract institute_id from PATCH request --- src/client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client.py b/src/client.py index c6d5bfe..2dea2c2 100644 --- a/src/client.py +++ b/src/client.py @@ -79,9 +79,10 @@ def globus_authorize( properties = item.properties elif role == "UPDATE" and item_id: facets = item_id.split(".") + extension_id = collection_id.lower() properties = { "project": collection_id, - "institute_id": facets[2], + f"{extension_id}:institute_id": facets[2], } else: properties = item.properties From 6b6f055097bfa239c1afe2e7703484bffd79a272 Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Tue, 2 Jun 2026 07:59:18 -0500 Subject: [PATCH 04/14] Use item_id to extract institute_id from PATCH request --- src/client.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/client.py b/src/client.py index 2dea2c2..3e19683 100644 --- a/src/client.py +++ b/src/client.py @@ -87,7 +87,9 @@ def globus_authorize( else: properties = item.properties + logger.info("PROPERTIES: %s", properties) allowed_groups = self.allowed_groups(properties, settings.client.access_control_policy) + logger.info("ALLOWED GROUPS: %s", allowed_groups) allowed_groups_uuid = [g.get("uuid") for g in allowed_groups] authorizer = request.state.authorizer From 3979cc0add8ff26c22d79a50d7530343021e178f Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Tue, 2 Jun 2026 08:23:30 -0500 Subject: [PATCH 05/14] Use item_id to extract institute_id from PATCH request --- src/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client.py b/src/client.py index 3e19683..ec2fb45 100644 --- a/src/client.py +++ b/src/client.py @@ -82,7 +82,7 @@ def globus_authorize( extension_id = collection_id.lower() properties = { "project": collection_id, - f"{extension_id}:institute_id": facets[2], + f"{extension_id}:institution_id": facets[2], } else: properties = item.properties From 9d43a3a1af67fe856255055f99261beff1cc6379 Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Tue, 2 Jun 2026 08:40:38 -0500 Subject: [PATCH 06/14] Use item_id to extract institute_id from PATCH request --- src/client.py | 2 + .../config/access_control_policy.json | 51 ++++++++----------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/client.py b/src/client.py index ec2fb45..72865a8 100644 --- a/src/client.py +++ b/src/client.py @@ -54,8 +54,10 @@ def allowed_groups(self, properties, acp) -> list: if isinstance(acp, list): return acp for facet, subpolicy in acp.items(): + logger.info("FACET: %s", facet) if hasattr(properties, facet): property_value = getattr(properties, facet) + logger.info("PROPERTY VALUE: %s", property_value) if isinstance(property_value, str): property_value = [property_value] matches = list(set(property_value) & set(subpolicy.keys())) diff --git a/src/settings/config/access_control_policy.json b/src/settings/config/access_control_policy.json index 1476eaf..1fb1df8 100644 --- a/src/settings/config/access_control_policy.json +++ b/src/settings/config/access_control_policy.json @@ -2,7 +2,7 @@ "project": { "CMIP6": { "cmip6:institution_id": { - "ALCF": [ + "AER": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", @@ -16,34 +16,6 @@ "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "EC-Earth-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "LLNL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UCI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "AER": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], "AWI": [ { "name": "ESGFNG Integration", @@ -142,6 +114,13 @@ "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], + "EC-Earth-Consortium": [ + { + "name": "ESGFNG Integration", + "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", + "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" + } + ], "FIO-QLNM": [ { "name": "ESGFNG Integration", @@ -177,6 +156,13 @@ "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], + "LLNL": [ + { + "name": "ESGFNG Integration", + "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", + "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" + } + ], "MIROC": [ { "name": "ESGFNG Integration", @@ -303,6 +289,13 @@ "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], + "UCI": [ + { + "name": "ESGFNG Integration", + "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", + "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" + } + ], "UCSB": [ { "name": "ESGFNG Integration", From afcfb09d2fd165a179fd40ff223a40bad1db5cce Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Wed, 3 Jun 2026 03:36:15 -0500 Subject: [PATCH 07/14] Update istitutions for CORDEX-CMIP6 --- src/client.py | 14 +-- .../config/access_control_policy.json | 111 ++++++++---------- 2 files changed, 58 insertions(+), 67 deletions(-) diff --git a/src/client.py b/src/client.py index 72865a8..2f1c2c7 100644 --- a/src/client.py +++ b/src/client.py @@ -2,6 +2,8 @@ import uuid from datetime import datetime from typing import Optional, Union +from types import SimpleNamespace + from esgf_core_utils.models.auth.egi import EGIAuth from esgf_core_utils.models.exceptions import ( @@ -54,10 +56,8 @@ def allowed_groups(self, properties, acp) -> list: if isinstance(acp, list): return acp for facet, subpolicy in acp.items(): - logger.info("FACET: %s", facet) if hasattr(properties, facet): property_value = getattr(properties, facet) - logger.info("PROPERTY VALUE: %s", property_value) if isinstance(property_value, str): property_value = [property_value] matches = list(set(property_value) & set(subpolicy.keys())) @@ -77,19 +77,17 @@ def globus_authorize( event_id: str, item_id: str = None, ) -> dict: + extension_id = collection_id.lower() if role == "CREATE": properties = item.properties elif role == "UPDATE" and item_id: + properties = SimpleNamespace() facets = item_id.split(".") - extension_id = collection_id.lower() - properties = { - "project": collection_id, - f"{extension_id}:institution_id": facets[2], - } + setattr(properties, "project", collection_id) + setattr(properties, f"{extension_id}:institution_id", facets[2]) else: properties = item.properties - logger.info("PROPERTIES: %s", properties) allowed_groups = self.allowed_groups(properties, settings.client.access_control_policy) logger.info("ALLOWED GROUPS: %s", allowed_groups) allowed_groups_uuid = [g.get("uuid") for g in allowed_groups] diff --git a/src/settings/config/access_control_policy.json b/src/settings/config/access_control_policy.json index 1fb1df8..50ea6f7 100644 --- a/src/settings/config/access_control_policy.json +++ b/src/settings/config/access_control_policy.json @@ -1271,371 +1271,364 @@ }, "CORDEX-CMIP6": { "cordex-cmip6:institution_id": { - "AER": [ + "AUTH": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "AS-RCEC": [ + "BAS": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "AWI": [ + "BCCR-UCAN": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "BCC": [ + "BOM": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "BNU": [ + "CCCma": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CAMS": [ + "CESAM-UA": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CAS": [ + "CLMcom-AWI": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CCCR-IITM": [ + "CLMcom-BTU": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CCCma": [ + "CLMcom-CMCC": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CMCC": [ + "CLMcom-DWD": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CNRM-CERFACS": [ + "CLMcom-ETH": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CSIR-Wits-CSIRO": [ + "CLMcom-FZJ": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CSIRO": [ + "CLMcom-GERICS": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CSIRO-ARCCSS": [ + "CLMcom-GUF": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "CSIRO-COSIMA": [ + "CLMcom-Hereon": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "DKRZ": [ + "CLMcom-IMWM": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "DWD": [ + "CLMcom-KUL": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "E3SM-Project": [ + "CLMcom-LIST": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "EC-Earth-Consortium": [ + "CLMcom-WEGC": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "ECMWF": [ + "CNR-ISAC": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "FIO-QLNM": [ + "CNRM": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "HAMMOZ-Consortium": [ + "CNRM-MF": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "INM": [ + "CORNELL": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "INPE": [ + "CSIRO": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "IPSL": [ + "CYI": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "KIOST": [ + "DWD-BSH": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "LLNL": [ + "ENEA": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "MESSy-Consortium": [ + "GERICS": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "MIROC": [ + "HCLIMcom-DMI": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "MOHC": [ + "HCLIMcom-METNo": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "MPI-M": [ + "HCLIMcom-SMHI": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "MRI": [ + "ICTP": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "NASA-GISS": [ + "IDL-FCUL": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "NASA-GSFC": [ + "IFCA": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "NCAR": [ + "IMWM": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "NCC": [ + "IRD-MF": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "NERC": [ + "IUM-FDU": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "NIMS-KMA": [ + "KNMI": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "NIWA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NOAA-GFDL": [ + "MOHC": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "NTU": [ + "NCAR": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "NUIST": [ + "NIMS-KMA": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "PCMDI": [ + "NKUA": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "PNNL-WACCEM": [ + "NORCE-BCCR": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "RTE-RRTMGP-Consortium": [ + "OURANOS": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "RUBISCO": [ + "RMIB-UGent": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "SNU": [ + "RU-CORE": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "THU": [ + "SENAMHI-PER": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "UA": [ + "TASK-IMWM": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "UCI": [ + "UBA-CIMA-IFAECI": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "UHH": [ + "UNSW-CCRC": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "UTAS": [ + "UQ-DEC": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" } ], - "UofT": [ + "UU-IMAU": [ { "name": "ESGFNG Integration", "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", From fffc7ae7f9a6fe975e6d15b603c20bfe26409c6c Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Wed, 3 Jun 2026 09:52:57 -0500 Subject: [PATCH 08/14] Fix validate_patch() definition --- src/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/utils.py b/src/utils.py index 7bb24e9..eaa6dde 100644 --- a/src/utils.py +++ b/src/utils.py @@ -171,6 +171,8 @@ def get_extension_validator(extension: str) -> Validator: def validate_patch( + event_id: str, + request_id: str, item_id: str, item: PartialItem, extensions: list[str], From ad7f898c393c2ea163b25998fd0d069038450dd4 Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Wed, 3 Jun 2026 11:47:04 -0500 Subject: [PATCH 09/14] Dump patch operations correctly --- src/client.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/client.py b/src/client.py index 2f1c2c7..41ab349 100644 --- a/src/client.py +++ b/src/client.py @@ -384,11 +384,16 @@ async def patch_item( user_agent = headers.get("user-agent", "/").split("/") + if isinstance(patch, list): + patch_body = [op.model_dump() for op in patch] + else: + patch_body = item.model_dump() + payload = PatchPayload( method="PATCH", collection_id=collection_id, item_id=item_id, - patch=patch.model_dump(), + patch=patch_body, ) data = Data(type="STAC", payload=payload) From 8f102855503da2b408019d03374ebe62dafe628d Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Sun, 7 Jun 2026 01:49:12 -0500 Subject: [PATCH 10/14] Cache access control policy; include validation error cause in responses --- src/authorizer/globus_authorizer.py | 67 +++++++++++++++++++++++++++-- src/client.py | 7 +-- src/settings/globus.py | 53 +---------------------- src/utils.py | 26 ++++++++--- 4 files changed, 91 insertions(+), 62 deletions(-) diff --git a/src/authorizer/globus_authorizer.py b/src/authorizer/globus_authorizer.py index eac4abb..ad79bde 100644 --- a/src/authorizer/globus_authorizer.py +++ b/src/authorizer/globus_authorizer.py @@ -1,9 +1,11 @@ import hashlib +import json import logging import time from dataclasses import dataclass from threading import Lock +import urllib3 from fastapi import Request from fastapi.responses import JSONResponse from globus_sdk import AccessTokenAuthorizer, GroupsClient @@ -77,6 +79,66 @@ def _evict_expired(self) -> None: _auth_cache = _AuthTTLCache() +@dataclass +class _CachedPolicy: + expires_at: float + policy: dict + + +_policy_cache: _CachedPolicy | None = None +_policy_lock = Lock() + + +def _load_access_control_policy(policy_path: str) -> dict: + logger.info("Loading access control policy from %s", policy_path) + parsed = urllib3.util.parse_url(policy_path) + if parsed.scheme == "file": + with open(parsed.path) as file: + logger.info("Access Control Policy loaded from %s", policy_path) + return json.load(file) + + http = urllib3.PoolManager() + response = http.request("GET", policy_path) + if response.status == 200: + logger.info("Access Control Policy loaded from %s", policy_path) + return json.loads(response.data.decode("utf-8")) + + raise RuntimeError( + f"Failed to load access control policy from {policy_path}: HTTP {response.status}" + ) + + +def get_access_control_policy() -> dict: + """Return access control policy, reloading from policy_path when cache expires.""" + global _policy_cache + + ttl = settings.client.policy_cache_ttl_seconds + now = time.monotonic() + + with _policy_lock: + if _policy_cache is not None and now < _policy_cache.expires_at: + return _policy_cache.policy + stale_policy = _policy_cache.policy if _policy_cache is not None else None + + try: + policy = _load_access_control_policy(settings.client.policy_path) + except Exception as exc: + if stale_policy is not None: + logger.warning("Access control policy refresh failed, using stale cache: %s", exc) + return stale_policy + raise + + with _policy_lock: + _policy_cache = _CachedPolicy(expires_at=now + ttl, policy=policy) + + return policy + + +def _authorizer_context(auth: dict) -> dict: + """Attach access control policy to token auth (policy has its own TTL cache).""" + return {**auth, "access_control_policy": get_access_control_policy()} + + def _cache_ttl_seconds(token_info: dict, max_ttl: int) -> int: exp = token_info.get("exp") if exp is None: @@ -108,7 +170,7 @@ async def dispatch(self, request: Request, call_next): access_token = authorization_header[7:].strip() cached_auth = _auth_cache.get(access_token) if cached_auth is not None: - request.state.authorizer = cached_auth + request.state.authorizer = _authorizer_context(cached_auth) return await call_next(request) response = settings.client.confidential_client.oauth2_token_introspect(access_token, include="identity_set_detail") @@ -131,7 +193,7 @@ async def dispatch(self, request: Request, call_next): } ttl = _cache_ttl_seconds(token_info, settings.client.authorizer_cache_ttl_seconds) _auth_cache.set(access_token, auth, ttl) - request.state.authorizer = auth + request.state.authorizer = _authorizer_context(auth) return await call_next(request) def _validate_token_info(self, token_info: dict) -> JSONResponse | None: @@ -169,7 +231,6 @@ def get_groups(self, token): Amazon API Gateway Authorization caching setting can be use to cache the authorizer response, and if the a new request with the same bearer token """ - tokens = settings.client.confidential_client.oauth2_get_dependent_tokens(token, scope=GroupsScopes.view_my_groups_and_memberships) groups_token = tokens.by_resource_server[GroupsClient.resource_server] authorizer = AccessTokenAuthorizer(groups_token["access_token"]) diff --git a/src/client.py b/src/client.py index 41ab349..15522ef 100644 --- a/src/client.py +++ b/src/client.py @@ -88,11 +88,12 @@ def globus_authorize( else: properties = item.properties - allowed_groups = self.allowed_groups(properties, settings.client.access_control_policy) + authorizer = request.state.authorizer + allowed_groups = self.allowed_groups( + properties, authorizer["access_control_policy"] + ) logger.info("ALLOWED GROUPS: %s", allowed_groups) allowed_groups_uuid = [g.get("uuid") for g in allowed_groups] - - authorizer = request.state.authorizer token_info = authorizer.get("token_info") user_groups = authorizer.get("groups") diff --git a/src/settings/globus.py b/src/settings/globus.py index 5fe4461..e605cd3 100644 --- a/src/settings/globus.py +++ b/src/settings/globus.py @@ -2,7 +2,6 @@ from typing import Any, Self import boto3 -import urllib3 from globus_sdk import ConfidentialAppAuthClient from pydantic import BaseModel, model_validator @@ -17,66 +16,18 @@ class GlobusClientSettings(BaseModel): issuer: str scope_string: str - access_control_policy: dict confidential_client: Any policy_path: str - secret_name: str = "transaction-api/integration" - region: str = "us-east-1" authorizer_cache_ttl_seconds: int = 300 - - def load_access_control_policy(policy_path: str) -> dict: - """load access control policy - - Args: - data (dict): inital data - - Returns: - dict: data with access control policy - """ - parsed = urllib3.util.parse_url(policy_path) - if parsed.scheme == "file": - with open(parsed.path) as file: - print("Access Control Policy loaded") - return json.load(file) - else: - http = urllib3.PoolManager() - response = http.request("GET", policy_path) - if response.status == 200: - print("Access Control Policy loaded") - return json.loads(response.data.decode("utf-8")) - - def load_secrets(data: dict) -> dict: - """load secrets from AWS - - Args: - data (dict): inital data - - Returns: - dict: data with secrets - """ - try: - session = boto3.session.Session() - client = session.client("secretsmanager", region_name=data["region"]) - response = client.get_secret_value(SecretId=data["secret_name"]) - secrets = json.loads(response["SecretString"]) - except Exception as e: - print(f"Error loading secrets: {e}") - secrets = {} - - for key, value in secrets.items(): - data[key] = value - - return data + policy_cache_ttl_seconds: int = 300 @model_validator(mode="before") @classmethod def pre_load(self, data: dict) -> Self: """ - Load the access control policy, secrets, and confidential_client. + Create confidential_client. """ - data["access_control_policy"] = self.load_access_control_policy(data["policy_path"]) - data["confidential_client"] = ConfidentialAppAuthClient( client_id=data["client_id"], client_secret=data["client_secret"], diff --git a/src/utils.py b/src/utils.py index eaa6dde..64c2730 100644 --- a/src/utils.py +++ b/src/utils.py @@ -4,6 +4,7 @@ import httpx import jsonschema +from jsonschema.exceptions import relevance from esgf_core_utils.models.exceptions import ( ExpectedExtensionsMissingException, OperationNotPermittedException, @@ -237,11 +238,26 @@ def validate_post( for extension in extensions: extension_validator = get_extension_validator(str(extension)) - raise_errors = [] - for error in extension_validator.iter_errors(json.loads(item.model_dump_json())): - raise_errors.append(error) + raise_errors = sorted( + extension_validator.iter_errors(json.loads(item.model_dump_json())), + key=relevance, + ) if raise_errors: + error_parts = [] + for error in raise_errors: + # anyOf/oneOf failures expose root causes in context (jsonschema docs). + if error.context: + error_parts.append(error.context[0].message) + else: + error_parts.append(error.message) + + validation_errors = "; ".join(error_parts) + detail = ( + "Your request is invalid -- please ensure your request is valid and try again. " + f"Item `{item_id}` failed validation against `{extension}`: {validation_errors}" + ) logger.error(f"STAC validation error: {item_id}") - - raise STACValidationException() + exc = STACValidationException() + exc.detail = detail + raise exc From 95f5864b6f9465710cc08d4db56fead378312414 Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Fri, 12 Jun 2026 11:28:55 -0500 Subject: [PATCH 11/14] Remove unused modules --- src/authorizer/globus_authorizer.py | 4 +--- src/client.py | 4 +--- src/settings/globus.py | 2 -- src/utils.py | 2 +- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/authorizer/globus_authorizer.py b/src/authorizer/globus_authorizer.py index ad79bde..f4fe50c 100644 --- a/src/authorizer/globus_authorizer.py +++ b/src/authorizer/globus_authorizer.py @@ -103,9 +103,7 @@ def _load_access_control_policy(policy_path: str) -> dict: logger.info("Access Control Policy loaded from %s", policy_path) return json.loads(response.data.decode("utf-8")) - raise RuntimeError( - f"Failed to load access control policy from {policy_path}: HTTP {response.status}" - ) + raise RuntimeError(f"Failed to load access control policy from {policy_path}: HTTP {response.status}") def get_access_control_policy() -> dict: diff --git a/src/client.py b/src/client.py index 15522ef..63ee88f 100644 --- a/src/client.py +++ b/src/client.py @@ -89,9 +89,7 @@ def globus_authorize( properties = item.properties authorizer = request.state.authorizer - allowed_groups = self.allowed_groups( - properties, authorizer["access_control_policy"] - ) + allowed_groups = self.allowed_groups(properties, authorizer["access_control_policy"]) logger.info("ALLOWED GROUPS: %s", allowed_groups) allowed_groups_uuid = [g.get("uuid") for g in allowed_groups] token_info = authorizer.get("token_info") diff --git a/src/settings/globus.py b/src/settings/globus.py index e605cd3..2eb61c8 100644 --- a/src/settings/globus.py +++ b/src/settings/globus.py @@ -1,7 +1,5 @@ -import json from typing import Any, Self -import boto3 from globus_sdk import ConfidentialAppAuthClient from pydantic import BaseModel, model_validator diff --git a/src/utils.py b/src/utils.py index 64c2730..e74e7b2 100644 --- a/src/utils.py +++ b/src/utils.py @@ -247,7 +247,7 @@ def validate_post( error_parts = [] for error in raise_errors: # anyOf/oneOf failures expose root causes in context (jsonschema docs). - if error.context: + if error.context: error_parts.append(error.context[0].message) else: error_parts.append(error.message) From 95122741b56e0b2bc189e09691387fe3440371e4 Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Mon, 15 Jun 2026 05:01:52 -0500 Subject: [PATCH 12/14] Use esgf-core-utils (projects and nodes) in Globus Authorization --- src/authorizer/globus_auth.py | 230 +++ src/authorizer/globus_authorizer.py | 56 +- src/client.py | 84 +- .../config/access_control_policy.json | 1641 ----------------- src/settings/config/access_control_policy.txt | 10 + src/settings/example.env | 2 +- src/settings/globus.py | 1 + 7 files changed, 301 insertions(+), 1723 deletions(-) create mode 100644 src/authorizer/globus_auth.py delete mode 100644 src/settings/config/access_control_policy.json create mode 100644 src/settings/config/access_control_policy.txt diff --git a/src/authorizer/globus_auth.py b/src/authorizer/globus_auth.py new file mode 100644 index 0000000..7924f2d --- /dev/null +++ b/src/authorizer/globus_auth.py @@ -0,0 +1,230 @@ +""" +Models relating to Authorisation for the ESGF Next Gen Core Architecture. +""" + +import logging +import re +from typing import Any, Literal +from urllib.parse import urlparse + +from pydantic import BaseModel +from pydantic_core import ValidationError +from stac_fastapi.extensions.core.transaction.request import PartialItem +from stac_pydantic.item import Item + +from esgf_core_utils.models.exceptions import ( + AuthorizationException, + MissingPermissionException, +) +from esgf_core_utils.models.kafka.events import RequesterData + +logger = logging.getLogger("uvicorn.error") + +Role = Literal[ + "CREATE", + "UPDATE", + "DELETE", + "REPLICATE", + "REVOKE", +] + + +class Node(BaseModel): + """ + Model describing Node auth info of a ESGF publisher. + """ + + id: str + roles: set[Role] + + +class Project(BaseModel): + """ + Model describing Project auth info of a ESGF publisher. + """ + + id: str + roles: set[Role] + + +class Nodes(BaseModel): + """ + Model describing Project auth info of a ESGF publisher. + """ + + nodes: dict[str, Node] = {} + + def add(self, node: Node | dict[str, Any]) -> None: + """ + Add a new project or update roles if project already exists. + + Args: + node (Node | dict): node to be added + """ + if isinstance(node, dict): + node = Node(**node) + + if existing_node := self.nodes.get(node.id): + existing_node.roles.update(node.roles) + + else: + self.nodes[node.id] = node + + def authorize_href(self, asset_href: str, role: Role) -> None: + asset_url = urlparse(asset_href) + node_permission = self.nodes.get(asset_url.hostname or "", None) + if not node_permission: + node_permission = self.nodes.get("*", None) + + if not node_permission: + raise MissingPermissionException( + permission_type="node", + target=asset_href, + ) + + if role not in node_permission.roles: + raise MissingPermissionException( + permission_type="node", + role=role, + target=asset_href, + ) + + def authorize(self, assets: dict[str, Any], role: Role) -> None: + """Check for appropriate authorisation. + + Args: + assets (dict): item to be authorised + role (Role): required role for auhroisation + + Raises: + MissingPermissionException: Raised if either node or role permission is missing + """ + + for asset in assets.values(): + asset = asset.model_dump() if not isinstance(asset, dict) else asset + + if "href" in asset: + self.authorize_href(f"https://{asset.get("alternate:name")}", role) + + if alternates := asset.get("alternate"): + self.authorize(alternates, role) + + +class Projects(BaseModel): + """ + Model describing Project auth info of a ESGF publisher. + """ + + projects: dict[str, Project] = {} + + def add(self, project: Project | dict[str, Any]) -> None: + """ + Add a new project or update roles if project already exists. + + Args: + project (Project | dict): project to be added + """ + if isinstance(project, dict): + project = Project(**project) + + if existing_project := self.projects.get(project.id): + existing_project.roles.update(project.roles) + + else: + self.projects[project.id] = project + + def authorize(self, project: str, role: Role) -> None: + """Check for appropriate authorisation. + + Args: + item (Item): item to be authorised + role (Role): required role for auhroisation + + Raises: + MissingPermissionException: Raised if either node or role permission is missing + """ + project_permission = self.projects.get(project, None) + if not project_permission: + project_permission = self.projects.get("*", None) + + if not project_permission: + raise MissingPermissionException( + permission_type="project", + target=project, + ) + + if role not in project_permission.roles: + raise MissingPermissionException( + permission_type="project", + role=role, + target=project, + ) + + +class GlobusAuth(BaseModel): + """ + Model describing Authentication information of a ESGF publisher. + """ + + requester_data: RequesterData + nodes: Nodes = Nodes() + projects: Projects = Projects() + regex: str + + def authorize( + self, + collection_id: str, + item: Item | PartialItem, + role: Role, + request_id: str, + event_id: str, + ) -> None: + """Check for appropriate authorisation. + + Args: + collection_id: collection id of request + item (Item): item to be authorised + role (Role): required role for auhroisation + + Raises: + AuthorizationException: Raised if either node or role permission is missing + """ + logger.info("Projects: %s", self.projects) + logger.info("Nodes: %s", self.nodes) + try: + self.projects.authorize(collection_id, role) + self.nodes.authorize(item.assets or {}, role) + + except MissingPermissionException as exc: + raise AuthorizationException(instance=f"{request_id}:{event_id}") from exc + + def add(self, entitlements: list[str]) -> None: + """add entitlements to Authorizer. + + Args: + entitlements (list[str]): list of entitlements to be added + """ + for entitlement in entitlements: + match = re.search(self.regex, entitlement) + if match is None: + continue + + try: + if match.group("type") == "project": + self.projects.add( + Project( + id=match.group("id"), + roles=[match.group("role")], + ) + ) + + elif match.group("type") == "node": + self.nodes.add( + Node( + id=match.group("id"), + roles=[match.group("role")], + ) + ) + + except ValidationError: + logger.info("Entitlement skipped: %s", entitlement) diff --git a/src/authorizer/globus_authorizer.py b/src/authorizer/globus_authorizer.py index f4fe50c..0548536 100644 --- a/src/authorizer/globus_authorizer.py +++ b/src/authorizer/globus_authorizer.py @@ -1,17 +1,18 @@ import hashlib -import json import logging import time from dataclasses import dataclass from threading import Lock import urllib3 +from esgf_core_utils.models.kafka.events import RequesterData from fastapi import Request from fastapi.responses import JSONResponse from globus_sdk import AccessTokenAuthorizer, GroupsClient from globus_sdk.scopes import GroupsScopes from starlette.middleware.base import BaseHTTPMiddleware +from authorizer.globus_auth import GlobusAuth from settings import settings logger = logging.getLogger("uvicorn.error") @@ -19,10 +20,7 @@ """ FastAPI Middleware Authorizer Authorizer type: FastAPI Middleware - Event payload: Token Token source: Authorization - Token validation: ^Bearer\\s[^\\s]+$ # noqa: W605 - ^Bearer\\s[0-9A-Za-z]+$ for access tokens issued by Globus Auth (?) # noqa: W605 Authorization caching: 300 seconds (TRANSACTION_CLIENT__AUTHORIZER_CACHE_TTL_SECONDS) """ @@ -82,31 +80,32 @@ def _evict_expired(self) -> None: @dataclass class _CachedPolicy: expires_at: float - policy: dict + policy: list[str] _policy_cache: _CachedPolicy | None = None _policy_lock = Lock() -def _load_access_control_policy(policy_path: str) -> dict: +def _load_access_control_policy(policy_path: str) -> list[str]: logger.info("Loading access control policy from %s", policy_path) parsed = urllib3.util.parse_url(policy_path) if parsed.scheme == "file": - with open(parsed.path) as file: - logger.info("Access Control Policy loaded from %s", policy_path) - return json.load(file) + with open(parsed.path, encoding="utf-8") as file: + text = file.read() + else: + http = urllib3.PoolManager() + response = http.request("GET", policy_path) + if response.status != 200: + raise RuntimeError(f"Failed to load access control policy from {policy_path}: HTTP {response.status}") + text = response.data.decode("utf-8") - http = urllib3.PoolManager() - response = http.request("GET", policy_path) - if response.status == 200: - logger.info("Access Control Policy loaded from %s", policy_path) - return json.loads(response.data.decode("utf-8")) + lines = [line.strip() for line in text.splitlines() if line.strip()] + logger.info("Access control policy loaded (%s lines)", len(lines)) + return lines - raise RuntimeError(f"Failed to load access control policy from {policy_path}: HTTP {response.status}") - -def get_access_control_policy() -> dict: +def get_access_control_policy() -> list[str]: """Return access control policy, reloading from policy_path when cache expires.""" global _policy_cache @@ -132,9 +131,25 @@ def get_access_control_policy() -> dict: return policy -def _authorizer_context(auth: dict) -> dict: - """Attach access control policy to token auth (policy has its own TTL cache).""" - return {**auth, "access_control_policy": get_access_control_policy()} +def _authorizer_context(auth: dict) -> GlobusAuth: + """Build GlobusAuth from token auth and cached access control policy entitlements.""" + token_info = auth["token_info"] + user_group_ids = {group["group_id"] for group in auth["groups"]} + + entitlements = [entitlement for entitlement in get_access_control_policy() if entitlement.rsplit(":group:", 1)[-1] in user_group_ids] + + authorizer = GlobusAuth( + requester_data=RequesterData( + client_id=token_info.get("client_id"), + sub=token_info.get("sub"), + iss=token_info.get("iss"), + ), + regex=settings.client.regex, + ) + + authorizer.add(entitlements) + + return authorizer def _cache_ttl_seconds(token_info: dict, max_ttl: int) -> int: @@ -173,6 +188,7 @@ async def dispatch(self, request: Request, call_next): response = settings.client.confidential_client.oauth2_token_introspect(access_token, include="identity_set_detail") token_info = response.data + logger.info("Token info: %s", token_info) auth_error = self._validate_token_info(token_info) if auth_error is not None: diff --git a/src/client.py b/src/client.py index 63ee88f..5b07fc3 100644 --- a/src/client.py +++ b/src/client.py @@ -2,9 +2,9 @@ import uuid from datetime import datetime from typing import Optional, Union -from types import SimpleNamespace +from authorizer.globus_auth import GlobusAuth from esgf_core_utils.models.auth.egi import EGIAuth from esgf_core_utils.models.exceptions import ( AuthorizationException, @@ -24,7 +24,6 @@ Metadata, PatchPayload, Publisher, - RequesterData, UpdatePayload, ) from esgf_core_utils.models.kafka.producer import KafkaProducer @@ -52,21 +51,6 @@ class TransactionClient(BaseTransactionsClient): def __init__(self): self.producer = KafkaProducer() - def allowed_groups(self, properties, acp) -> list: - if isinstance(acp, list): - return acp - for facet, subpolicy in acp.items(): - if hasattr(properties, facet): - property_value = getattr(properties, facet) - if isinstance(property_value, str): - property_value = [property_value] - matches = list(set(property_value) & set(subpolicy.keys())) - for match in matches: - groups = self.allowed_groups(properties, subpolicy[match]) - if groups: - return groups - return [] - def globus_authorize( self, collection_id: str, @@ -75,51 +59,32 @@ def globus_authorize( request: Request, request_id: str, event_id: str, - item_id: str = None, - ) -> dict: - extension_id = collection_id.lower() - if role == "CREATE": - properties = item.properties - elif role == "UPDATE" and item_id: - properties = SimpleNamespace() - facets = item_id.split(".") - setattr(properties, "project", collection_id) - setattr(properties, f"{extension_id}:institution_id", facets[2]) - else: - properties = item.properties - - authorizer = request.state.authorizer - allowed_groups = self.allowed_groups(properties, authorizer["access_control_policy"]) - logger.info("ALLOWED GROUPS: %s", allowed_groups) - allowed_groups_uuid = [g.get("uuid") for g in allowed_groups] - token_info = authorizer.get("token_info") - user_groups = authorizer.get("groups") - - authorized_identities = [] - for group in user_groups: - if group.get("group_id") in allowed_groups_uuid: - authorized_identities.append( - { - "group_id": group.get("group_id"), - "identity_id": group.get("identity_id"), - } - ) - if not authorized_identities: - raise MissingPermissionException(permission_type="globus", target=collection_id) - - requester_data = RequesterData( - client_id=token_info.get("client_id"), - sub=token_info.get("sub"), - iss=token_info.get("iss"), - ) + ) -> Auth: + """Auhorise request with Globus Auth - logger.info("REQUESTER DATA: %s", requester_data) + Args: + item (Item): item to check authorization for + role (str): role to check authorization for + request (Request): current request - auth = Auth( - requester_data=requester_data, + Returns: + Auth: Auth object if successful + """ + authorizer: GlobusAuth = request.state.authorizer + logger.info("Authorizer: %s", authorizer) + authorizer.authorize( + collection_id=collection_id, + item=item, + role=role, + request_id=request_id, + event_id=event_id, ) - return auth + logger.info("REQUESTER DATA: %s", authorizer.requester_data) + + return Auth( + requester_data=authorizer.requester_data.model_dump(), + ) def egi_authorize( self, @@ -163,7 +128,6 @@ def authorize( request: Request, request_id: str, event_id: str, - item_id: str = None, ) -> Auth: if settings.authorizer == "globus": @@ -174,7 +138,6 @@ def authorize( request=request, request_id=request_id, event_id=event_id, - item_id=item_id, ) else: return self.egi_authorize( @@ -366,7 +329,6 @@ async def patch_item( request=request, request_id=request_id, event_id=event_id, - item_id=item_id, ) item_extensions = item.stac_extensions if item.stac_extensions else [] diff --git a/src/settings/config/access_control_policy.json b/src/settings/config/access_control_policy.json deleted file mode 100644 index 50ea6f7..0000000 --- a/src/settings/config/access_control_policy.json +++ /dev/null @@ -1,1641 +0,0 @@ -{ - "project": { - "CMIP6": { - "cmip6:institution_id": { - "AER": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "AS-RCEC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "AWI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "BCC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CAMS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CAS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CCCma": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CCCR-IITM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CMCC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CNRM-CERFACS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO-ARCCSS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO-COSIMA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "DKRZ": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "DWD": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "E3SM-Project": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "EC-Earth-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "FIO-QLNM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "HAMMOZ-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "INM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IPSL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "KIOST": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "LLNL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MIROC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MOHC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MPI-M": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MRI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NASA-GISS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NCAR": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NCC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NERC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NIMS-KMA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NIWA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NOAA-GFDL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NTU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NUIST": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RTE-RRTMGP-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RUBISCO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "SNU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "THU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UCI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UCSB": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UHH": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ] - } - }, - "obs4MIPs": { - "obs4mips:institution_id": { - "CNES": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "ECMWF": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "ESSO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MOHC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NASA-GSFC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NASA-JPL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NASA-LaRC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NOAA-ESRL-PSD": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NOAA-NCEI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RSS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ] - } - }, - "CMIP6Plus": { - "cmip6plus:institution_id": { - "AER": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CNES": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CNRM-CERFACS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO-ARCCSS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO-COSIMA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "DKRZ": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "DLR-BIRA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "DWD": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "E3SM-Project": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "EAWAG": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "EC-Earth-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "ECMWF": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "ESPRI-IPSL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "ESSO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "FIO-QLNM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "FMI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "FUBerlin": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "HAMMOZ-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IACETH": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IAMC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IFM-GEOMAR": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IMPERIALCOLLEGE": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "INCOIS-NIO-IPSL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "INM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IPSL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "ISSI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "JAXA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "KIOST": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "KIT": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "LLNL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "LPC2E": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MESSy-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MIROC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MOHC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MPI-B": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MPI-M": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MPS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MRI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NASA-GISS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NASA-GSFC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NASA-JPL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NASA-LaRC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NCAR": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NCAS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NCC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NERC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NIMS-KMA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NIWA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NOAA-GFDL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NOAA-NCEI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NTU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NUIST": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "OSU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "PCMDI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "PMOD": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "PNNL-JGCRI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "PNNL-WACCEM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RSS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RTE-RRTMGP-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RUBISCO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "SNU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "SOLARIS-HEPPA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "THU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UCI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UCSB": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UCSD-SIO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UColorado": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UHH": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UReading": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UW": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UoBergen": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UoLeeds": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UoM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UoMontreal": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UoOtago": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UoOulu": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UofMD": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "VUA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ] - } - }, - "CMIP7": { - "cmip7:institution_id": { - "ALCF": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "AS-RCEC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "EC-Earth-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "LLNL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UCI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "AER": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "AWI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "BCC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CAMS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CAS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CCCma": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CCCR-IITM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CMCC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CNRM-CERFACS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO-ARCCSS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO-COSIMA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "DKRZ": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "DWD": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "E3SM-Project": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "FIO-QLNM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "HAMMOZ-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "INM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IPSL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "KIOST": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MIROC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MOHC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MPI-M": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MRI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NASA-GISS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NCAR": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NCC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NERC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NIMS-KMA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NIWA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NOAA-GFDL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NTU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NUIST": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RTE-RRTMGP-Consortium": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RUBISCO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "SNU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "THU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UCSB": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UHH": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ] - } - }, - "CORDEX-CMIP6": { - "cordex-cmip6:institution_id": { - "AUTH": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "BAS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "BCCR-UCAN": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "BOM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CCCma": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CESAM-UA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-AWI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-BTU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-CMCC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-DWD": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-ETH": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-FZJ": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-GERICS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-GUF": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-Hereon": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-IMWM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-KUL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-LIST": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CLMcom-WEGC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CNR-ISAC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CNRM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CNRM-MF": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CORNELL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CSIRO": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "CYI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "DWD-BSH": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "ENEA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "GERICS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "HCLIMcom-DMI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "HCLIMcom-METNo": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "HCLIMcom-SMHI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "ICTP": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IDL-FCUL": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IFCA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IMWM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IRD-MF": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "IUM-FDU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "KNMI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "MOHC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NCAR": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NIMS-KMA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NKUA": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "NORCE-BCCR": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "OURANOS": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RMIB-UGent": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "RU-CORE": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "SENAMHI-PER": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "TASK-IMWM": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UBA-CIMA-IFAECI": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UNSW-CCRC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UQ-DEC": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ], - "UU-IMAU": [ - { - "name": "ESGFNG Integration", - "uuid": "e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3", - "url": "https://app.globus.org/groups/e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3" - } - ] - } - } - } -} diff --git a/src/settings/config/access_control_policy.txt b/src/settings/config/access_control_policy.txt new file mode 100644 index 0000000..3731200 --- /dev/null +++ b/src/settings/config/access_control_policy.txt @@ -0,0 +1,10 @@ +project:*:role=CREATE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 +project:*:role=UPDATE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 +project:*:role=REPLICATE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 +project:*:role=DELETE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 +project:*:role=REVOKE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 +node:*:role=CREATE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 +node:*:role=UPDATE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 +node:*:role=REPLICATE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 +node:*:role=DELETE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 +node:*:role=REVOKE:group:e3329078-b8f6-11f0-9fdd-0e7d9e9fc9e3 diff --git a/src/settings/example.env b/src/settings/example.env index 958b66e..e5a9972 100644 --- a/src/settings/example.env +++ b/src/settings/example.env @@ -11,4 +11,4 @@ TRANSACTION_CLIENT__GLOBUS_CLIENT_SECRET=GLOBUS_CLIENT_SECRET TRANSACTION_CLIENT__GLOBUS_ISSUER=issuer TRANSACTION_CLIENT__GLOBUS_SCOPE_STRING=scope_string TRANSACTION_CLIENT__GLOBUS_AUTHORIZER=athorizer -TRANSACTION_CLIENT__GLOBUS_POLICY_PATH=/policy/path +TRANSACTION_CLIENT__GLOBUS_POLICY_PATH=file:///var/task/settings/config/new_acp.txt diff --git a/src/settings/globus.py b/src/settings/globus.py index 2eb61c8..8b5866f 100644 --- a/src/settings/globus.py +++ b/src/settings/globus.py @@ -19,6 +19,7 @@ class GlobusClientSettings(BaseModel): policy_path: str authorizer_cache_ttl_seconds: int = 300 policy_cache_ttl_seconds: int = 300 + regex: str = r"(?P[^:]*)\:(?P[^:]*)(\:institution\:(?P[^:]*))?" r"\:role=(?P[^:]*)\:group\:(?P[^:]*)" @model_validator(mode="before") @classmethod From 2964cbfafa54c2445864a3b05aae78debfe98790 Mon Sep 17 00:00:00 2001 From: Lukasz Lacinski Date: Mon, 15 Jun 2026 05:43:21 -0500 Subject: [PATCH 13/14] Remove excessive logging --- src/authorizer/globus_auth.py | 2 -- src/authorizer/globus_authorizer.py | 2 -- src/client.py | 1 - 3 files changed, 5 deletions(-) diff --git a/src/authorizer/globus_auth.py b/src/authorizer/globus_auth.py index 7924f2d..7fa2ab3 100644 --- a/src/authorizer/globus_auth.py +++ b/src/authorizer/globus_auth.py @@ -189,8 +189,6 @@ def authorize( Raises: AuthorizationException: Raised if either node or role permission is missing """ - logger.info("Projects: %s", self.projects) - logger.info("Nodes: %s", self.nodes) try: self.projects.authorize(collection_id, role) self.nodes.authorize(item.assets or {}, role) diff --git a/src/authorizer/globus_authorizer.py b/src/authorizer/globus_authorizer.py index 0548536..970df18 100644 --- a/src/authorizer/globus_authorizer.py +++ b/src/authorizer/globus_authorizer.py @@ -101,7 +101,6 @@ def _load_access_control_policy(policy_path: str) -> list[str]: text = response.data.decode("utf-8") lines = [line.strip() for line in text.splitlines() if line.strip()] - logger.info("Access control policy loaded (%s lines)", len(lines)) return lines @@ -188,7 +187,6 @@ async def dispatch(self, request: Request, call_next): response = settings.client.confidential_client.oauth2_token_introspect(access_token, include="identity_set_detail") token_info = response.data - logger.info("Token info: %s", token_info) auth_error = self._validate_token_info(token_info) if auth_error is not None: diff --git a/src/client.py b/src/client.py index 5b07fc3..bd255b7 100644 --- a/src/client.py +++ b/src/client.py @@ -71,7 +71,6 @@ def globus_authorize( Auth: Auth object if successful """ authorizer: GlobusAuth = request.state.authorizer - logger.info("Authorizer: %s", authorizer) authorizer.authorize( collection_id=collection_id, item=item, From e9be3bcf49ef53cb3564359b1d563a25535e75e8 Mon Sep 17 00:00:00 2001 From: Steve Turoscy Date: Tue, 7 Jul 2026 10:35:17 -0400 Subject: [PATCH 14/14] Hopefully fixing imports --- src/client.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/client.py b/src/client.py index afb3a3d..5bc35b8 100644 --- a/src/client.py +++ b/src/client.py @@ -5,7 +5,6 @@ from authorizer.globus_auth import GlobusAuth -from esgf_core_utils.models.auth.egi import EGIAuth from esgf_core_utils.models.exceptions import ( AuthorizationException, ExpectedExtensionsMissingException, @@ -25,10 +24,10 @@ Metadata, PatchPayload, Publisher, - UpdatePayload, ) from esgf_core_utils.models.kafka.producer import KafkaProducer from fastapi import Request, Response, status +from src.authorizer import Authorizer from stac_fastapi.extensions.transaction import BaseTransactionsClient from stac_fastapi.extensions.transaction.request import PartialItem, PatchOperation from stac_fastapi.types.stac import Collection