Skip to content

Commit

Permalink
Merge pull request #457 from UgnineSirdis/oauth2-fix-resource
Browse files Browse the repository at this point in the history
OAuth 2.0 token exchange. Allow multiple resource parameters
  • Loading branch information
vgvoleg authored Jul 29, 2024
2 parents 2c3e0ca + 2cbee93 commit 6102df4
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* OAuth 2.0 token exchange. Allow multiple resource parameters in according to https://www.rfc-editor.org/rfc/rfc8693

## 3.14.0 ##
* Added load OAuth 2.0 token exchange credentials provider from config file

Expand Down Expand Up @@ -83,7 +85,7 @@ yanked bad api release

## 3.3.5 ##
* Fixed use positional argument instead of named in WriterAsyncIO.__del__
* Fixed release buffer while read topic by one messages
* Fixed release buffer while read topic by one messages
* Fixed race condition between commit_with_ack and reconnect in topic writer

## 3.3.4 ##
Expand Down
11 changes: 7 additions & 4 deletions tests/oauth2_token_exchange/test_token_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,12 @@ def check(self, handler, parsed_request) -> None:
assert len(parsed_request.get("scope", [])) == 1
assert parsed_request["scope"][0] == " ".join(self.scope)

if self.resource is None or self.resource == "":
if self.resource is None or len(self.resource) == 0:
assert len(parsed_request.get("resource", [])) == 0
else:
assert len(parsed_request.get("resource", [])) == 1
assert parsed_request["resource"][0] == self.resource
assert len(parsed_request["resource"]) == len(self.resource)
for i in range(len(self.resource)):
assert parsed_request["resource"][i] == self.resource[i]

if self.subject_token_source is None:
assert len(parsed_request.get("subject_token", [])) == 0
Expand Down Expand Up @@ -478,7 +479,7 @@ def test_oauth2_token_exchange_credentials_file():
),
grant_type="grant",
requested_token_type="access_token",
resource="tEst",
resource=["tEst"],
),
response=Oauth2TokenExchangeResponse(
200,
Expand All @@ -498,6 +499,7 @@ def test_oauth2_token_exchange_credentials_file():
"s1",
"s2",
],
"res": ["r1", "r2"],
"unknown-field": [123],
"actor-credentials": {
"type": "fixed",
Expand All @@ -512,6 +514,7 @@ def test_oauth2_token_exchange_credentials_file():
),
audience=["test-aud"],
scope=["s1", "s2"],
resource=["r1", "r2"],
),
response=Oauth2TokenExchangeResponse(
200,
Expand Down
42 changes: 39 additions & 3 deletions ydb/oauth2_token_exchange/token_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __init__(
actor_token_source: typing.Optional[TokenSource] = None,
audience: typing.Union[typing.List[str], str, None] = None,
scope: typing.Union[typing.List[str], str, None] = None,
resource: typing.Optional[str] = None,
resource: typing.Union[typing.List[str], str, None] = None,
grant_type: str = "urn:ietf:params:oauth:grant-type:token-exchange",
requested_token_type: str = "urn:ietf:params:oauth:token-type:access_token",
):
Expand Down Expand Up @@ -224,6 +224,42 @@ def _duration_seconds_from_config(cls, cfg_json, key_name, default_value):

@classmethod
def from_file(cls, cfg_file, iam_endpoint=None):
"""
Create OAuth 2.0 token exchange protocol credentials from config file.
https://www.rfc-editor.org/rfc/rfc8693
Config file must be a valid json file
Fields of json file
grant-type: [string] Grant type option (default: "urn:ietf:params:oauth:grant-type:token-exchange")
res: [string | list of strings] Resource option (optional)
aud: [string | list of strings] Audience option for token exchange request (optional)
scope: [string | list of strings] Scope option (optional)
requested-token-type: [string] Requested token type option (default: "urn:ietf:params:oauth:token-type:access_token")
subject-credentials: [creds_json] Subject credentials options (optional)
actor-credentials: [creds_json] Actor credentials options (optional)
token-endpoint: [string] Token endpoint
Fields of creds_json (JWT):
type: [string] Token source type. Set JWT
alg: [string] Algorithm for JWT signature.
Supported algorithms can be listed
with GetSupportedOauth2TokenExchangeJwtAlgorithms()
private-key: [string] (Private) key in PEM format (RSA, EC) or Base64 format (HMAC) for JWT signature
kid: [string] Key id JWT standard claim (optional)
iss: [string] Issuer JWT standard claim (optional)
sub: [string] Subject JWT standard claim (optional)
aud: [string | list of strings] Audience JWT standard claim (optional)
jti: [string] JWT ID JWT standard claim (optional)
ttl: [string] Token TTL (default: 1h)
Fields of creds_json (FIXED):
type: [string] Token source type. Set FIXED
token: [string] Token value
token-type: [string] Token type value. It will become
subject_token_type/actor_token_type parameter
in token exchange request (https://www.rfc-editor.org/rfc/rfc8693)
"""
with open(os.path.expanduser(cfg_file), "r") as r:
cfg = r.read()

Expand All @@ -245,7 +281,7 @@ def from_content(cls, cfg, iam_endpoint=None):
actor_token_source = cls._token_source_from_config(cfg_json, "actor-credentials")
audience = cls._list_of_strings_or_single_from_config(cfg_json, "aud")
scope = cls._list_of_strings_or_single_from_config(cfg_json, "scope")
resource = cls._string_with_default_from_config(cfg_json, "res", None)
resource = cls._list_of_strings_or_single_from_config(cfg_json, "res")
grant_type = cls._string_with_default_from_config(
cfg_json, "grant-type", "urn:ietf:params:oauth:grant-type:token-exchange"
)
Expand Down Expand Up @@ -273,7 +309,7 @@ def __init__(
actor_token_source: typing.Optional[TokenSource] = None,
audience: typing.Union[typing.List[str], str, None] = None,
scope: typing.Union[typing.List[str], str, None] = None,
resource: typing.Optional[str] = None,
resource: typing.Union[typing.List[str], str, None] = None,
grant_type: str = "urn:ietf:params:oauth:grant-type:token-exchange",
requested_token_type: str = "urn:ietf:params:oauth:token-type:access_token",
tracer=None,
Expand Down

0 comments on commit 6102df4

Please sign in to comment.