24
24
from .version import __version__
25
25
from .utils import has_bad_first_or_last_char , remove_null_values , cleanup_values
26
26
from .iam_token_manager import IAMTokenManager
27
+ from .icp4d_token_manager import ICP4DTokenManager
27
28
from .detailed_response import DetailedResponse
28
29
from .api_exception import ApiException
29
30
@@ -45,19 +46,21 @@ class BaseService(object):
45
46
ICP_PREFIX = 'icp-'
46
47
APIKEY = 'apikey'
47
48
IAM_ACCESS_TOKEN = 'iam_access_token'
49
+ ICP4D_ACCESS_TOKEN = 'icp4d_access_token'
48
50
URL = 'url'
49
51
USERNAME = 'username'
50
52
PASSWORD = 'password'
51
53
IAM_APIKEY = 'iam_apikey'
52
54
IAM_URL = 'iam_url'
55
+ ICP4D_URL = 'icp4d_url'
53
56
APIKEY_DEPRECATION_MESSAGE = 'Authenticating with apikey is deprecated. Move to using Identity and Access Management (IAM) authentication.'
54
57
DEFAULT_CREDENTIALS_FILE_NAME = 'ibm-credentials.env'
55
58
SDK_NAME = 'ibm-python-sdk-core'
56
59
57
60
def __init__ (self , vcap_services_name , url , username = None , password = None ,
58
- use_vcap_services = True , api_key = None ,
59
- iam_apikey = None , iam_access_token = None , iam_url = None , iam_client_id = None , iam_client_secret = None ,
60
- display_name = None ):
61
+ use_vcap_services = True , api_key = None , iam_apikey = None , iam_url = None ,
62
+ iam_access_token = None , iam_client_id = None , iam_client_secret = None ,
63
+ display_name = None , icp4d_access_token = None , icp4d_url = None , authentication_type = None ):
61
64
"""
62
65
It loads credentials with the following preference:
63
66
1) Credentials explicitly set in the request
@@ -66,41 +69,56 @@ def __init__(self, vcap_services_name, url, username=None, password=None,
66
69
"""
67
70
self .url = url
68
71
self .http_config = {}
72
+ self .authentication_type = authentication_type .lower () if authentication_type else None
69
73
self .jar = None
70
- self .api_key = None
71
- self .username = None
72
- self .password = None
73
- self .default_headers = None
74
- self .iam_apikey = None
75
- self .iam_access_token = None
76
- self .iam_url = None
77
- self .iam_client_id = None
78
- self .iam_client_secret = None
74
+ self .api_key = api_key
75
+ self .username = username
76
+ self .password = password
77
+ self .iam_apikey = iam_apikey
78
+ self .iam_access_token = iam_access_token
79
+ self .iam_url = iam_url
80
+ self .iam_client_id = iam_client_id
81
+ self .iam_client_secret = iam_client_secret
82
+ self .icp4d_access_token = icp4d_access_token
83
+ self .icp4d_url = icp4d_url
79
84
self .token_manager = None
85
+ self .default_headers = None
80
86
self .verify = None # Indicates whether to ignore verifying the SSL certification
81
87
82
- if has_bad_first_or_last_char (self .url ):
83
- raise ValueError ('The URL shouldn\' t start or end with curly brackets or quotes. '
84
- 'Be sure to remove any {} and \" characters surrounding your URL' )
88
+ self ._check_credentials ()
85
89
86
90
self .set_user_agent_header (self .build_user_agent ())
87
91
88
92
# 1. Credentials are passed in constructor
89
- if api_key is not None :
90
- if api_key .startswith (self .ICP_PREFIX ):
91
- self .set_username_and_password (self .APIKEY , api_key )
92
- else :
93
- self .set_token_manager (api_key , iam_access_token , iam_url , iam_client_id , iam_client_secret )
94
- elif username is not None and password is not None :
95
- if username is self .APIKEY and not password .startswith (self .ICP_PREFIX ):
96
- self .set_token_manager (password , iam_access_token , iam_url , iam_client_id , iam_client_secret )
97
- else :
98
- self .set_username_and_password (username , password )
99
- elif iam_access_token is not None or iam_apikey is not None :
100
- if iam_apikey and iam_apikey .startswith (self .ICP_PREFIX ):
101
- self .set_username_and_password (self .APIKEY , iam_apikey )
102
- else :
103
- self .set_token_manager (iam_apikey , iam_access_token , iam_url , iam_client_id , iam_client_secret )
93
+ if self .authentication_type == 'iam' or self ._has_iam_credentials (self .iam_apikey , self .iam_access_token ) or self ._has_iam_credentials (self .api_key , self .iam_access_token ):
94
+ self .token_manager = IAMTokenManager (self .iam_apikey or self .api_key or self .password ,
95
+ self .iam_access_token ,
96
+ self .iam_url ,
97
+ self .iam_client_id ,
98
+ self .iam_client_secret )
99
+ self .iam_apikey = self .iam_apikey or self .api_key or self .password
100
+ elif self ._uses_basic_for_iam (self .username , self .password ):
101
+ self .token_manager = IAMTokenManager (self .password ,
102
+ self .iam_access_token ,
103
+ self .iam_url ,
104
+ self .iam_client_id ,
105
+ self .iam_client_secret )
106
+ self .iam_apikey = self .password
107
+ self .username = None
108
+ self .password = None
109
+ elif self ._is_for_icp4d (self .authentication_type , self .icp4d_access_token ):
110
+ if self .icp4d_access_token is None and self .icp4d_url is None :
111
+ raise Exception ('The icp4d_url is mandatory for ICP4D.' )
112
+ self .token_manager = ICP4DTokenManager (self .icp4d_url ,
113
+ self .username ,
114
+ self .password ,
115
+ self .icp4d_access_token )
116
+ elif self ._is_for_icp (self .api_key ) or self ._is_for_icp (self .iam_apikey ):
117
+ self .username = self .APIKEY
118
+ self .password = self .api_key or self .iam_apikey
119
+ elif self .token_manager is None and self ._has_basic_credentials (username , password ):
120
+ self .username = username
121
+ self .password = password
104
122
105
123
# 2. Credentials from credential file
106
124
if display_name and not self .username and not self .token_manager :
@@ -124,6 +142,10 @@ def __init__(self, vcap_services_name, url, username=None, password=None,
124
142
self .set_iam_apikey (self .vcap_service_credentials .get (self .IAM_APIKEY ))
125
143
if self .IAM_ACCESS_TOKEN in self .vcap_service_credentials :
126
144
self .set_iam_access_token (self .vcap_service_credentials .get (self .IAM_ACCESS_TOKEN ))
145
+ if self .ICP4D_URL in self .vcap_service_credentials :
146
+ self .icp4d_url = self .vcap_service_credentials .get (self .ICP4D_URL )
147
+ if self .ICP4D_ACCESS_TOKEN in self .vcap_service_credentials :
148
+ self .set_icp4d_access_token (self .vcap_service_credentials .get (self .ICP4D_ACCESS_TOKEN ))
127
149
128
150
if (self .username is None or self .password is None ) and self .token_manager is None :
129
151
raise ValueError (
@@ -183,8 +205,45 @@ def _load_from_vcap_services(self, service_name):
183
205
else :
184
206
return None
185
207
208
+ def _is_for_icp (self , credential = None ):
209
+ return credential and credential .startswith (self .ICP_PREFIX )
210
+
211
+ def _is_for_icp4d (self , authentication_type , icp4d_access_token = None ):
212
+ return authentication_type == 'icp4d' or icp4d_access_token
213
+
214
+ def _has_basic_credentials (self , username , password ):
215
+ return username and password and not self ._uses_basic_for_iam (username , password )
216
+
217
+ def _has_iam_credentials (self , iam_apikey , iam_access_token ):
218
+ return (iam_apikey or iam_access_token ) and not self ._is_for_icp (iam_apikey )
219
+
220
+ def _uses_basic_for_iam (self , username , password ):
221
+ """
222
+ Returns true if the user provides basic auth creds with the intention
223
+ of using IAM auth
224
+ """
225
+ return username and password and username == self .APIKEY and not self ._is_for_icp (password )
226
+
227
+ def _has_bad_first_or_last_char (self , str ):
228
+ return str is not None and (str .startswith ('{' ) or str .startswith ('"' ) or str .endswith ('}' ) or str .endswith ('"' ))
229
+
230
+ def _check_credentials (self ):
231
+ credentials_to_check = {
232
+ 'URL' : self .url ,
233
+ 'username' : self .username ,
234
+ 'password' : self .password ,
235
+ 'credentials' : self .iam_apikey
236
+ }
237
+
238
+ for key in credentials_to_check :
239
+ if self ._has_bad_first_or_last_char (credentials_to_check .get (key )):
240
+ raise ValueError ('The ' + key + ' shouldn\' t start or end with curly brackets or quotes. '
241
+ 'Be sure to remove any {} and \" characters surrounding your ' + key )
242
+
186
243
def disable_SSL_verification (self ):
187
244
self .verify = False
245
+ if self .token_manager is not None :
246
+ self .token_manager .disable_SSL_verification (True )
188
247
189
248
def set_username_and_password (self , username , password ):
190
249
if has_bad_first_or_last_char (username ):
@@ -198,20 +257,6 @@ def set_username_and_password(self, username, password):
198
257
self .password = password
199
258
self .jar = CookieJar ()
200
259
201
- def set_token_manager (self , iam_apikey = None , iam_access_token = None , iam_url = None ,
202
- iam_client_id = None , iam_client_secret = None ):
203
- if has_bad_first_or_last_char (iam_apikey ):
204
- raise ValueError ('The credentials shouldn\' t start or end with curly brackets or quotes. '
205
- 'Be sure to remove any {} and \" characters surrounding your credentials' )
206
-
207
- self .token_manager = IAMTokenManager (iam_apikey , iam_access_token , iam_url , iam_client_id , iam_client_secret )
208
- self .iam_apikey = iam_apikey
209
- self .iam_access_token = iam_access_token
210
- self .iam_url = iam_url
211
- self .iam_client_id = iam_client_id
212
- self .iam_client_secret = iam_client_secret
213
- self .jar = CookieJar ()
214
-
215
260
def set_iam_access_token (self , iam_access_token ):
216
261
if self .token_manager :
217
262
self .token_manager .set_access_token (iam_access_token )
@@ -220,6 +265,16 @@ def set_iam_access_token(self, iam_access_token):
220
265
self .iam_access_token = iam_access_token
221
266
self .jar = CookieJar ()
222
267
268
+ def set_icp4d_access_token (self , icp4d_access_token ):
269
+ if self .token_manager :
270
+ self .token_manager .set_access_token (icp4d_access_token )
271
+ else :
272
+ if self .icp4d_url is None :
273
+ raise Exception ('The icp4d_url is mandatory for ICP4D.' )
274
+ self .token_manager = ICP4DTokenManager (self .icp4d_url , access_token = icp4d_access_token )
275
+ self .icp4d_access_token = icp4d_access_token
276
+ self .jar = CookieJar ()
277
+
223
278
def set_iam_url (self , iam_url ):
224
279
if self .token_manager :
225
280
self .token_manager .set_iam_url (iam_url )
@@ -313,7 +368,7 @@ def request(self, method, url, accept_json=False, headers=None,
313
368
if self .token_manager :
314
369
access_token = self .token_manager .get_token ()
315
370
headers ['Authorization' ] = '{0} {1}' .format (self .BEARER , access_token )
316
- if self .username and self .password :
371
+ elif self .username and self .password :
317
372
auth = (self .username , self .password )
318
373
319
374
# Use a one minute timeout when our caller doesn't give a timeout.
0 commit comments