Skip to content

Commit fb5930e

Browse files
committed
refactor: scopes change from tuple to str
1 parent 6dfa54d commit fb5930e

File tree

4 files changed

+42
-16
lines changed

4 files changed

+42
-16
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ The application is configurable via environment variables.
8080
- **Required:** No, defaults to `false`
8181
- **Example:** `false`, `1`, `True`
8282
- **`PRIVATE_ENDPOINTS`**, endpoints explicitly marked as requiring authentication, used when `DEFAULT_PUBLIC == True`
83-
- **Type:** JSON object mapping regex patterns to HTTP methods OR tuples of HTTP methods and an array of strings representing required scopes
83+
- **Type:** JSON object mapping regex patterns to HTTP methods OR tuples of an HTTP method and string representing required scopes
8484
- **Required:** No, defaults to the following:
8585
```json
8686
{

src/stac_auth_proxy/config.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99

1010
METHODS = Literal["GET", "POST", "PUT", "DELETE", "PATCH"]
1111
EndpointMethodsNoScope: TypeAlias = dict[str, Sequence[METHODS]]
12-
EndpointMethods: TypeAlias = dict[
13-
str, Sequence[Union[METHODS, tuple[METHODS, Sequence[str]]]]
14-
]
12+
EndpointMethods: TypeAlias = dict[str, Sequence[Union[METHODS, tuple[METHODS, str]]]]
1513

1614
_PREFIX_PATTERN = r"^/.*$"
1715

src/stac_auth_proxy/utils/requests.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ def _check_endpoint_match(
3737
for endpoint_method in endpoint_methods:
3838
required_scopes: Sequence[str] = []
3939
if isinstance(endpoint_method, tuple):
40-
endpoint_method, required_scopes = endpoint_method
40+
endpoint_method, _required_scopes = endpoint_method
41+
if _required_scopes: # Ignore empty scopes, e.g. `["POST", ""]`
42+
required_scopes = _required_scopes.split(" ")
4143
if method.casefold() == endpoint_method.casefold():
4244
return True, required_scopes
4345
return False, []

tests/test_authn.py

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,48 @@ def test_default_public_false(source_api_server, path, method, token_builder):
5151

5252

5353
@pytest.mark.parametrize(
54-
"token,permitted",
54+
"rules,token,permitted",
5555
[
56-
[{"scope": "collection:create"}, True],
57-
[{"scope": ""}, False],
58-
[{"scope": "openid"}, False],
59-
[{"scope": "openid collection:create"}, True],
56+
[
57+
[("POST", "collection:create")],
58+
{"scope": "collection:create"},
59+
True,
60+
],
61+
[
62+
[("POST", "collection:create")],
63+
{"scope": ""},
64+
False,
65+
],
66+
[
67+
[("POST", "collection:create")],
68+
{"scope": "openid"},
69+
False,
70+
],
71+
[
72+
[("POST", "collection:create")],
73+
{"scope": "openid collection:create"},
74+
True,
75+
],
76+
[
77+
[("POST", "foo collection:create")],
78+
{"scope": "openid collection:create foo"},
79+
True,
80+
],
81+
[
82+
[("GET", "collection:read"), ("POST", "collection:create")],
83+
{"scope": "openid collection:read"},
84+
False,
85+
],
6086
],
6187
)
6288
def test_default_public_false_with_scopes(
63-
source_api_server, token, permitted, token_builder
89+
source_api_server, rules, token, permitted, token_builder
6490
):
6591
"""Private endpoints permit access with a valid token."""
6692
test_app = app_factory(
6793
upstream_url=source_api_server,
6894
default_public=False,
69-
private_endpoints={r"^/collections$": [("POST", ["collection:create"])]},
95+
private_endpoints={r"^/collections$": rules},
7096
)
7197
valid_auth_token = token_builder(token)
7298

@@ -84,31 +110,31 @@ def test_default_public_false_with_scopes(
84110
[
85111
pytest.param(
86112
"",
87-
{r"^/*": [("POST", ["collection:create"])]},
113+
{r"^/*": [("POST", "collection:create")]},
88114
"/collections",
89115
"POST",
90116
False,
91117
id="empty scopes + private endpoint",
92118
),
93119
pytest.param(
94120
"openid profile collection:createbutnotcreate",
95-
{r"^/*": [("POST", ["collection:create"])]},
121+
{r"^/*": [("POST", "collection:create")]},
96122
"/collections",
97123
"POST",
98124
False,
99125
id="invalid scopes + private endpoint",
100126
),
101127
pytest.param(
102128
"openid profile collection:create somethingelse",
103-
{r"^/*": [("POST", [])]},
129+
{r"^/*": [("POST", "")]},
104130
"/collections",
105131
"POST",
106132
True,
107133
id="valid scopes + private endpoint without required scopes",
108134
),
109135
pytest.param(
110136
"openid",
111-
{r"^/collections/.*/items$": [("POST", ["collection:create"])]},
137+
{r"^/collections/.*/items$": [("POST", "collection:create")]},
112138
"/collections",
113139
"GET",
114140
True,

0 commit comments

Comments
 (0)