1+ import fnmatch
12import json
23import logging
34import re
@@ -77,10 +78,49 @@ def load_met_json(bucket: str, job_output_prefix: str) -> Optional[Dict[str, str
7778 )
7879
7980
80- def get_stac_items (catalog_json_key : str ) -> Generator [Item , Any , Any ]:
81+ def is_authorized (
82+ username : str ,
83+ collection_id : str ,
84+ registry : dict [str , list [str ]],
85+ ) -> bool :
86+ """Return True if username is authorized to publish to collection_id.
87+
88+ Each key in registry is a collection ID pattern (exact string or glob
89+ wildcard using fnmatch syntax). A user is authorized when their username
90+ appears in the list for any pattern that matches collection_id.
91+
92+ Args:
93+ username: The DPS job submitter's username.
94+ collection_id: The collection ID the item declares.
95+ registry: Mapping of collection ID patterns to authorized usernames.
96+
97+ Returns:
98+ True if the username is authorized for the given collection ID.
8199 """
82- Yield STAC items out of a catalog.json
100+ for pattern , authorized_users in registry .items ():
101+ if fnmatch .fnmatch (collection_id , pattern ) and username in authorized_users :
102+ return True
103+ return False
104+
105+
106+ def get_stac_items (
107+ catalog_json_key : str ,
108+ collection_id_registry : dict [str , list [str ]] | None = None ,
109+ ) -> Generator [Item , Any , Any ]:
110+ """Yield STAC items out of a catalog.json.
111+
112+ If collection_id_registry is provided, items whose existing collection ID
113+ is authorized for the submitting user are published as-is. All other items
114+ receive a deterministic collection ID derived from DPS job metadata.
115+
116+ Args:
117+ catalog_json_key: S3 URI of the catalog.json file.
118+ collection_id_registry: Optional mapping of collection ID patterns to
119+ lists of authorized usernames. When omitted, all items receive the
120+ deterministic collection ID.
83121 """
122+ registry = collection_id_registry or {}
123+
84124 job_output_prefix = get_dps_output_prefix (catalog_json_key )
85125 if not job_output_prefix :
86126 raise ValueError (
@@ -95,15 +135,25 @@ def get_stac_items(catalog_json_key: str) -> Generator[Item, Any, Any]:
95135 f"could not locate the .met.json file with the DPS job outputs in { job_output_prefix } "
96136 )
97137
98- collection_id = slugify (
138+ deterministic_collection_id = slugify (
99139 COLLECTION_ID_FORMAT .format (** job_metadata ), regex_pattern = r"[/\?#%& ]+"
100140 )
141+ username = job_metadata .get ("username" , "" )
101142
102143 catalog = pystac .Catalog .from_file (catalog_json_key )
103144 catalog .make_all_asset_hrefs_absolute ()
104145
105146 for item in catalog .get_all_items ():
106147 item_dict = item .to_dict ()
107- item_dict ["collection" ] = collection_id
148+ item_collection_id = item_dict .get ("collection" )
149+
150+ if item_collection_id and is_authorized (username , item_collection_id , registry ):
151+ logger .info (
152+ "Preserving user-specified collection %s for user %s" ,
153+ item_collection_id ,
154+ username ,
155+ )
156+ else :
157+ item_dict ["collection" ] = deterministic_collection_id
108158
109159 yield Item (** item_dict )
0 commit comments