-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor the auth mechanism selection algorithm
This fixes some regressions for wrongly identified auth mechanisms when parsing the security_schemes from the openapi document. Also the whole selection decision tree is mapped onto a better function call dependency chain. (cherry picked from commit 6c6a5c2)
- Loading branch information
1 parent
5817710
commit 8c4a439
Showing
4 changed files
with
160 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Fixed regressions in the auth selection algorithm of `AuthProviderBase`. | ||
In particular, proposals requiring multiple mechanisms are ignored for now instead of considering each constituent individually, | ||
"HTTP Bearer" and other IANA schemes are no longer interpreted as "HTTP Basic" and the empty proposal rightfully reflects no needed authentication. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import pytest | ||
|
||
from pulp_glue.common.openapi import AuthProviderBase, OpenAPIError | ||
|
||
pytestmark = pytest.mark.glue | ||
|
||
|
||
SECURITY_SCHEMES = { | ||
"A": {"type": "http", "scheme": "bearer"}, | ||
"B": {"type": "http", "scheme": "basic"}, | ||
"C": { | ||
"type": "oauth2", | ||
"flows": { | ||
"implicit": { | ||
"authorizationUrl": "https://example.com/api/oauth/dialog", | ||
"scopes": { | ||
"write:pets": "modify pets in your account", | ||
"read:pets": "read your pets", | ||
}, | ||
}, | ||
"authorizationCode": { | ||
"authorizationUrl": "https://example.com/api/oauth/dialog", | ||
"tokenUrl": "https://example.com/api/oauth/token", | ||
"scopes": { | ||
"write:pets": "modify pets in your account", | ||
"read:pets": "read your pets", | ||
}, | ||
}, | ||
}, | ||
}, | ||
"D": { | ||
"type": "oauth2", | ||
"flows": { | ||
"implicit": { | ||
"authorizationUrl": "https://example.com/api/oauth/dialog", | ||
"scopes": { | ||
"write:pets": "modify pets in your account", | ||
"read:pets": "read your pets", | ||
}, | ||
}, | ||
"clientCredentials": { | ||
"tokenUrl": "https://example.com/api/oauth/token", | ||
"scopes": { | ||
"write:pets": "modify pets in your account", | ||
"read:pets": "read your pets", | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
|
||
def test_auth_provider_select_mechanism(monkeypatch: pytest.MonkeyPatch) -> None: | ||
monkeypatch.setattr(AuthProviderBase, "basic_auth", lambda *args: "BASIC") | ||
monkeypatch.setattr( | ||
AuthProviderBase, | ||
"oauth2_client_credentials_auth", | ||
lambda *args: "OAUTH2_CLIENT_CREDENTIALS", | ||
) | ||
|
||
# Error if no auth scheme is available. | ||
with pytest.raises(OpenAPIError): | ||
AuthProviderBase()([], SECURITY_SCHEMES) | ||
|
||
# Error if a nonexisting mechanism is proposed. | ||
with pytest.raises(KeyError): | ||
AuthProviderBase()([{"foo": []}], SECURITY_SCHEMES) | ||
|
||
# Succeed without mechanism for an empty proposal. | ||
assert AuthProviderBase()([{}], SECURITY_SCHEMES) is None | ||
|
||
# Try select a not implemented auth. | ||
with pytest.raises(OpenAPIError): | ||
AuthProviderBase()([{"A": []}], SECURITY_SCHEMES) | ||
|
||
# Ignore proposals with multiple mechanisms. | ||
with pytest.raises(OpenAPIError): | ||
AuthProviderBase()([{"B": [], "C": []}], SECURITY_SCHEMES) | ||
|
||
# Select Basic auth alone and from multiple. | ||
assert AuthProviderBase()([{"B": []}], SECURITY_SCHEMES) == "BASIC" | ||
assert AuthProviderBase()([{"A": []}, {"B": []}], SECURITY_SCHEMES) == "BASIC" | ||
|
||
# Select oauth2 client credentials alone and over basic auth if scopes match. | ||
assert AuthProviderBase()([{"D": []}], SECURITY_SCHEMES) == "OAUTH2_CLIENT_CREDENTIALS" | ||
assert ( | ||
AuthProviderBase()([{"B": []}, {"D": []}], SECURITY_SCHEMES) == "OAUTH2_CLIENT_CREDENTIALS" | ||
) | ||
assert ( | ||
AuthProviderBase()([{"B": []}, {"D": ["read:pets"]}], SECURITY_SCHEMES) | ||
== "OAUTH2_CLIENT_CREDENTIALS" | ||
) | ||
assert AuthProviderBase()([{"B": []}, {"D": ["read:cattle"]}], SECURITY_SCHEMES) == "BASIC" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters