ibm-cloud-sdk-core 3.15.0__py3-none-any.whl → 3.20.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. ibm_cloud_sdk_core/__init__.py +1 -0
  2. ibm_cloud_sdk_core/api_exception.py +18 -4
  3. ibm_cloud_sdk_core/authenticators/__init__.py +1 -0
  4. ibm_cloud_sdk_core/authenticators/authenticator.py +3 -3
  5. ibm_cloud_sdk_core/authenticators/basic_authenticator.py +5 -6
  6. ibm_cloud_sdk_core/authenticators/bearer_token_authenticator.py +1 -1
  7. ibm_cloud_sdk_core/authenticators/container_authenticator.py +25 -16
  8. ibm_cloud_sdk_core/authenticators/cp4d_authenticator.py +34 -20
  9. ibm_cloud_sdk_core/authenticators/iam_authenticator.py +22 -13
  10. ibm_cloud_sdk_core/authenticators/iam_request_based_authenticator.py +5 -7
  11. ibm_cloud_sdk_core/authenticators/mcsp_authenticator.py +130 -0
  12. ibm_cloud_sdk_core/authenticators/vpc_instance_authenticator.py +7 -10
  13. ibm_cloud_sdk_core/base_service.py +113 -92
  14. ibm_cloud_sdk_core/detailed_response.py +21 -15
  15. ibm_cloud_sdk_core/get_authenticator.py +28 -16
  16. ibm_cloud_sdk_core/http_adapter.py +28 -0
  17. ibm_cloud_sdk_core/private_helpers.py +34 -0
  18. ibm_cloud_sdk_core/token_managers/container_token_manager.py +61 -30
  19. ibm_cloud_sdk_core/token_managers/cp4d_token_manager.py +34 -21
  20. ibm_cloud_sdk_core/token_managers/iam_request_based_token_manager.py +43 -20
  21. ibm_cloud_sdk_core/token_managers/iam_token_manager.py +24 -13
  22. ibm_cloud_sdk_core/token_managers/jwt_token_manager.py +3 -16
  23. ibm_cloud_sdk_core/token_managers/mcsp_token_manager.py +102 -0
  24. ibm_cloud_sdk_core/token_managers/token_manager.py +13 -23
  25. ibm_cloud_sdk_core/token_managers/vpc_instance_token_manager.py +33 -13
  26. ibm_cloud_sdk_core/utils.py +126 -32
  27. ibm_cloud_sdk_core/version.py +1 -1
  28. {ibm_cloud_sdk_core-3.15.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/METADATA +39 -30
  29. ibm_cloud_sdk_core-3.20.6.dist-info/RECORD +34 -0
  30. {ibm_cloud_sdk_core-3.15.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/WHEEL +1 -1
  31. ibm_cloud_sdk_core-3.20.6.dist-info/top_level.txt +1 -0
  32. ibm_cloud_sdk_core-3.15.0.dist-info/RECORD +0 -52
  33. ibm_cloud_sdk_core-3.15.0.dist-info/top_level.txt +0 -3
  34. ibm_cloud_sdk_core-3.15.0.dist-info/zip-safe +0 -1
  35. test/__init__.py +0 -0
  36. test/test_api_exception.py +0 -73
  37. test/test_authenticator.py +0 -21
  38. test/test_base_service.py +0 -925
  39. test/test_basic_authenticator.py +0 -36
  40. test/test_bearer_authenticator.py +0 -28
  41. test/test_container_authenticator.py +0 -105
  42. test/test_container_token_manager.py +0 -283
  43. test/test_cp4d_authenticator.py +0 -171
  44. test/test_cp4d_token_manager.py +0 -56
  45. test/test_detailed_response.py +0 -57
  46. test/test_iam_authenticator.py +0 -157
  47. test/test_iam_token_manager.py +0 -362
  48. test/test_jwt_token_manager.py +0 -109
  49. test/test_no_auth_authenticator.py +0 -15
  50. test/test_token_manager.py +0 -84
  51. test/test_utils.py +0 -634
  52. test/test_vpc_instance_authenticator.py +0 -66
  53. test/test_vpc_instance_token_manager.py +0 -266
  54. test_integration/__init__.py +0 -0
  55. test_integration/test_cp4d_authenticator_integration.py +0 -45
  56. {ibm_cloud_sdk_core-3.15.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/LICENSE +0 -0
@@ -1,57 +0,0 @@
1
- # coding=utf-8
2
- # pylint: disable=missing-docstring
3
- import json
4
-
5
- import responses
6
- import requests
7
-
8
- from ibm_cloud_sdk_core import DetailedResponse
9
-
10
-
11
- def clean(val):
12
- """Eliminate all whitespace and convert single to double quotes"""
13
- return val.translate(str.maketrans('', '', ' \n\t\r')).replace("'", "\"")
14
-
15
-
16
- @responses.activate
17
- def test_detailed_response_dict():
18
- responses.add(responses.GET,
19
- 'https://test.com',
20
- status=200,
21
- body=json.dumps({'foobar': 'baz'}),
22
- content_type='application/json')
23
-
24
- mock_response = requests.get('https://test.com')
25
- detailed_response = DetailedResponse(response=mock_response.json(), headers=mock_response.headers,
26
- status_code=mock_response.status_code)
27
- assert detailed_response is not None
28
- assert detailed_response.get_result() == {'foobar': 'baz'}
29
- assert detailed_response.get_headers() == {'Content-Type': 'application/json'}
30
- assert detailed_response.get_status_code() == 200
31
-
32
- response_str = clean(detailed_response.__str__())
33
- assert clean(detailed_response.get_result().__str__()) in response_str
34
- #assert clean(detailed_response.get_headers().__str__()) in response_str
35
- assert clean(detailed_response.get_status_code().__str__()) in response_str
36
-
37
-
38
- @responses.activate
39
- def test_detailed_response_list():
40
- responses.add(responses.GET,
41
- 'https://test.com',
42
- status=200,
43
- body=json.dumps(['foobar', 'baz']),
44
- content_type='application/json')
45
-
46
- mock_response = requests.get('https://test.com')
47
- detailed_response = DetailedResponse(response=mock_response.json(), headers=mock_response.headers,
48
- status_code=mock_response.status_code)
49
- assert detailed_response is not None
50
- assert detailed_response.get_result() == ['foobar', 'baz']
51
- assert detailed_response.get_headers() == {'Content-Type': 'application/json'}
52
- assert detailed_response.get_status_code() == 200
53
-
54
- response_str = clean(detailed_response.__str__())
55
- assert clean(detailed_response.get_result().__str__()) in response_str
56
- #assert clean(detailed_response.get_headers().__str__()) in response_str
57
- assert clean(detailed_response.get_status_code().__str__()) in response_str
@@ -1,157 +0,0 @@
1
- # pylint: disable=missing-docstring
2
- import json
3
-
4
- import jwt
5
- import pytest
6
- import responses
7
-
8
- from ibm_cloud_sdk_core.authenticators import IAMAuthenticator, Authenticator
9
-
10
-
11
- def test_iam_authenticator():
12
- authenticator = IAMAuthenticator(apikey='my_apikey')
13
- assert authenticator is not None
14
- assert authenticator.authentication_type() == Authenticator.AUTHTYPE_IAM
15
- assert authenticator.token_manager.url == 'https://iam.cloud.ibm.com'
16
- assert authenticator.token_manager.client_id is None
17
- assert authenticator.token_manager.client_secret is None
18
- assert authenticator.token_manager.disable_ssl_verification is False
19
- assert authenticator.token_manager.headers is None
20
- assert authenticator.token_manager.proxies is None
21
- assert authenticator.token_manager.apikey == 'my_apikey'
22
- assert authenticator.token_manager.scope is None
23
-
24
- authenticator.set_client_id_and_secret('tom', 'jerry')
25
- assert authenticator.token_manager.client_id == 'tom'
26
- assert authenticator.token_manager.client_secret == 'jerry'
27
-
28
- authenticator.set_scope('scope1 scope2 scope3')
29
- assert authenticator.token_manager.scope == 'scope1 scope2 scope3'
30
-
31
- with pytest.raises(TypeError) as err:
32
- authenticator.set_headers('dummy')
33
- assert str(err.value) == 'headers must be a dictionary'
34
-
35
- authenticator.set_headers({'dummy': 'headers'})
36
- assert authenticator.token_manager.headers == {'dummy': 'headers'}
37
-
38
- with pytest.raises(TypeError) as err:
39
- authenticator.set_proxies('dummy')
40
- assert str(err.value) == 'proxies must be a dictionary'
41
-
42
- authenticator.set_proxies({'dummy': 'proxies'})
43
- assert authenticator.token_manager.proxies == {'dummy': 'proxies'}
44
-
45
- authenticator.set_disable_ssl_verification(True)
46
- assert authenticator.token_manager.disable_ssl_verification
47
-
48
-
49
- def test_disable_ssl_verification():
50
- authenticator = IAMAuthenticator(
51
- apikey='my_apikey', disable_ssl_verification=True)
52
- assert authenticator.token_manager.disable_ssl_verification is True
53
-
54
- authenticator.set_disable_ssl_verification(False)
55
- assert authenticator.token_manager.disable_ssl_verification is False
56
-
57
-
58
- def test_invalid_disable_ssl_verification_type():
59
- with pytest.raises(TypeError) as err:
60
- authenticator = IAMAuthenticator(
61
- apikey='my_apikey', disable_ssl_verification='True')
62
- assert str(err.value) == 'disable_ssl_verification must be a bool'
63
-
64
- authenticator = IAMAuthenticator(apikey='my_apikey')
65
- assert authenticator.token_manager.disable_ssl_verification is False
66
-
67
- with pytest.raises(TypeError) as err:
68
- authenticator.set_disable_ssl_verification('True')
69
- assert str(err.value) == 'status must be a bool'
70
-
71
-
72
- def test_iam_authenticator_with_scope():
73
- authenticator = IAMAuthenticator(apikey='my_apikey', scope='scope1 scope2')
74
- assert authenticator is not None
75
- assert authenticator.token_manager.scope == 'scope1 scope2'
76
-
77
-
78
- def test_iam_authenticator_validate_failed():
79
- with pytest.raises(ValueError) as err:
80
- IAMAuthenticator(None)
81
- assert str(err.value) == 'The apikey shouldn\'t be None.'
82
-
83
- with pytest.raises(ValueError) as err:
84
- IAMAuthenticator('{apikey}')
85
- assert str(
86
- err.value
87
- ) == 'The apikey shouldn\'t start or end with curly brackets or quotes. '\
88
- 'Please remove any surrounding {, }, or \" characters.'
89
-
90
- with pytest.raises(ValueError) as err:
91
- IAMAuthenticator('my_apikey', client_id='my_client_id')
92
- assert str(
93
- err.value) == 'Both client_id and client_secret should be initialized.'
94
-
95
- with pytest.raises(ValueError) as err:
96
- IAMAuthenticator('my_apikey', client_secret='my_client_secret')
97
- assert str(
98
- err.value) == 'Both client_id and client_secret should be initialized.'
99
-
100
-
101
- @responses.activate
102
- def test_get_token():
103
- url = "https://iam.cloud.ibm.com/identity/token"
104
- access_token_layout = {
105
- "username": "dummy",
106
- "role": "Admin",
107
- "permissions": ["administrator", "manage_catalog"],
108
- "sub": "admin",
109
- "iss": "sss",
110
- "aud": "sss",
111
- "uid": "sss",
112
- "iat": 1559324664,
113
- "exp": 1559324664
114
- }
115
-
116
- access_token = jwt.encode(
117
- access_token_layout,
118
- 'secret',
119
- algorithm='HS256',
120
- headers={
121
- 'kid': '230498151c214b788dd97f22b85410a5'
122
- })
123
- response = {
124
- "access_token": access_token,
125
- "token_type": "Bearer",
126
- "expires_in": 3600,
127
- "expiration": 1524167011,
128
- "refresh_token": "jy4gl91BQ"
129
- }
130
- responses.add(
131
- responses.POST, url=url, body=json.dumps(response), status=200)
132
-
133
- auth_headers = {'Host': 'iam.cloud.ibm.com:443'}
134
- authenticator = IAMAuthenticator('my_apikey', headers=auth_headers)
135
-
136
- # Simulate an SDK API request that needs to be authenticated.
137
- request = {'headers': {}}
138
-
139
- # Trigger the "get token" processing to obtain the access token and add to the "SDK request".
140
- authenticator.authenticate(request)
141
-
142
- # Verify that the "authenticate()" method added the Authorization header
143
- assert request['headers']['Authorization'] is not None
144
-
145
- # Verify that the "get token" call contained the Host header.
146
- assert responses.calls[0].request.headers.get(
147
- 'Host') == 'iam.cloud.ibm.com:443'
148
-
149
-
150
- def test_multiple_iam_authenticators():
151
- authenticator_1 = IAMAuthenticator('my_apikey')
152
- assert authenticator_1.token_manager.request_payload['apikey'] == 'my_apikey'
153
-
154
- authenticator_2 = IAMAuthenticator('my_other_apikey')
155
- assert authenticator_2.token_manager.request_payload['apikey'] == 'my_other_apikey'
156
-
157
- assert authenticator_1.token_manager.request_payload['apikey'] == 'my_apikey'
@@ -1,362 +0,0 @@
1
- # pylint: disable=missing-docstring
2
- import os
3
- import time
4
-
5
- import jwt
6
- import pytest
7
- import responses
8
-
9
- from ibm_cloud_sdk_core import IAMTokenManager, ApiException, get_authenticator_from_environment
10
-
11
-
12
- def get_access_token() -> str:
13
- access_token_layout = {
14
- "username": "dummy",
15
- "role": "Admin",
16
- "permissions": [
17
- "administrator",
18
- "manage_catalog"
19
- ],
20
- "sub": "admin",
21
- "iss": "sss",
22
- "aud": "sss",
23
- "uid": "sss",
24
- "iat": 3600,
25
- "exp": int(time.time())
26
- }
27
-
28
- access_token = jwt.encode(access_token_layout, 'secret', algorithm='HS256',
29
- headers={'kid': '230498151c214b788dd97f22b85410a5'})
30
- return access_token
31
-
32
-
33
- @responses.activate
34
- def test_request_token_auth_default():
35
- iam_url = "https://iam.cloud.ibm.com/identity/token"
36
- response = """{
37
- "access_token": "oAeisG8yqPY7sFR_x66Z15",
38
- "token_type": "Bearer",
39
- "expires_in": 3600,
40
- "expiration": 1524167011,
41
- "refresh_token": "jy4gl91BQ"
42
- }"""
43
- responses.add(responses.POST, url=iam_url, body=response, status=200)
44
-
45
- token_manager = IAMTokenManager("apikey")
46
- token_manager.request_token()
47
-
48
- assert len(responses.calls) == 1
49
- assert responses.calls[0].request.url == iam_url
50
- assert responses.calls[0].request.headers.get('Authorization') is None
51
- assert responses.calls[0].response.text == response
52
-
53
-
54
- @responses.activate
55
- def test_request_token_auth_in_ctor():
56
- iam_url = "https://iam.cloud.ibm.com/identity/token"
57
- response = """{
58
- "access_token": "oAeisG8yqPY7sFR_x66Z15",
59
- "token_type": "Bearer",
60
- "expires_in": 3600,
61
- "expiration": 1524167011,
62
- "refresh_token": "jy4gl91BQ"
63
- }"""
64
- default_auth_header = 'Basic Yng6Yng='
65
- responses.add(responses.POST, url=iam_url, body=response, status=200)
66
-
67
- token_manager = IAMTokenManager(
68
- "apikey", url=iam_url, client_id='foo', client_secret='bar')
69
- token_manager.request_token()
70
-
71
- assert len(responses.calls) == 1
72
- assert responses.calls[0].request.url == iam_url
73
- assert responses.calls[0].request.headers['Authorization'] != default_auth_header
74
- assert responses.calls[0].response.text == response
75
- assert 'scope' not in responses.calls[0].response.request.body
76
-
77
-
78
- @responses.activate
79
- def test_request_token_auth_in_ctor_with_scope():
80
- iam_url = "https://iam.cloud.ibm.com/identity/token"
81
- response = """{
82
- "access_token": "oAeisG8yqPY7sFR_x66Z15",
83
- "token_type": "Bearer",
84
- "expires_in": 3600,
85
- "expiration": 1524167011,
86
- "refresh_token": "jy4gl91BQ"
87
- }"""
88
- default_auth_header = 'Basic Yng6Yng='
89
- responses.add(responses.POST, url=iam_url, body=response, status=200)
90
-
91
- token_manager = IAMTokenManager(
92
- "apikey", url=iam_url, client_id='foo', client_secret='bar', scope='john snow')
93
- token_manager.request_token()
94
-
95
- assert len(responses.calls) == 1
96
- assert responses.calls[0].request.url == iam_url
97
- assert responses.calls[0].request.headers['Authorization'] != default_auth_header
98
- assert responses.calls[0].response.text == response
99
- assert 'scope=john+snow' in responses.calls[0].response.request.body
100
-
101
-
102
- @responses.activate
103
- def test_request_token_unsuccessful():
104
- iam_url = "https://iam.cloud.ibm.com/identity/token"
105
- response = """{
106
- "context": {
107
- "requestId": "38a0e9c226d94764820d92aa623eb0f6",
108
- "requestType": "incoming.Identity_Token",
109
- "userAgent": "ibm-python-sdk-core-1.0.0",
110
- "url": "https://iam.cloud.ibm.com",
111
- "instanceId": "iamid-4.5-6788-90b137c-75f48695b5-kl4wx",
112
- "threadId": "169de5",
113
- "host": "iamid-4.5-6788-90b137c-75f48695b5-kl4wx",
114
- "startTime": "29.10.2019 12:31:00:300 GMT",
115
- "endTime": "29.10.2019 12:31:00:381 GMT",
116
- "elapsedTime": "81",
117
- "locale": "en_US",
118
- "clusterName": "iam-id-prdal12-8brn"
119
- },
120
- "errorCode": "BXNIM0415E",
121
- "errorMessage": "Provided API key could not be found"
122
- }
123
- """
124
- responses.add(responses.POST, url=iam_url, body=response, status=400)
125
-
126
- token_manager = IAMTokenManager("apikey")
127
- with pytest.raises(ApiException):
128
- token_manager.request_token()
129
-
130
- assert len(responses.calls) == 1
131
- assert responses.calls[0].request.url == iam_url
132
- assert responses.calls[0].response.text == response
133
-
134
-
135
- @responses.activate
136
- def test_request_token_auth_in_ctor_client_id_only():
137
- iam_url = "https://iam.cloud.ibm.com/identity/token"
138
- response = """{
139
- "access_token": "oAeisG8yqPY7sFR_x66Z15",
140
- "token_type": "Bearer",
141
- "expires_in": 3600,
142
- "expiration": 1524167011,
143
- "refresh_token": "jy4gl91BQ"
144
- }"""
145
- responses.add(responses.POST, url=iam_url, body=response, status=200)
146
-
147
- token_manager = IAMTokenManager("iam_apikey", url=iam_url, client_id='foo')
148
- token_manager.request_token()
149
-
150
- assert len(responses.calls) == 1
151
- assert responses.calls[0].request.url == iam_url
152
- assert responses.calls[0].request.headers.get('Authorization') is None
153
- assert responses.calls[0].response.text == response
154
- assert 'scope' not in responses.calls[0].response.request.body
155
-
156
-
157
- @responses.activate
158
- def test_request_token_auth_in_ctor_secret_only():
159
- iam_url = "https://iam.cloud.ibm.com/identity/token"
160
- response = """{
161
- "access_token": "oAeisG8yqPY7sFR_x66Z15",
162
- "token_type": "Bearer",
163
- "expires_in": 3600,
164
- "expiration": 1524167011,
165
- "refresh_token": "jy4gl91BQ"
166
- }"""
167
- responses.add(responses.POST, url=iam_url, body=response, status=200)
168
-
169
- token_manager = IAMTokenManager(
170
- "iam_apikey", url=iam_url, client_id=None, client_secret='bar')
171
- token_manager.request_token()
172
-
173
- assert len(responses.calls) == 1
174
- assert responses.calls[0].request.url == iam_url
175
- assert responses.calls[0].request.headers.get('Authorization') is None
176
- assert responses.calls[0].response.text == response
177
- assert 'scope' not in responses.calls[0].response.request.body
178
-
179
-
180
- @responses.activate
181
- def test_request_token_auth_in_setter():
182
- iam_url = "https://iam.cloud.ibm.com/identity/token"
183
- response = """{
184
- "access_token": "oAeisG8yqPY7sFR_x66Z15",
185
- "token_type": "Bearer",
186
- "expires_in": 3600,
187
- "expiration": 1524167011,
188
- "refresh_token": "jy4gl91BQ"
189
- }"""
190
- default_auth_header = 'Basic Yng6Yng='
191
- responses.add(responses.POST, url=iam_url, body=response, status=200)
192
-
193
- token_manager = IAMTokenManager("iam_apikey")
194
- token_manager.set_client_id_and_secret('foo', 'bar')
195
- token_manager.request_token()
196
-
197
- assert len(responses.calls) == 1
198
- assert responses.calls[0].request.url == iam_url
199
- assert responses.calls[0].request.headers['Authorization'] != default_auth_header
200
- assert responses.calls[0].response.text == response
201
- assert 'scope' not in responses.calls[0].response.request.body
202
-
203
-
204
- @responses.activate
205
- def test_request_token_auth_in_setter_client_id_only():
206
- iam_url = "https://iam.cloud.ibm.com/identity/token"
207
- response = """{
208
- "access_token": "oAeisG8yqPY7sFR_x66Z15",
209
- "token_type": "Bearer",
210
- "expires_in": 3600,
211
- "expiration": 1524167011,
212
- "refresh_token": "jy4gl91BQ"
213
- }"""
214
- responses.add(responses.POST, url=iam_url, body=response, status=200)
215
-
216
- token_manager = IAMTokenManager("iam_apikey")
217
- token_manager.set_client_id_and_secret('foo', None)
218
- token_manager.request_token()
219
-
220
- assert len(responses.calls) == 1
221
- assert responses.calls[0].request.url == iam_url
222
- assert responses.calls[0].request.headers.get('Authorization') is None
223
- assert responses.calls[0].response.text == response
224
- assert 'scope' not in responses.calls[0].response.request.body
225
-
226
-
227
- @responses.activate
228
- def test_request_token_auth_in_setter_secret_only():
229
- iam_url = "https://iam.cloud.ibm.com/identity/token"
230
- response = """{
231
- "access_token": "oAeisG8yqPY7sFR_x66Z15",
232
- "token_type": "Bearer",
233
- "expires_in": 3600,
234
- "expiration": 1524167011,
235
- "refresh_token": "jy4gl91BQ"
236
- }"""
237
- responses.add(responses.POST, url=iam_url, body=response, status=200)
238
-
239
- token_manager = IAMTokenManager("iam_apikey")
240
- token_manager.set_client_id_and_secret(None, 'bar')
241
- token_manager.set_headers({'user': 'header'})
242
- token_manager.request_token()
243
-
244
- assert len(responses.calls) == 1
245
- assert responses.calls[0].request.url == iam_url
246
- assert responses.calls[0].request.headers.get('Authorization') is None
247
- assert responses.calls[0].response.text == response
248
- assert 'scope' not in responses.calls[0].response.request.body
249
-
250
-
251
- @responses.activate
252
- def test_request_token_auth_in_setter_scope():
253
- iam_url = "https://iam.cloud.ibm.com/identity/token"
254
- response = """{
255
- "access_token": "oAeisG8yqPY7sFR_x66Z15",
256
- "token_type": "Bearer",
257
- "expires_in": 3600,
258
- "expiration": 1524167011,
259
- "refresh_token": "jy4gl91BQ"
260
- }"""
261
- responses.add(responses.POST, url=iam_url, body=response, status=200)
262
-
263
- token_manager = IAMTokenManager("iam_apikey")
264
- token_manager.set_client_id_and_secret(None, 'bar')
265
- token_manager.set_headers({'user': 'header'})
266
- token_manager.set_scope('john snow')
267
- token_manager.request_token()
268
-
269
- assert len(responses.calls) == 1
270
- assert responses.calls[0].request.url == iam_url
271
- assert responses.calls[0].request.headers.get('Authorization') is None
272
- assert responses.calls[0].response.text == response
273
- assert 'scope=john+snow' in responses.calls[0].response.request.body
274
-
275
-
276
- @responses.activate
277
- def test_get_refresh_token():
278
- iam_url = "https://iam.cloud.ibm.com/identity/token"
279
- access_token_str = get_access_token()
280
- response = """{
281
- "access_token": "%s",
282
- "token_type": "Bearer",
283
- "expires_in": 3600,
284
- "expiration": 1524167011,
285
- "refresh_token": "jy4gl91BQ"
286
- }""" % (access_token_str)
287
- responses.add(responses.POST, url=iam_url, body=response, status=200)
288
-
289
- token_manager = IAMTokenManager("iam_apikey")
290
- token_manager.get_token()
291
-
292
- assert len(responses.calls) == 2
293
- assert token_manager.refresh_token == "jy4gl91BQ"
294
-
295
- #
296
- # In order to run the following integration test with a live IAM server:
297
- #
298
- # 1. Create file "iamtest.env" in the project root.
299
- # It should look like this:
300
- # IAMTEST1_AUTH_URL=<url> e.g. https://iam.cloud.ibm.com
301
- # IAMTEST1_AUTH_TYPE=iam
302
- # IAMTEST1_APIKEY=<apikey>
303
- # IAMTEST2_AUTH_URL=<url> e.g. https://iam.test.cloud.ibm.com
304
- # IAMTEST2_AUTH_TYPE=iam
305
- # IAMTEST2_APIKEY=<apikey>
306
- # IAMTEST2_CLIENT_ID=<client id>
307
- # IAMTEST2_CLIENT_SECRET=<client secret>
308
- #
309
- # 2. Comment out the "@pytest.mark.skip" decorator below.
310
- #
311
- # 3. Run this command:
312
- # python3 -m pytest -s test -k "test_iam_live_token_server"
313
- # (or just run tests like normal and this test function will be invoked)
314
- #
315
-
316
-
317
- @pytest.mark.skip(reason="avoid integration test in automated builds")
318
- def test_iam_live_token_server():
319
- # Get two iam authenticators from the environment.
320
- # "iamtest1" uses the production IAM token server
321
- # "iamtest2" uses the staging IAM token server
322
- os.environ['IBM_CREDENTIALS_FILE'] = "iamtest.env"
323
-
324
- # Test "iamtest1" service
325
- auth1 = get_authenticator_from_environment("iamtest1")
326
- assert auth1 is not None
327
- assert auth1.token_manager is not None
328
- assert auth1.token_manager.url is not None
329
-
330
- request = {'method': "GET"}
331
- request["url"] = ""
332
- request["headers"] = {}
333
-
334
- assert auth1.token_manager.refresh_token is None
335
-
336
- auth1.authenticate(request)
337
-
338
- assert request.get("headers") is not None
339
- assert request["headers"].get("Authorization") is not None
340
- assert "Bearer " in request["headers"].get("Authorization")
341
-
342
- # Test "iamtest2" service
343
- auth2 = get_authenticator_from_environment("iamtest2")
344
- assert auth2 is not None
345
- assert auth2.token_manager is not None
346
- assert auth2.token_manager.url is not None
347
-
348
- request = {'method': "GET"}
349
- request["url"] = ""
350
- request["headers"] = {}
351
-
352
- assert auth2.token_manager.refresh_token is None
353
-
354
- auth2.authenticate(request)
355
-
356
- assert auth2.token_manager.refresh_token is not None
357
-
358
- assert request.get("headers") is not None
359
- assert request["headers"].get("Authorization") is not None
360
- assert "Bearer " in request["headers"].get("Authorization")
361
-
362
- # print('Refresh token: ', auth2.token_manager.refresh_token)
@@ -1,109 +0,0 @@
1
- # pylint: disable=missing-docstring,protected-access,abstract-class-instantiated
2
- import time
3
- import threading
4
- from typing import Optional
5
-
6
- import jwt
7
- import pytest
8
-
9
- from ibm_cloud_sdk_core import JWTTokenManager, DetailedResponse
10
-
11
-
12
- class JWTTokenManagerMockImpl(JWTTokenManager):
13
- def __init__(self, url: Optional[str] = None, access_token: Optional[str] = None) -> None:
14
- self.url = url
15
- self.access_token = access_token
16
- self.request_count = 0 # just for tests to see how many times request was called
17
- super().__init__(url, disable_ssl_verification=access_token,
18
- token_name='access_token')
19
-
20
- def request_token(self) -> DetailedResponse:
21
- self.request_count += 1
22
- current_time = int(time.time())
23
- token_layout = {
24
- "username": "dummy",
25
- "role": "Admin",
26
- "permissions": [
27
- "administrator",
28
- "manage_catalog"
29
- ],
30
- "sub": "admin",
31
- "iss": "sss",
32
- "aud": "sss",
33
- "uid": "sss",
34
- "iat": current_time,
35
- "exp": current_time + 3600
36
- }
37
-
38
- access_token = jwt.encode(token_layout, 'secret', algorithm='HS256',
39
- headers={'kid': '230498151c214b788dd97f22b85410a5'})
40
- response = {"access_token": access_token,
41
- "token_type": "Bearer",
42
- "expires_in": 3600,
43
- "expiration": current_time + 3600,
44
- "refresh_token": "jy4gl91BQ",
45
- "from_token_manager": True
46
- }
47
- time.sleep(0.5)
48
- return response
49
-
50
-
51
- def _get_current_time() -> int:
52
- return int(time.time())
53
-
54
-
55
- def test_get_token():
56
- url = "https://iam.cloud.ibm.com/identity/token"
57
- token_manager = JWTTokenManagerMockImpl(url)
58
- old_token = token_manager.get_token()
59
- assert token_manager.token_info.get('expires_in') == 3600
60
- assert token_manager._is_token_expired() is False
61
-
62
- token_manager.token_info = {"access_token": "old_dummy",
63
- "token_type": "Bearer",
64
- "expires_in": 3600,
65
- "expiration": time.time(),
66
- "refresh_token": "jy4gl91BQ"
67
- }
68
- token = token_manager.get_token()
69
- assert token == old_token
70
-
71
- # expired token:
72
- token_manager.expire_time = _get_current_time() - 300
73
- token = token_manager.get_token()
74
- assert token != "old_dummy"
75
- assert token_manager.request_count == 2
76
-
77
-
78
- def test_paced_get_token():
79
- url = "https://iam.cloud.ibm.com/identity/token"
80
- token_manager = JWTTokenManagerMockImpl(url)
81
- threads = []
82
- for _ in range(10):
83
- thread = threading.Thread(target=token_manager.get_token)
84
- thread.start()
85
- threads.append(thread)
86
- for thread in threads:
87
- thread.join()
88
- assert token_manager.request_count == 1
89
-
90
-
91
- def test_is_token_expired():
92
- token_manager = JWTTokenManagerMockImpl(None, access_token=None)
93
- assert token_manager._is_token_expired() is True
94
- token_manager.expire_time = _get_current_time() + 3600
95
- assert token_manager._is_token_expired() is False
96
- token_manager.expire_time = _get_current_time() - 3600
97
- assert token_manager._is_token_expired()
98
-
99
-
100
- def test_abstract_class_instantiation():
101
- with pytest.raises(TypeError) as err:
102
- JWTTokenManager(None)
103
- assert str(err.value).startswith("Can't instantiate abstract class JWTTokenManager with abstract")
104
-
105
-
106
- def test_disable_ssl_verification():
107
- token_manager = JWTTokenManagerMockImpl('https://iam.cloud.ibm.com/identity/token')
108
- token_manager.set_disable_ssl_verification(True)
109
- assert token_manager.disable_ssl_verification is True