Skip to content

Commit 7d4177b

Browse files
committed
buildout working example
1 parent c4bc3f2 commit 7d4177b

File tree

2 files changed

+58
-11
lines changed

2 files changed

+58
-11
lines changed

src/stac_auth_proxy/app.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from .middleware import (
1717
AddProcessTimeHeaderMiddleware,
1818
ApplyCql2FilterMiddleware,
19+
AuthenticationExtensionMiddleware,
1920
BuildCql2FilterMiddleware,
2021
EnforceAuthMiddleware,
2122
OpenApiMiddleware,
@@ -61,6 +62,11 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
6162
S3AssetSigner(bucket_pattern=settings.signer_asset_expression).endpoint,
6263
methods=["POST"],
6364
)
65+
app.add_middleware(
66+
AuthenticationExtensionMiddleware,
67+
endpoint=settings.signer_endpoint,
68+
asset_expression=settings.signer_asset_expression,
69+
)
6470

6571
app.add_api_route(
6672
"/{path:path}",
@@ -81,11 +87,6 @@ def create_app(settings: Optional[Settings] = None) -> FastAPI:
8187
default_public=settings.default_public,
8288
)
8389

84-
# signers={
85-
# schema: endpoint
86-
# for schema, endpoint in {"s3": settings.signer_endpoint}.items()
87-
# if endpoint
88-
# },
8990
if settings.items_filter:
9091
app.add_middleware(
9192
ApplyCql2FilterMiddleware,
Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
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
45
from typing import Any
56

67
from starlette.requests import Request
78
from starlette.types import ASGIApp
89

10+
from ..utils.filters import is_item_endpoint
911
from ..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

Comments
 (0)