Skip to content
This repository was archived by the owner on Jun 1, 2023. It is now read-only.

Commit d32baa6

Browse files
authored
Merge pull request #8 from angelakis/feature-token-exchange
Feature token exchange
2 parents 59c763d + 7d9d288 commit d32baa6

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

src/oidcmsg/oauth2/__init__.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,32 @@ class TokenIntrospectionResponse(Message):
295295
}
296296

297297

298+
# RFC 8693
299+
class TokenExchangeRequest(Message):
300+
c_param = {
301+
"grant_type": SINGLE_REQUIRED_STRING,
302+
"resource": OPTIONAL_LIST_OF_STRINGS,
303+
"audience": OPTIONAL_LIST_OF_STRINGS,
304+
"scope": OPTIONAL_LIST_OF_SP_SEP_STRINGS,
305+
"requested_token_type": SINGLE_OPTIONAL_STRING,
306+
"subject_token": SINGLE_REQUIRED_STRING,
307+
"subject_token_type": SINGLE_REQUIRED_STRING,
308+
"actor_token": SINGLE_OPTIONAL_STRING,
309+
"actor_token_type": SINGLE_OPTIONAL_STRING,
310+
}
311+
312+
313+
class TokenExchangeResponse(Message):
314+
c_param = {
315+
"access_token": SINGLE_REQUIRED_STRING,
316+
"issued_token_type": SINGLE_REQUIRED_STRING,
317+
"token_type": SINGLE_REQUIRED_STRING,
318+
"expires_in": SINGLE_OPTIONAL_INT,
319+
"refresh_token": SINGLE_OPTIONAL_STRING,
320+
"scope": OPTIONAL_LIST_OF_SP_SEP_STRINGS,
321+
}
322+
323+
298324
class JWTSecuredAuthorizationRequest(AuthorizationRequest):
299325
c_param = AuthorizationRequest.c_param.copy()
300326
c_param.update({

tests/test_05_oauth2.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
from oidcmsg.oauth2 import AuthorizationResponse
1919
from oidcmsg.oauth2 import CCAccessTokenRequest
2020
from oidcmsg.oauth2 import RefreshAccessTokenRequest
21+
from oidcmsg.oauth2 import TokenExchangeRequest
22+
from oidcmsg.oauth2 import TokenExchangeResponse
2123
from oidcmsg.oauth2 import ResponseMessage
2224
from oidcmsg.oauth2 import ROPCAccessTokenRequest
2325
from oidcmsg.oauth2 import TokenErrorResponse
@@ -504,6 +506,45 @@ def test_init(self):
504506
assert ratr.verify()
505507

506508

509+
class TestTokenExchangeRequest(object):
510+
def test_init(self):
511+
request = TokenExchangeRequest(
512+
grant_type="urn:ietf:params:oauth:grant-type:token-exchange",
513+
subject_token="ababababab",
514+
subject_token_type="urn:ietf:params:oauth:token-type:access_token"
515+
)
516+
assert (
517+
request["grant_type"]
518+
== "urn:ietf:params:oauth:grant-type:token-exchange"
519+
)
520+
assert request["subject_token"] == "ababababab"
521+
assert (
522+
request["subject_token_type"]
523+
== "urn:ietf:params:oauth:token-type:access_token"
524+
)
525+
526+
assert request.verify()
527+
528+
529+
class TestTokenExchangeResponse(object):
530+
def test_init(self):
531+
response = TokenExchangeResponse(
532+
access_token="bababababa",
533+
issued_token_type="urn:ietf:params:oauth:token-type:access_token",
534+
token_type="Bearer",
535+
expires_in=60
536+
)
537+
assert (
538+
response["issued_token_type"]
539+
== "urn:ietf:params:oauth:token-type:access_token"
540+
)
541+
assert response["access_token"] == "bababababa"
542+
assert response["token_type"] == "Bearer"
543+
assert response["expires_in"] == 60
544+
545+
assert response.verify()
546+
547+
507548
class TestResponseMessage_error(object):
508549
def test_error_message(self):
509550
err = ResponseMessage(error="invalid_request",

0 commit comments

Comments
 (0)