1- """Middleware to add auth information to the OpenAPI spec served by upstream API."""
1+ """Middleware to add auth information to item response served by upstream API."""
22
3- from dataclasses import dataclass , field
3+ import re
4+ from dataclasses import dataclass
45from typing import Any
56
67from starlette .requests import Request
78from starlette .types import ASGIApp
89
10+ from ..utils .filters import is_item_endpoint
911from ..utils .middleware import JsonResponseMiddleware
1012
1113
@@ -14,14 +16,58 @@ class AuthenticationExtensionMiddleware(JsonResponseMiddleware):
1416 """Middleware to add the authentication extension to the response."""
1517
1618 app : ASGIApp
17- signers : dict [str , str ] = field (default_factory = dict )
19+ endpoint : str
20+ asset_expression : str
1821
1922 def should_transform_response (self , request : Request ) -> bool :
2023 """Only transform responses for STAC Items."""
21- # TODO: Implement proper path matching for STAC Items
22- return True
24+ return is_item_endpoint (request .url .path )
2325
2426 def transform_json (self , item : dict [str , Any ]) -> dict [str , Any ]:
2527 """Augment the STAC Item with auth information."""
26- # TODO: Implement STAC Item augmentation
28+ extension = (
29+ "https://stac-extensions.github.io/authentication/v1.1.0/schema.json"
30+ )
31+ extensions = item .setdefault ("stac_extensions" , [])
32+ if extension not in extensions :
33+ extensions .append (extension )
34+
35+ # TODO: Should we add this to items even if the assets don't match the asset expression?
36+ schemes = item ["properties" ].setdefault ("auth:schemes" , {})
37+ scheme = "signed_url_auth"
38+ schemes [scheme ] = {
39+ "type" : "signedUrl" ,
40+ "description" : "Requires an authentication API" ,
41+ "flows" : {
42+ "authorizationCode" : {
43+ "authorizationApi" : self .endpoint ,
44+ "method" : "POST" ,
45+ "parameters" : {
46+ "bucket" : {
47+ "in" : "body" ,
48+ "required" : True ,
49+ "description" : "asset bucket" ,
50+ "schema" : {
51+ "type" : "string" ,
52+ "examples" : "example-bucket" ,
53+ },
54+ },
55+ "key" : {
56+ "in" : "body" ,
57+ "required" : True ,
58+ "description" : "asset key" ,
59+ "schema" : {
60+ "type" : "string" ,
61+ "examples" : "path/to/example/asset.xyz" ,
62+ },
63+ },
64+ },
65+ "responseField" : "signed_url" ,
66+ }
67+ },
68+ }
69+
70+ for asset in item ["assets" ].values ():
71+ if re .match (self .asset_expression , asset .get ("href" , "" )):
72+ asset .setdefault ("auth:refs" , []).append (scheme )
2773 return item
0 commit comments