ibm-cloud-sdk-core 3.16.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 +2 -1
  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 +33 -21
  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 +107 -91
  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 +30 -22
  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 +121 -46
  27. ibm_cloud_sdk_core/version.py +1 -1
  28. {ibm_cloud_sdk_core-3.16.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/METADATA +40 -28
  29. ibm_cloud_sdk_core-3.20.6.dist-info/RECORD +34 -0
  30. {ibm_cloud_sdk_core-3.16.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.16.0.dist-info/RECORD +0 -52
  33. ibm_cloud_sdk_core-3.16.0.dist-info/top_level.txt +0 -3
  34. ibm_cloud_sdk_core-3.16.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 -933
  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.16.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/LICENSE +0 -0
@@ -1,36 +0,0 @@
1
- # pylint: disable=missing-docstring
2
- import pytest
3
-
4
- from ibm_cloud_sdk_core.authenticators import BasicAuthenticator, Authenticator
5
-
6
-
7
- def test_basic_authenticator():
8
- authenticator = BasicAuthenticator('my_username', 'my_password')
9
- assert authenticator is not None
10
- assert authenticator.authentication_type() == Authenticator.AUTHTYPE_BASIC
11
- assert authenticator.username == 'my_username'
12
- assert authenticator.password == 'my_password'
13
-
14
- request = {'headers': {}}
15
- authenticator.authenticate(request)
16
- assert request['headers']['Authorization'] == 'Basic bXlfdXNlcm5hbWU6bXlfcGFzc3dvcmQ='
17
-
18
-
19
- def test_basic_authenticator_validate_failed():
20
- with pytest.raises(ValueError) as err:
21
- BasicAuthenticator('my_username', None)
22
- assert str(err.value) == 'The username and password shouldn\'t be None.'
23
-
24
- with pytest.raises(ValueError) as err:
25
- BasicAuthenticator(None, 'my_password')
26
- assert str(err.value) == 'The username and password shouldn\'t be None.'
27
-
28
- with pytest.raises(ValueError) as err:
29
- BasicAuthenticator('{my_username}', 'my_password')
30
- assert str(err.value) == 'The username and password shouldn\'t start or end with curly brackets or quotes. '\
31
- 'Please remove any surrounding {, }, or \" characters.'
32
-
33
- with pytest.raises(ValueError) as err:
34
- BasicAuthenticator('my_username', '{my_password}')
35
- assert str(err.value) == 'The username and password shouldn\'t start or end with curly brackets or quotes. '\
36
- 'Please remove any surrounding {, }, or \" characters.'
@@ -1,28 +0,0 @@
1
- # pylint: disable=missing-docstring
2
- import pytest
3
-
4
- from ibm_cloud_sdk_core.authenticators import BearerTokenAuthenticator, Authenticator
5
-
6
-
7
- def test_bearer_authenticator():
8
- authenticator = BearerTokenAuthenticator('my_bearer_token')
9
- assert authenticator is not None
10
- assert authenticator.authentication_type() == Authenticator.AUTHTYPE_BEARERTOKEN
11
- assert authenticator.bearer_token == 'my_bearer_token'
12
-
13
- authenticator.set_bearer_token('james bond')
14
- assert authenticator.bearer_token == 'james bond'
15
-
16
- request = {'headers': {}}
17
- authenticator.authenticate(request)
18
- assert request['headers']['Authorization'] == 'Bearer james bond'
19
-
20
-
21
- def test_bearer_validate_failed():
22
- with pytest.raises(ValueError) as err:
23
- BearerTokenAuthenticator(None)
24
- assert str(err.value) == 'The bearer token shouldn\'t be None.'
25
- authenticator = BearerTokenAuthenticator('my_bearer_token')
26
- with pytest.raises(ValueError) as err:
27
- authenticator.set_bearer_token(None)
28
- assert str(err.value) == 'The bearer token shouldn\'t be None.'
@@ -1,105 +0,0 @@
1
- # pylint: disable=missing-docstring
2
- import pytest
3
-
4
- from ibm_cloud_sdk_core.authenticators import ContainerAuthenticator, Authenticator
5
-
6
-
7
- def test_container_authenticator():
8
- authenticator = ContainerAuthenticator(iam_profile_name='iam-user-123')
9
- assert authenticator is not None
10
- assert authenticator.authentication_type() == Authenticator.AUTHTYPE_CONTAINER
11
- assert authenticator.token_manager.cr_token_filename is None
12
- assert authenticator.token_manager.iam_profile_name == 'iam-user-123'
13
- assert authenticator.token_manager.iam_profile_id is None
14
- assert authenticator.token_manager.client_id is None
15
- assert authenticator.token_manager.client_secret is None
16
- assert authenticator.token_manager.disable_ssl_verification is False
17
- assert authenticator.token_manager.headers is None
18
- assert authenticator.token_manager.proxies is None
19
- assert authenticator.token_manager.scope is None
20
-
21
- authenticator.set_cr_token_filename('path/to/token')
22
- assert authenticator.token_manager.cr_token_filename == 'path/to/token'
23
-
24
- # Set the IAM profile to None to trigger a validation which will fail,
25
- # because both of the profile and ID are None.
26
- with pytest.raises(ValueError) as err:
27
- authenticator.set_iam_profile_name(None)
28
- assert str(
29
- err.value) == 'At least one of iam_profile_name or iam_profile_id must be specified.'
30
-
31
- authenticator.set_iam_profile_id('iam-id-123')
32
- assert authenticator.token_manager.iam_profile_id == 'iam-id-123'
33
-
34
- authenticator.set_iam_profile_name('iam-user-123')
35
- assert authenticator.token_manager.iam_profile_name == 'iam-user-123'
36
-
37
- authenticator.set_client_id_and_secret('tom', 'jerry')
38
- assert authenticator.token_manager.client_id == 'tom'
39
- assert authenticator.token_manager.client_secret == 'jerry'
40
-
41
- authenticator.set_scope('scope1 scope2 scope3')
42
- assert authenticator.token_manager.scope == 'scope1 scope2 scope3'
43
-
44
- with pytest.raises(TypeError) as err:
45
- authenticator.set_headers('dummy')
46
- assert str(err.value) == 'headers must be a dictionary'
47
-
48
- authenticator.set_headers({'dummy': 'headers'})
49
- assert authenticator.token_manager.headers == {'dummy': 'headers'}
50
-
51
- with pytest.raises(TypeError) as err:
52
- authenticator.set_proxies('dummy')
53
- assert str(err.value) == 'proxies must be a dictionary'
54
-
55
- authenticator.set_proxies({'dummy': 'proxies'})
56
- assert authenticator.token_manager.proxies == {'dummy': 'proxies'}
57
-
58
-
59
- def test_disable_ssl_verification():
60
- authenticator = ContainerAuthenticator(
61
- iam_profile_name='iam-user-123', disable_ssl_verification=True)
62
- assert authenticator.token_manager.disable_ssl_verification is True
63
-
64
- authenticator.set_disable_ssl_verification(False)
65
- assert authenticator.token_manager.disable_ssl_verification is False
66
-
67
-
68
- def test_invalid_disable_ssl_verification_type():
69
- with pytest.raises(TypeError) as err:
70
- authenticator = ContainerAuthenticator(
71
- iam_profile_name='iam-user-123', disable_ssl_verification='True')
72
- assert str(err.value) == 'disable_ssl_verification must be a bool'
73
-
74
- authenticator = ContainerAuthenticator(iam_profile_name='iam-user-123')
75
- assert authenticator.token_manager.disable_ssl_verification is False
76
-
77
- with pytest.raises(TypeError) as err:
78
- authenticator.set_disable_ssl_verification('True')
79
- assert str(err.value) == 'status must be a bool'
80
-
81
-
82
- def test_container_authenticator_with_scope():
83
- authenticator = ContainerAuthenticator(
84
- iam_profile_name='iam-user-123', scope='scope1 scope2')
85
- assert authenticator is not None
86
- assert authenticator.token_manager.scope == 'scope1 scope2'
87
-
88
-
89
- def test_authenticator_validate_failed():
90
- with pytest.raises(ValueError) as err:
91
- ContainerAuthenticator(None)
92
- assert str(
93
- err.value) == 'At least one of iam_profile_name or iam_profile_id must be specified.'
94
-
95
- with pytest.raises(ValueError) as err:
96
- ContainerAuthenticator(
97
- iam_profile_name='iam-user-123', client_id='my_client_id')
98
- assert str(
99
- err.value) == 'Both client_id and client_secret should be initialized.'
100
-
101
- with pytest.raises(ValueError) as err:
102
- ContainerAuthenticator(
103
- iam_profile_name='iam-user-123', client_secret='my_client_secret')
104
- assert str(
105
- err.value) == 'Both client_id and client_secret should be initialized.'
@@ -1,283 +0,0 @@
1
- # pylint: disable=missing-docstring
2
- import json
3
- import os
4
- import time
5
- from urllib.parse import parse_qs
6
-
7
- import responses
8
- import pytest
9
-
10
- from ibm_cloud_sdk_core import ApiException, ContainerTokenManager
11
- from ibm_cloud_sdk_core.authenticators import ContainerAuthenticator
12
-
13
- # pylint: disable=line-too-long
14
- TEST_ACCESS_TOKEN_1 = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImhlbGxvIiwicm9sZSI6InVzZXIiLCJwZXJtaXNzaW9ucyI6WyJhZG1pbmlzdHJhdG9yIiwiZGVwbG95bWVudF9hZG1pbiJdLCJzdWIiOiJoZWxsbyIsImlzcyI6IkpvaG4iLCJhdWQiOiJEU1giLCJ1aWQiOiI5OTkiLCJpYXQiOjE1NjAyNzcwNTEsImV4cCI6MTU2MDI4MTgxOSwianRpIjoiMDRkMjBiMjUtZWUyZC00MDBmLTg2MjMtOGNkODA3MGI1NDY4In0.cIodB4I6CCcX8vfIImz7Cytux3GpWyObt9Gkur5g1QI'
15
- TEST_ACCESS_TOKEN_2 = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IjIzMDQ5ODE1MWMyMTRiNzg4ZGQ5N2YyMmI4NTQxMGE1In0.eyJ1c2VybmFtZSI6ImR1bW15Iiwicm9sZSI6IkFkbWluIiwicGVybWlzc2lvbnMiOlsiYWRtaW5pc3RyYXRvciIsIm1hbmFnZV9jYXRhbG9nIl0sInN1YiI6ImFkbWluIiwiaXNzIjoic3NzIiwiYXVkIjoic3NzIiwidWlkIjoic3NzIiwiaWF0IjozNjAwLCJleHAiOjE2MjgwMDcwODF9.zvUDpgqWIWs7S1CuKv40ERw1IZ5FqSFqQXsrwZJyfRM'
16
- TEST_REFRESH_TOKEN = 'Xj7Gle500MachEOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImhlbGxvIiwicm9sZSI6InVzZXIiLCJwZXJtaXNzaW9ucyI6WyJhZG1pbmlzdHJhdG9yIiwiZGVwbG95bWVudF9hZG1pbiJdLCJzdWIiOiJoZWxsbyIsImlzcyI6IkpvaG4iLCJhdWQiOiJEU1giLCJ1aWQiOiI5OTkiLCJpYXQiOjE1NjAyNzcwNTEsImV4cCI6MTU2MDI4MTgxOSwianRpIjoiMDRkMjBiMjUtZWUyZC00MDBmLTg2MjMtOGNkODA3MGI1NDY4In0.cIodB4I6CCcX8vfIImz7Cytux3GpWyObt9Gkur5g1QI'
17
- MOCK_IAM_PROFILE_NAME = 'iam-user-123'
18
- MOCK_CLIENT_ID = 'client-id-1'
19
- MOCK_CLIENT_SECRET = 'client-secret-1'
20
-
21
- cr_token_file = os.path.join(os.path.dirname(__file__), '../resources/cr-token.txt')
22
-
23
-
24
- def _get_current_time() -> int:
25
- return int(time.time())
26
-
27
-
28
- def mock_iam_response(func):
29
- """This is decorator function which extends `responses.activate`.
30
- This sets up all the mock response stuffs.
31
- """
32
- def callback(request):
33
- assert request.headers['Accept'] == 'application/json'
34
- assert request.headers['Content-Type'] == 'application/x-www-form-urlencoded'
35
-
36
- payload = parse_qs(request.body)
37
-
38
- assert payload['cr_token'][0] == 'cr-token-1'
39
- assert payload['grant_type'][0] == 'urn:ibm:params:oauth:grant-type:cr-token'
40
- assert payload.get('profile_name', [None])[0] or payload.get('profile_id', [None])[0]
41
-
42
- status_code = 200
43
-
44
- scope = payload.get('scope')[0] if payload.get('scope') else None
45
- if scope == 'send-second-token':
46
- access_token = TEST_ACCESS_TOKEN_2
47
- elif scope == 'status-bad-request':
48
- access_token = None
49
- status_code = 400
50
- elif scope == 'check-basic-auth':
51
- assert request.headers['Authorization'] == 'Basic Y2xpZW50LWlkLTE6Y2xpZW50LXNlY3JldC0x'
52
- access_token = TEST_ACCESS_TOKEN_1
53
- else:
54
- access_token = TEST_ACCESS_TOKEN_1
55
-
56
- response = json.dumps({
57
- 'access_token': access_token,
58
- 'token_type': 'Bearer',
59
- 'expires_in': 3600,
60
- 'expiration': _get_current_time()+3600,
61
- 'refresh_token': TEST_REFRESH_TOKEN,
62
- })
63
-
64
- return (status_code, {}, response)
65
-
66
- @responses.activate
67
- def wrapper():
68
- response = responses.CallbackResponse(
69
- method=responses.POST,
70
- url='https://iam.cloud.ibm.com/identity/token',
71
- callback=callback,
72
- )
73
-
74
- responses.add(response)
75
-
76
- func()
77
-
78
- return wrapper
79
-
80
-
81
- @mock_iam_response
82
- def test_request_token_auth_default():
83
- iam_url = "https://iam.cloud.ibm.com/identity/token"
84
-
85
- token_manager = ContainerTokenManager(
86
- cr_token_filename=cr_token_file,
87
- iam_profile_name=MOCK_IAM_PROFILE_NAME,
88
- )
89
- token_manager.request_token()
90
-
91
- assert len(responses.calls) == 1
92
- assert responses.calls[0].request.url == iam_url
93
- assert responses.calls[0].request.headers.get('Authorization') is None
94
- assert json.loads(responses.calls[0].response.text)['access_token'] == TEST_ACCESS_TOKEN_1
95
-
96
-
97
- @mock_iam_response
98
- def test_request_token_auth_in_ctor():
99
- default_auth_header = 'Basic Yng6Yng='
100
- token_manager = ContainerTokenManager(
101
- cr_token_filename=cr_token_file,
102
- iam_profile_name=MOCK_IAM_PROFILE_NAME,
103
- client_id='foo',
104
- client_secret='bar')
105
-
106
- token_manager.request_token()
107
-
108
- assert len(responses.calls) == 1
109
- assert responses.calls[0].request.headers['Authorization'] != default_auth_header
110
- assert json.loads(responses.calls[0].response.text)['access_token'] == TEST_ACCESS_TOKEN_1
111
- assert 'scope' not in responses.calls[0].response.request.body
112
-
113
-
114
- @mock_iam_response
115
- def test_request_token_auth_in_ctor_with_scope():
116
- default_auth_header = 'Basic Yng6Yng='
117
- token_manager = ContainerTokenManager(
118
- cr_token_filename=cr_token_file,
119
- iam_profile_name=MOCK_IAM_PROFILE_NAME,
120
- client_id='foo',
121
- client_secret='bar',
122
- scope='john snow')
123
-
124
- token_manager.request_token()
125
-
126
- assert len(responses.calls) == 1
127
- assert responses.calls[0].request.headers['Authorization'] != default_auth_header
128
- assert json.loads(responses.calls[0].response.text)['access_token'] == TEST_ACCESS_TOKEN_1
129
- assert 'scope=john+snow' in responses.calls[0].response.request.body
130
-
131
-
132
- def test_retrieve_cr_token_success():
133
- token_manager = ContainerTokenManager(
134
- cr_token_filename=cr_token_file,
135
- )
136
-
137
- cr_token = token_manager.retrieve_cr_token()
138
-
139
- assert cr_token == 'cr-token-1'
140
-
141
-
142
- def test_retrieve_cr_token_fail():
143
- token_manager = ContainerTokenManager(
144
- cr_token_filename='bogus-cr-token-file',
145
- )
146
-
147
- with pytest.raises(Exception) as err:
148
- token_manager.retrieve_cr_token()
149
-
150
- assert str(err.value) == 'Unable to retrieve the CR token value from file bogus-cr-token-file: [Errno 2] No such file or directory: \'bogus-cr-token-file\''
151
-
152
-
153
- @mock_iam_response
154
- def test_get_token_success():
155
- token_manager = ContainerTokenManager(
156
- cr_token_filename=cr_token_file,
157
- iam_profile_name=MOCK_IAM_PROFILE_NAME,
158
- )
159
-
160
- access_token = token_manager.access_token
161
- assert access_token is None
162
-
163
- access_token = token_manager.get_token()
164
- assert access_token == TEST_ACCESS_TOKEN_1
165
- assert token_manager.access_token == TEST_ACCESS_TOKEN_1
166
-
167
- # Verify the token manager return the cached value.
168
- # Before we call the `get_token` again, set the expiration and time.
169
- # This is necessary because we are using a fix JWT response.
170
- token_manager.expire_time = _get_current_time() + 3600
171
- token_manager.refresh_time = _get_current_time() + 3600
172
- token_manager.set_scope('send-second-token')
173
- access_token = token_manager.get_token()
174
- assert access_token == TEST_ACCESS_TOKEN_1
175
- assert token_manager.access_token == TEST_ACCESS_TOKEN_1
176
-
177
- # Force expiration to get the second token.
178
- token_manager.expire_time = _get_current_time() - 1
179
- access_token = token_manager.get_token()
180
- assert access_token == TEST_ACCESS_TOKEN_2
181
- assert token_manager.access_token == TEST_ACCESS_TOKEN_2
182
-
183
-
184
- @mock_iam_response
185
- def test_request_token_success():
186
- token_manager = ContainerTokenManager(
187
- cr_token_filename=cr_token_file,
188
- iam_profile_name=MOCK_IAM_PROFILE_NAME,
189
- )
190
-
191
- token_response = token_manager.request_token()
192
- assert token_response['access_token'] == TEST_ACCESS_TOKEN_1
193
-
194
-
195
- @mock_iam_response
196
- def test_authenticate_success():
197
- authenticator = ContainerAuthenticator(
198
- cr_token_filename=cr_token_file,
199
- iam_profile_name=MOCK_IAM_PROFILE_NAME)
200
-
201
- request = {'headers': {}}
202
-
203
- authenticator.authenticate(request)
204
- assert request['headers']['Authorization'] == 'Bearer ' + TEST_ACCESS_TOKEN_1
205
-
206
- # Verify the token manager return the cached value.
207
- # Before we call the `get_token` again, set the expiration and time.
208
- # This is necessary because we are using a fix JWT response.
209
- authenticator.token_manager.expire_time = _get_current_time() + 3600
210
- authenticator.token_manager.refresh_time = _get_current_time() + 3600
211
- authenticator.token_manager.set_scope('send-second-token')
212
- authenticator.authenticate(request)
213
- assert request['headers']['Authorization'] == 'Bearer ' + TEST_ACCESS_TOKEN_1
214
-
215
- # Force expiration to get the second token.
216
- authenticator.token_manager.expire_time = _get_current_time() - 1
217
- authenticator.authenticate(request)
218
- assert request['headers']['Authorization'] == 'Bearer ' + TEST_ACCESS_TOKEN_2
219
-
220
-
221
- @mock_iam_response
222
- def test_authenticate_fail_no_cr_token():
223
- authenticator = ContainerAuthenticator(
224
- cr_token_filename='bogus-cr-token-file',
225
- iam_profile_name=MOCK_IAM_PROFILE_NAME,
226
- url='https://bogus.iam.endpoint')
227
-
228
- request = {'headers': {}}
229
-
230
- with pytest.raises(Exception) as err:
231
- authenticator.authenticate(request)
232
-
233
- assert str(err.value) == 'Unable to retrieve the CR token value from file bogus-cr-token-file: [Errno 2] No such file or directory: \'bogus-cr-token-file\''
234
-
235
-
236
- @mock_iam_response
237
- def test_authenticate_fail_iam():
238
- authenticator = ContainerAuthenticator(
239
- cr_token_filename=cr_token_file,
240
- iam_profile_name=MOCK_IAM_PROFILE_NAME,
241
- scope='status-bad-request')
242
-
243
- request = {'headers': {}}
244
-
245
- with pytest.raises(ApiException) as err:
246
- authenticator.authenticate(request)
247
-
248
- assert str(err.value) == 'Error: Bad Request, Code: 400'
249
-
250
-
251
- @mock_iam_response
252
- def test_client_id_and_secret():
253
- token_manager = ContainerTokenManager(
254
- cr_token_filename=cr_token_file,
255
- iam_profile_name=MOCK_IAM_PROFILE_NAME,
256
- )
257
-
258
- token_manager.set_client_id_and_secret(MOCK_CLIENT_ID, MOCK_CLIENT_SECRET)
259
- token_manager.set_scope('check-basic-auth')
260
- access_token = token_manager.get_token()
261
- assert access_token == TEST_ACCESS_TOKEN_1
262
-
263
- @mock_iam_response
264
- def test_setter_methods():
265
- token_manager = ContainerTokenManager(
266
- cr_token_filename='bogus-cr-token-file',
267
- iam_profile_name=MOCK_IAM_PROFILE_NAME,
268
- )
269
-
270
- assert token_manager.iam_profile_id is None
271
- assert token_manager.iam_profile_name == MOCK_IAM_PROFILE_NAME
272
- assert token_manager.cr_token_filename == 'bogus-cr-token-file'
273
-
274
- token_manager.set_iam_profile_id('iam-id-123')
275
- token_manager.set_iam_profile_name(None)
276
- token_manager.set_cr_token_filename(cr_token_file)
277
-
278
- assert token_manager.iam_profile_id == 'iam-id-123'
279
- assert token_manager.iam_profile_name is None
280
- assert token_manager.cr_token_filename == cr_token_file
281
-
282
- access_token = token_manager.get_token()
283
- assert access_token == TEST_ACCESS_TOKEN_1
@@ -1,171 +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 CloudPakForDataAuthenticator, Authenticator
9
-
10
-
11
- def test_cp4d_authenticator():
12
- authenticator = CloudPakForDataAuthenticator(
13
- 'my_username', 'my_password', 'http://my_url')
14
- assert authenticator is not None
15
- assert authenticator.authentication_type() == Authenticator.AUTHTYPE_CP4D
16
- assert authenticator.token_manager.url == 'http://my_url/v1/authorize'
17
- assert authenticator.token_manager.username == 'my_username'
18
- assert authenticator.token_manager.password == 'my_password'
19
- assert authenticator.token_manager.disable_ssl_verification is False
20
- assert authenticator.token_manager.headers == {
21
- 'Content-Type': 'application/json'}
22
- assert authenticator.token_manager.proxies is None
23
-
24
- authenticator.set_disable_ssl_verification(True)
25
- assert authenticator.token_manager.disable_ssl_verification is True
26
-
27
- with pytest.raises(TypeError) as err:
28
- authenticator.set_headers('dummy')
29
- assert str(err.value) == 'headers must be a dictionary'
30
-
31
- authenticator.set_headers({'dummy': 'headers'})
32
- assert authenticator.token_manager.headers == {'dummy': 'headers'}
33
-
34
- with pytest.raises(TypeError) as err:
35
- authenticator.set_proxies('dummy')
36
- assert str(err.value) == 'proxies must be a dictionary'
37
-
38
- authenticator.set_proxies({'dummy': 'proxies'})
39
- assert authenticator.token_manager.proxies == {'dummy': 'proxies'}
40
-
41
-
42
- def test_disable_ssl_verification():
43
- authenticator = CloudPakForDataAuthenticator(
44
- 'my_username', 'my_password', 'http://my_url', disable_ssl_verification=True)
45
- assert authenticator.token_manager.disable_ssl_verification is True
46
-
47
- authenticator.set_disable_ssl_verification(False)
48
- assert authenticator.token_manager.disable_ssl_verification is False
49
-
50
-
51
- def test_invalid_disable_ssl_verification_type():
52
- with pytest.raises(TypeError) as err:
53
- authenticator = CloudPakForDataAuthenticator(
54
- 'my_username', 'my_password', 'http://my_url', disable_ssl_verification='True')
55
- assert str(err.value) == 'disable_ssl_verification must be a bool'
56
-
57
- authenticator = CloudPakForDataAuthenticator(
58
- 'my_username', 'my_password', 'http://my_url')
59
- assert authenticator.token_manager.disable_ssl_verification is False
60
-
61
- with pytest.raises(TypeError) as err:
62
- authenticator.set_disable_ssl_verification('True')
63
- assert str(err.value) == 'status must be a bool'
64
-
65
-
66
- def test_cp4d_authenticator_validate_failed():
67
- with pytest.raises(ValueError) as err:
68
- CloudPakForDataAuthenticator('my_username', None, 'my_url')
69
- assert str(
70
- err.value) == 'Exactly one of `apikey` or `password` must be specified.'
71
-
72
- with pytest.raises(ValueError) as err:
73
- CloudPakForDataAuthenticator(username='my_username', url='my_url')
74
- assert str(
75
- err.value) == 'Exactly one of `apikey` or `password` must be specified.'
76
-
77
- with pytest.raises(ValueError) as err:
78
- CloudPakForDataAuthenticator(
79
- 'my_username', None, 'my_url', apikey=None)
80
- assert str(
81
- err.value) == 'Exactly one of `apikey` or `password` must be specified.'
82
-
83
- with pytest.raises(ValueError) as err:
84
- CloudPakForDataAuthenticator(None, 'my_password', 'my_url')
85
- assert str(err.value) == 'The username shouldn\'t be None.'
86
-
87
- with pytest.raises(ValueError) as err:
88
- CloudPakForDataAuthenticator(password='my_password', url='my_url')
89
- assert str(err.value) == 'The username shouldn\'t be None.'
90
-
91
- with pytest.raises(ValueError) as err:
92
- CloudPakForDataAuthenticator('my_username', 'my_password', None)
93
- assert str(err.value) == 'The url shouldn\'t be None.'
94
-
95
- with pytest.raises(ValueError) as err:
96
- CloudPakForDataAuthenticator(
97
- username='my_username', password='my_password')
98
- assert str(err.value) == 'The url shouldn\'t be None.'
99
-
100
- with pytest.raises(ValueError) as err:
101
- CloudPakForDataAuthenticator('{my_username}', 'my_password', 'my_url')
102
- assert str(err.value) == 'The username and password shouldn\'t start or end with curly brackets or quotes. '\
103
- 'Please remove any surrounding {, }, or \" characters.'
104
-
105
- with pytest.raises(ValueError) as err:
106
- CloudPakForDataAuthenticator('my_username', '{my_password}', 'my_url')
107
- assert str(err.value) == 'The username and password shouldn\'t start or end with curly brackets or quotes. '\
108
- 'Please remove any surrounding {, }, or \" characters.'
109
-
110
- with pytest.raises(ValueError) as err:
111
- CloudPakForDataAuthenticator('my_username', 'my_password', '{my_url}')
112
- assert str(err.value) == 'The url shouldn\'t start or end with curly brackets or quotes. '\
113
- 'Please remove any surrounding {, }, or \" characters.'
114
-
115
-
116
- @responses.activate
117
- def test_get_token():
118
- url = "https://test"
119
- access_token_layout = {
120
- "username": "dummy",
121
- "role": "Admin",
122
- "permissions": [
123
- "administrator",
124
- "manage_catalog"
125
- ],
126
- "sub": "admin",
127
- "iss": "sss",
128
- "aud": "sss",
129
- "uid": "sss",
130
- "iat": 1559324664,
131
- "exp": 1559324664
132
- }
133
-
134
- access_token = jwt.encode(access_token_layout,
135
- 'secret', algorithm='HS256',
136
- headers={'kid': '230498151c214b788dd97f22b85410a5'})
137
- response = {
138
- "token": access_token,
139
- "token_type": "Bearer",
140
- "expires_in": 3600,
141
- "expiration": 1524167011,
142
- "refresh_token": "jy4gl91BQ"
143
- }
144
- responses.add(responses.POST, url + '/v1/authorize',
145
- body=json.dumps(response), status=200)
146
-
147
- auth_headers = {'Host': 'cp4d.cloud.ibm.com:443'}
148
- authenticator = CloudPakForDataAuthenticator(
149
- 'my_username', 'my_password', url + '/v1/authorize',
150
- headers=auth_headers)
151
-
152
- # Simulate an SDK API request that needs to be authenticated.
153
- request = {'headers': {}}
154
-
155
- # Trigger the "get token" processing to obtain the access token and add to the "SDK request".
156
- authenticator.authenticate(request)
157
-
158
- # Verify that the "authenticate()" method added the Authorization header
159
- assert request['headers']['Authorization'] is not None
160
-
161
- # Verify that the "get token" call contained the Host header.
162
- assert responses.calls[0].request.headers.get(
163
- 'Host') == 'cp4d.cloud.ibm.com:443'
164
-
165
- # Ensure '/v1/authorize' is added to the url if omitted
166
- authenticator = CloudPakForDataAuthenticator(
167
- 'my_username', 'my_password', url)
168
-
169
- request = {'headers': {}}
170
- authenticator.authenticate(request)
171
- assert request['headers']['Authorization'] is not None
@@ -1,56 +0,0 @@
1
- # pylint: disable=missing-docstring
2
- import json
3
- import time
4
-
5
- import jwt
6
- import responses
7
-
8
- from ibm_cloud_sdk_core import CP4DTokenManager
9
-
10
-
11
- @responses.activate
12
- def test_request_token():
13
- url = "https://test"
14
- now = time.time()
15
- access_token_layout = {
16
- "username": "dummy",
17
- "role": "Admin",
18
- "permissions": [
19
- "administrator",
20
- "manage_catalog"
21
- ],
22
- "sub": "admin",
23
- "iss": "sss",
24
- "aud": "sss",
25
- "uid": "sss",
26
- "iat": now,
27
- "exp": now + 3600
28
- }
29
-
30
- access_token = jwt.encode(access_token_layout,
31
- 'secret', algorithm='HS256',
32
- headers={'kid': '230498151c214b788dd97f22b85410a5'})
33
- response = {
34
- "token": access_token,
35
- }
36
- responses.add(responses.POST, url + '/v1/authorize', body=json.dumps(response), status=200)
37
-
38
- token_manager = CP4DTokenManager("username", "password", url)
39
- token_manager.set_disable_ssl_verification(True)
40
- token = token_manager.get_token()
41
-
42
- assert len(responses.calls) == 1
43
- assert responses.calls[0].request.url == url + '/v1/authorize'
44
- assert token == access_token
45
-
46
- token_manager = CP4DTokenManager("username", "password", url + '/v1/authorize')
47
- token = token_manager.get_token()
48
- assert len(responses.calls) == 2
49
- assert responses.calls[1].request.url == url + '/v1/authorize'
50
- assert token == access_token
51
-
52
- token_manager = CP4DTokenManager(username="username", apikey="fake_api_key", url=url + '/v1/authorize')
53
- token = token_manager.get_token()
54
- assert len(responses.calls) == 3
55
- assert responses.calls[2].request.url == url + '/v1/authorize'
56
- assert token == access_token