Skip to content

Commit 36425f9

Browse files
committed
chore: iam assume token manager test improvements
Signed-off-by: Norbert Biczo <[email protected]>
1 parent 97e4d3b commit 36425f9

File tree

1 file changed

+71
-59
lines changed

1 file changed

+71
-59
lines changed

test/test_iam_assume_token_manager.py

Lines changed: 71 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,31 @@
1818
import json
1919
import logging
2020
import time
21+
import urllib
2122

2223
import jwt
2324
import responses
2425

2526
from ibm_cloud_sdk_core import IAMAssumeTokenManager
27+
from ibm_cloud_sdk_core.api_exception import ApiException
2628
from .utils.logger_utils import setup_test_logger
2729

2830

29-
MY_PROFILE_ID = 'my-profile-id'
30-
MY_PROFILE_CRN = 'my-profile-crn'
31-
MY_PROFILE_NAME = 'my-profile-name'
32-
MY_ACCOUNT_ID = 'my-account_id'
33-
34-
3531
setup_test_logger(logging.ERROR)
3632

3733

3834
def _get_current_time() -> int:
3935
return int(time.time())
4036

4137

38+
IAM_URL = "https://iam.cloud.ibm.com/identity/token"
39+
MY_PROFILE_ID = 'my-profile-id'
40+
MY_PROFILE_CRN = 'my-profile-crn'
41+
MY_PROFILE_NAME = 'my-profile-name'
42+
MY_ACCOUNT_ID = 'my-account_id'
43+
44+
45+
# The base layout of an access token.
4246
ACCESS_TOKEN_LAYOUT = {
4347
"username": "dummy",
4448
"role": "Admin",
@@ -50,33 +54,53 @@ def _get_current_time() -> int:
5054
"iat": _get_current_time(),
5155
"exp": _get_current_time() + 3600,
5256
}
53-
57+
# Create two different access tokens by using different secrets for the encoding.
5458
ACCESS_TOKEN = jwt.encode(
5559
ACCESS_TOKEN_LAYOUT, 'secret', algorithm='HS256', headers={'kid': '230498151c214b788dd97f22b85410a5'}
5660
)
61+
OTHER_ACCESS_TOKEN = jwt.encode(
62+
ACCESS_TOKEN_LAYOUT, 'other_secret', algorithm='HS256', headers={'kid': '230498151c214b788dd97f22b85410a5'}
63+
)
64+
# Create a base response and serialize it to a JSON string to avoid doing that in each test case.
65+
BASE_RESPONSE = {
66+
"access_token": ACCESS_TOKEN,
67+
"token_type": "Bearer",
68+
"expires_in": 3600,
69+
"expiration": _get_current_time() + 3600,
70+
"refresh_token": "not_available",
71+
}
72+
BASE_RESPONSE_JSON = json.dumps(BASE_RESPONSE)
73+
# Create a second base response just like we did above, but use the other access token.
74+
OTHER_BASE_RESPONSE = BASE_RESPONSE.copy()
75+
OTHER_BASE_RESPONSE['access_token'] = OTHER_ACCESS_TOKEN
76+
OTHER_BASE_RESPONSE_JSON = json.dumps(OTHER_BASE_RESPONSE)
77+
78+
79+
def request_callback(request):
80+
"""Parse the form data, and return a response based on the `grant_type` value."""
81+
form_data = urllib.parse.unquote(request.body)
82+
params = dict(param.split('=') for param in form_data.split('&'))
83+
if params.get('grant_type') == 'urn:ibm:params:oauth:grant-type:apikey':
84+
return (200, {}, BASE_RESPONSE_JSON)
85+
if params.get('grant_type') == 'urn:ibm:params:oauth:grant-type:assume':
86+
return (200, {}, OTHER_BASE_RESPONSE_JSON)
87+
88+
raise ApiException(400)
5789

5890

5991
@responses.activate
6092
def test_request_token_with_profile_id():
61-
iam_url = "https://iam.cloud.ibm.com/identity/token"
62-
response = {
63-
"access_token": ACCESS_TOKEN,
64-
"token_type": "Bearer",
65-
"expires_in": 3600,
66-
"expiration": _get_current_time() + 3600,
67-
"refresh_token": "jy4gl91BQ",
68-
}
69-
responses.add(responses.POST, url=iam_url, body=json.dumps(response), status=200)
93+
responses.add_callback(responses.POST, url=IAM_URL, callback=request_callback)
7094

7195
token_manager = IAMAssumeTokenManager("apikey", iam_profile_id=MY_PROFILE_ID)
7296

7397
# Make sure we don't have an access token yet.
74-
assert token_manager.request_payload.get('access_token', None) is None
98+
assert token_manager.request_payload.get('access_token') is None
7599

76100
token_manager.request_token()
77101

78102
# Now the access token should be set along with the profile ID.
79-
assert token_manager.request_payload.get('access_token') is not None
103+
assert token_manager.request_payload.get('access_token') == ACCESS_TOKEN
80104
assert token_manager.request_payload.get('profile_id') == MY_PROFILE_ID
81105
assert token_manager.request_payload.get('profile_crn') is None
82106
assert token_manager.request_payload.get('profile_name') is None
@@ -85,25 +109,17 @@ def test_request_token_with_profile_id():
85109

86110
@responses.activate
87111
def test_request_token_with_profile_crn():
88-
iam_url = "https://iam.cloud.ibm.com/identity/token"
89-
response = {
90-
"access_token": ACCESS_TOKEN,
91-
"token_type": "Bearer",
92-
"expires_in": 3600,
93-
"expiration": _get_current_time() + 3600,
94-
"refresh_token": "jy4gl91BQ",
95-
}
96-
responses.add(responses.POST, url=iam_url, body=json.dumps(response), status=200)
112+
responses.add_callback(responses.POST, url=IAM_URL, callback=request_callback)
97113

98114
token_manager = IAMAssumeTokenManager("apikey", iam_profile_crn=MY_PROFILE_CRN)
99115

100116
# Make sure we don't have an access token yet.
101-
assert token_manager.request_payload.get('access_token', None) is None
117+
assert token_manager.request_payload.get('access_token') is None
102118

103119
token_manager.request_token()
104120

105121
# Now the access token should be set along with the profile ID.
106-
assert token_manager.request_payload.get('access_token') is not None
122+
assert token_manager.request_payload.get('access_token') == ACCESS_TOKEN
107123
assert token_manager.request_payload.get('profile_id') is None
108124
assert token_manager.request_payload.get('profile_crn') == MY_PROFILE_CRN
109125
assert token_manager.request_payload.get('profile_name') is None
@@ -112,25 +128,17 @@ def test_request_token_with_profile_crn():
112128

113129
@responses.activate
114130
def test_request_token_with_profile_name_and_account_id():
115-
iam_url = "https://iam.cloud.ibm.com/identity/token"
116-
response = {
117-
"access_token": ACCESS_TOKEN,
118-
"token_type": "Bearer",
119-
"expires_in": 3600,
120-
"expiration": _get_current_time() + 3600,
121-
"refresh_token": "jy4gl91BQ",
122-
}
123-
responses.add(responses.POST, url=iam_url, body=json.dumps(response), status=200)
131+
responses.add_callback(responses.POST, url=IAM_URL, callback=request_callback)
124132

125133
token_manager = IAMAssumeTokenManager("apikey", iam_profile_name=MY_PROFILE_NAME, iam_account_id=MY_ACCOUNT_ID)
126134

127135
# Make sure we don't have an access token yet.
128-
assert token_manager.request_payload.get('access_token', None) is None
136+
assert token_manager.request_payload.get('access_token') is None
129137

130138
token_manager.request_token()
131139

132140
# Now the access token should be set along with the profile ID.
133-
assert token_manager.request_payload.get('access_token') is not None
141+
assert token_manager.request_payload.get('access_token') == ACCESS_TOKEN
134142
assert token_manager.request_payload.get('profile_id') is None
135143
assert token_manager.request_payload.get('profile_crn') is None
136144
assert token_manager.request_payload.get('profile_name') == MY_PROFILE_NAME
@@ -140,15 +148,7 @@ def test_request_token_with_profile_name_and_account_id():
140148
@responses.activate
141149
def test_request_token_uses_the_correct_grant_types():
142150
iam_url = "https://iam.cloud.ibm.com/identity/token"
143-
response = {
144-
"access_token": ACCESS_TOKEN,
145-
"token_type": "Bearer",
146-
"expires_in": 3600,
147-
"expiration": _get_current_time() + 3600,
148-
"refresh_token": "jy4gl91BQ",
149-
}
150-
response_json = json.dumps(response)
151-
responses.add(responses.POST, url=iam_url, body=response_json, status=200)
151+
responses.add(responses.POST, url=iam_url, body=BASE_RESPONSE_JSON, status=200)
152152

153153
token_manager = IAMAssumeTokenManager("apikey", iam_profile_id='my_profile_id')
154154
token_manager.request_token()
@@ -159,16 +159,7 @@ def test_request_token_uses_the_correct_grant_types():
159159

160160
@responses.activate
161161
def test_request_token_uses_the_correct_headers():
162-
iam_url = "https://iam.cloud.ibm.com/identity/token"
163-
response = {
164-
"access_token": ACCESS_TOKEN,
165-
"token_type": "Bearer",
166-
"expires_in": 3600,
167-
"expiration": _get_current_time() + 3600,
168-
"refresh_token": "jy4gl91BQ",
169-
}
170-
response_json = json.dumps(response)
171-
responses.add(responses.POST, url=iam_url, body=response_json, status=200)
162+
responses.add_callback(responses.POST, url=IAM_URL, callback=request_callback)
172163

173164
token_manager = IAMAssumeTokenManager("apikey", iam_profile_id='my_profile_id')
174165
token_manager.request_token()
@@ -178,3 +169,24 @@ def test_request_token_uses_the_correct_headers():
178169
assert (
179170
responses.calls[1].request.headers.get('User-Agent').startswith('ibm-python-sdk-core/iam-assume-authenticator')
180171
)
172+
173+
174+
@responses.activate
175+
def test_get_token():
176+
responses.add_callback(responses.POST, url=IAM_URL, callback=request_callback)
177+
178+
token_manager = IAMAssumeTokenManager("apikey", iam_profile_id=MY_PROFILE_ID)
179+
180+
# Make sure we don't have an access token yet.
181+
assert token_manager.request_payload.get('access_token') is None
182+
183+
access_token = token_manager.get_token()
184+
# Now the access token should be set along with the profile ID.
185+
assert token_manager.request_payload.get('access_token') == ACCESS_TOKEN
186+
assert token_manager.request_payload.get('profile_id') == MY_PROFILE_ID
187+
assert token_manager.request_payload.get('profile_crn') is None
188+
assert token_manager.request_payload.get('profile_name') is None
189+
assert token_manager.request_payload.get('account_id') is None
190+
191+
# The final result should be the other access token, which belong to the "assume" request.
192+
assert access_token == OTHER_ACCESS_TOKEN

0 commit comments

Comments
 (0)