@@ -25,11 +25,15 @@ class AuthenticationExtensionMiddleware(JsonResponseMiddleware):
2525
2626 app : ASGIApp
2727
28+ signing_endpoint : Optional [str ]
29+ signed_asset_expression : str
30+
2831 default_public : bool
2932 private_endpoints : EndpointMethods
3033 public_endpoints : EndpointMethods
3134
3235 oidc_config_url : Optional [HttpUrl ] = None
36+ signing_scheme_name : str = "signed_url_auth"
3337 auth_scheme_name : str = "oauth"
3438 auth_scheme : dict [str , Any ] = field (default_factory = dict )
3539 extension_url : str = (
@@ -84,9 +88,60 @@ def transform_json(self, doc: dict[str, Any]) -> dict[str, Any]:
8488 scheme_loc = doc ["properties" ] if "properties" in doc else doc
8589 schemes = scheme_loc .setdefault ("auth:schemes" , {})
8690 schemes [self .auth_scheme_name ] = self .auth_scheme
91+ if self .signing_endpoint :
92+ schemes [self .signing_scheme_name ] = {
93+ "type" : "signedUrl" ,
94+ "description" : "Requires an authentication API" ,
95+ "flows" : {
96+ "authorizationCode" : {
97+ "authorizationApi" : self .signing_endpoint ,
98+ "method" : "POST" ,
99+ "parameters" : {
100+ "bucket" : {
101+ "in" : "body" ,
102+ "required" : True ,
103+ "description" : "asset bucket" ,
104+ "schema" : {
105+ "type" : "string" ,
106+ "examples" : "example-bucket" ,
107+ },
108+ },
109+ "key" : {
110+ "in" : "body" ,
111+ "required" : True ,
112+ "description" : "asset key" ,
113+ "schema" : {
114+ "type" : "string" ,
115+ "examples" : "path/to/example/asset.xyz" ,
116+ },
117+ },
118+ },
119+ "responseField" : "signed_url" ,
120+ }
121+ },
122+ }
87123
88124 # auth:refs
89125 # ---
126+ # Annotate assets with "auth:refs": [signing_scheme]
127+ if self .signing_endpoint :
128+ assets = chain (
129+ # Item
130+ doc .get ("assets" , {}).values (),
131+ # Items/Search
132+ (
133+ asset
134+ for item in doc .get ("features" , [])
135+ for asset in item .get ("assets" , {}).values ()
136+ ),
137+ )
138+ for asset in assets :
139+ if "href" not in asset :
140+ logger .warning ("Asset %s has no href" , asset )
141+ continue
142+ if re .match (self .signed_asset_expression , asset ["href" ]):
143+ asset .setdefault ("auth:refs" , []).append (self .signing_scheme_name )
144+
90145 # Annotate links with "auth:refs": [auth_scheme]
91146 links = chain (
92147 # Item/Collection
0 commit comments