diff --git a/SoftLayer/API.py b/SoftLayer/API.py index ea119a4b1..cff277286 100644 --- a/SoftLayer/API.py +++ b/SoftLayer/API.py @@ -46,7 +46,7 @@ 'raw_headers', 'limit', 'offset', - 'verify', + 'verify' )) @@ -182,7 +182,7 @@ def employee_client(username=None, verify=None, config_file=config_file) - url = settings.get('endpoint_url') + url = settings.get('endpoint_url', '') verify = settings.get('verify', True) if 'internal' not in url: @@ -374,7 +374,6 @@ def call(self, service, method, *args, **kwargs): request.url = self.settings['softlayer'].get('endpoint_url') if kwargs.get('verify') is not None: request.verify = kwargs.get('verify') - if self.auth: request = self.auth.get_request(request) @@ -495,7 +494,7 @@ def __setAuth(self, auth=None): """Prepares the authentication property""" if auth is None: auth_cert = self.settings['softlayer'].get('auth_cert') - serv_cert = self.settings['softlayer'].get('server_cert', None) + serv_cert = self.settings['softlayer'].get('verify', True) auth = slauth.X509Authentication(auth_cert, serv_cert) self.auth = auth @@ -712,7 +711,7 @@ def authenticate_with_internal(self, username, password, security_token=None): if len(security_token) != 6: raise exceptions.SoftLayerAPIError("Invalid security token: {}".format(security_token)) - auth_result = self.call('SoftLayer_User_Employee', 'performExternalAuthentication', + auth_result = self.call('SoftLayer_User_Employee', 'getEncryptedSessionToken', username, password, security_token) self.settings['softlayer']['access_token'] = auth_result['hash'] diff --git a/SoftLayer/CLI/login.py b/SoftLayer/CLI/login.py index 8ee981979..d37ea043c 100644 --- a/SoftLayer/CLI/login.py +++ b/SoftLayer/CLI/login.py @@ -4,7 +4,6 @@ import click -from SoftLayer.API import employee_client from SoftLayer.CLI.command import SLCommand as SLCommand from SoftLayer.CLI import environment from SoftLayer import config @@ -30,16 +29,15 @@ def cli(env): username = settings.get('username') or os.environ.get('SLCLI_USER', None) password = os.environ.get('SLCLI_PASSWORD', '') yubi = None - client = employee_client(config_file=env.config_file) # Might already be logged in, try and refresh token if settings.get('access_token') and settings.get('userid'): - client.authenticate_with_hash(settings.get('userid'), settings.get('access_token')) + env.client.authenticate_with_hash(settings.get('userid'), settings.get('access_token')) try: emp_id = settings.get('userid') - client.call('SoftLayer_User_Employee', 'getObject', id=emp_id, mask="mask[id,username]") - client.refresh_token(emp_id, settings.get('access_token')) - client.call('SoftLayer_User_Employee', 'refreshEncryptedToken', settings.get('access_token'), id=emp_id) + env.client.call('SoftLayer_User_Employee', 'getObject', id=emp_id, mask="mask[id,username]") + env.client.refresh_token(emp_id, settings.get('access_token')) + env.client.call('SoftLayer_User_Employee', 'refreshEncryptedToken', settings.get('access_token'), id=emp_id) config_settings['softlayer'] = settings config.write_config(config_settings, env.config_file) @@ -52,13 +50,12 @@ def cli(env): click.echo("URL: {}".format(url)) if username is None: username = input("Username: ") - click.echo("Username: {}".format(username)) if not password: - password = env.getpass("Password: ") - click.echo("Password: {}".format(censor_password(password))) + password = env.getpass("Password: ", default="") yubi = input("Yubi: ") + try: - result = client.authenticate_with_internal(username, password, str(yubi)) + result = env.client.authenticate_with_internal(username, password, str(yubi)) print(result) # pylint: disable=broad-exception-caught except Exception as e: diff --git a/SoftLayer/auth.py b/SoftLayer/auth.py index 8698249ae..cdbbf8526 100644 --- a/SoftLayer/auth.py +++ b/SoftLayer/auth.py @@ -5,7 +5,7 @@ :license: MIT, see LICENSE for more details. """ - +import os __all__ = [ 'BasicAuthentication', @@ -89,7 +89,7 @@ def get_request(self, request): return request def __repr__(self): - return "BasicAuthentication(username=%r)" % self.username + return f"BasicAuthentication(username={self.username})" class BasicHTTPAuthentication(AuthenticationBase): @@ -110,7 +110,7 @@ def get_request(self, request): return request def __repr__(self): - return "BasicHTTPAuthentication(username=%r)" % self.username + return f"BasicHTTPAuthentication(username={self.username}" class BearerAuthentication(AuthenticationBase): @@ -149,7 +149,7 @@ class X509Authentication(AuthenticationBase): """ def __init__(self, cert, ca_cert): - self.cert = cert + self.cert = os.path.expanduser(cert) self.ca_cert = ca_cert def get_request(self, request): diff --git a/SoftLayer/transports/rest.py b/SoftLayer/transports/rest.py index 9d2a13269..2e2be1986 100644 --- a/SoftLayer/transports/rest.py +++ b/SoftLayer/transports/rest.py @@ -76,6 +76,9 @@ def __call__(self, request): request.params = params + # This handles any edge cases on the REST api. + request.special_rest_params() + auth = None if request.transport_user: auth = requests.auth.HTTPBasicAuth( @@ -110,7 +113,6 @@ def __call__(self, request): # Prefer the request setting, if it's not None if request.verify is None: request.verify = self.verify - try: resp = self.client.request(method, request.url, auth=auth, @@ -163,6 +165,8 @@ def print_reproduceable(request): :param request request: Request object """ + # This handles any edge cases on the REST api. + request.special_rest_params() command = "curl -u $SL_USER:$SL_APIKEY -X {method} -H {headers} {data} '{uri}'" method = REST_SPECIAL_METHODS.get(request.method) diff --git a/SoftLayer/transports/transport.py b/SoftLayer/transports/transport.py index 9496be50b..e90249057 100644 --- a/SoftLayer/transports/transport.py +++ b/SoftLayer/transports/transport.py @@ -44,6 +44,9 @@ def __init__(self): #: API Parameters. self.args = tuple() + #: URL Parameters, used for the REST Transport + self.params = None + #: API headers, used for authentication, masks, limits, offsets, etc. self.headers = {} @@ -103,13 +106,27 @@ def __repr__(self): pretty_filter = self.filter clean_args = self.args # Passwords can show up here, so censor them before logging. - if self.method in ["performExternalAuthentication", "refreshEncryptedToken", "getPortalLoginToken"]: + if self.method in ["performExternalAuthentication", "refreshEncryptedToken", + "getPortalLoginToken", "getEncryptedSessionToken"]: clean_args = "*************" param_string = (f"id={self.identifier}, mask='{pretty_mask}', filter='{pretty_filter}', args={clean_args}, " f"limit={self.limit}, offset={self.offset}") return "{service}::{method}({params})".format( service=self.service, method=self.method, params=param_string) + def special_rest_params(self): + """This method is to handle the edge case of SoftLayer_User_Employee::getEncryptedSessionToken + + Added this method here since it was a little easier to change the data as needed this way. + """ + if self.method == "getEncryptedSessionToken" and self.service == "SoftLayer_User_Employee": + if len(self.args) < 3: + return + self.params = {"remoteToken": self.args[2]} + self.transport_user = self.args[0] + self.transport_password = self.args[1] + self.args = [] + class SoftLayerListResult(list): """A SoftLayer API list result.""" diff --git a/docs/requirements.txt b/docs/requirements.txt index b599248f1..894d7abbc 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ sphinx_rtd_theme==3.0.2 -sphinx==8.2.1 +sphinx==8.2.3 sphinx-click==6.0.0 click prettytable