1010import logging
1111import requests
1212import warnings
13-
13+ import time
1414
1515from SoftLayer import auth as slauth
1616from SoftLayer import config
1717from SoftLayer import consts
1818from SoftLayer import exceptions
1919from SoftLayer import transports
2020
21-
21+ from pprint import pprint as pp
2222LOGGER = logging .getLogger (__name__ )
2323API_PUBLIC_ENDPOINT = consts .API_PUBLIC_ENDPOINT
2424API_PRIVATE_ENDPOINT = consts .API_PRIVATE_ENDPOINT
@@ -402,29 +402,63 @@ def authenticate_with_password(self, username, password):
402402 self .settings ['softlayer' ]['access_token' ] = tokens ['access_token' ]
403403 self .settings ['softlayer' ]['refresh_token' ] = tokens ['refresh_token' ]
404404
405- config .write_config (self .settings )
405+ config .write_config (self .settings , self .config_file )
406+ self .auth = slauth .BearerAuthentication ('' , tokens ['access_token' ], tokens ['refresh_token' ])
407+
408+ return tokens
409+
410+ def authenticate_with_passcode (self , passcode ):
411+ """Performs IBM IAM SSO Authentication
412+
413+ :param string passcode: your IBMid password
414+ """
415+
416+ iam_client = requests .Session ()
417+
418+ headers = {
419+ 'Content-Type' : 'application/x-www-form-urlencoded' ,
420+ 'User-Agent' : consts .USER_AGENT ,
421+ 'Accept' : 'application/json'
422+ }
423+ data = {
424+ 'grant_type' : 'urn:ibm:params:oauth:grant-type:passcode' ,
425+ 'passcode' : passcode ,
426+ 'response_type' : 'cloud_iam'
427+ }
428+
429+ response = iam_client .request (
430+ 'POST' ,
431+ 'https://iam.cloud.ibm.com/identity/token' ,
432+ data = data ,
433+ headers = headers ,
434+ auth = requests .auth .HTTPBasicAuth ('bx' , 'bx' )
435+ )
436+ if response .status_code != 200 :
437+ LOGGER .error ("Unable to login: {}" .format (response .text ))
438+
439+ response .raise_for_status ()
440+
441+ tokens = json .loads (response .text )
442+ self .settings ['softlayer' ]['access_token' ] = tokens ['access_token' ]
443+ self .settings ['softlayer' ]['refresh_token' ] = tokens ['refresh_token' ]
444+ a_expire = time .strftime ('%Y-%m-%d %H:%M:%S' , time .localtime (tokens ['expiration' ]))
445+ r_expire = time .strftime ('%Y-%m-%d %H:%M:%S' , time .localtime (tokens ['refresh_token_expiration' ]))
446+ LOGGER .warning ("Tokens retrieved, expires at {}, Refresh expires at {}" .format (a_expire , r_expire ))
447+ config .write_config (self .settings , self .config_file )
406448 self .auth = slauth .BearerAuthentication ('' , tokens ['access_token' ], tokens ['refresh_token' ])
449+
407450 return tokens
408451
409- def authenticate_with_iam_token (self , a_token , r_token ):
452+ def authenticate_with_iam_token (self , a_token , r_token = None ):
410453 """Authenticates to the SL API with an IAM Token
411454
412455 :param string a_token: Access token
413456 :param string r_token: Refresh Token, to be used if Access token is expired.
414457 """
415- self .auth = slauth .BearerAuthentication ('' , a_token )
416- user = None
417- try :
418- user = self .call ('Account' , 'getCurrentUser' )
419- except exceptions .SoftLayerAPIError as ex :
420- if ex .faultCode == 401 :
421- LOGGER .warning ("Token has expired, trying to refresh." )
422- # self.refresh_iam_token(r_token)
423- else :
424- raise ex
425- return user
458+ self .auth = slauth .BearerAuthentication ('' , a_token , r_token )
426459
427- def refresh_iam_token (self , r_token ):
460+ def refresh_iam_token (self , r_token , account_id = None , ims_account = None ):
461+ """Refreshes the IAM Token, will default to values in the config file"""
428462 iam_client = requests .Session ()
429463
430464 headers = {
@@ -438,11 +472,15 @@ def refresh_iam_token(self, r_token):
438472 'response_type' : 'cloud_iam'
439473 }
440474
441- config = self .settings .get ('softlayer' )
442- if config .get ('account' , False ):
443- data ['account' ] = account
444- if config .get ('ims_account' , False ):
445- data ['ims_account' ] = ims_account
475+ sl_config = self .settings ['softlayer' ]
476+
477+ if account_id is None and sl_config .get ('account_id' , False ):
478+ account_id = sl_config .get ('account_id' )
479+ if ims_account is None and sl_config .get ('ims_account' , False ):
480+ ims_account = sl_config .get ('ims_account' )
481+
482+ data ['account' ] = account_id
483+ data ['ims_account' ] = ims_account
446484
447485 response = iam_client .request (
448486 'POST' ,
@@ -451,30 +489,37 @@ def refresh_iam_token(self, r_token):
451489 headers = headers ,
452490 auth = requests .auth .HTTPBasicAuth ('bx' , 'bx' )
453491 )
492+
493+ if response .status_code != 200 :
494+ LOGGER .warning ("Unable to refresh IAM Token. {}" .format (response .text ))
495+
454496 response .raise_for_status ()
455-
456- LOGGER .warning ("Successfully refreshed Tokens, saving to config" )
497+
457498 tokens = json .loads (response .text )
499+ a_expire = time .strftime ('%Y-%m-%d %H:%M:%S' , time .localtime (tokens ['expiration' ]))
500+ r_expire = time .strftime ('%Y-%m-%d %H:%M:%S' , time .localtime (tokens ['refresh_token_expiration' ]))
501+ LOGGER .warning ("Successfully refreshed Tokens. Expires at {}, Refresh expires at {}" .format (a_expire , r_expire ))
502+
458503 self .settings ['softlayer' ]['access_token' ] = tokens ['access_token' ]
459504 self .settings ['softlayer' ]['refresh_token' ] = tokens ['refresh_token' ]
460- config .write_config (self .settings )
505+ config .write_config (self .settings , self .config_file )
506+ self .auth = slauth .BearerAuthentication ('' , tokens ['access_token' ])
461507 return tokens
462-
463-
464508
465509 def call (self , service , method , * args , ** kwargs ):
466510 """Handles refreshing IAM tokens in case of a HTTP 401 error"""
467511 try :
468512 return super ().call (service , method , * args , ** kwargs )
469513 except exceptions .SoftLayerAPIError as ex :
514+
470515 if ex .faultCode == 401 :
471- LOGGER .warning ("Token has expired, trying to refresh." )
472- self .refresh_iam_token (r_token )
473- return super ().call (service , method , * args , ** kwargs )
516+ LOGGER .warning ("Token has expired, trying to refresh. {}" .format (ex .faultString ))
517+ # self.refresh_iam_token(r_token)
518+ # return super().call(service, method, *args, **kwargs)
519+ return ex
474520 else :
475521 raise ex
476522
477-
478523 def __repr__ (self ):
479524 return "IAMClient(transport=%r, auth=%r)" % (self .transport , self .auth )
480525
0 commit comments