diff --git a/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/oidc_http_client.py b/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/oidc_http_client.py index 66faf0c9e66950ce188278b8d32077856bac31a3..4539d77c1403b75c4e84ef267196cd9838df20d7 100644 --- a/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/oidc_http_client.py +++ b/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/oidc_http_client.py @@ -7,12 +7,22 @@ import json class OIDCHTTPClient(HTTPClient): """ Class which uses the BBP oidc client to do http calls """ - def __init__(self, oidc_username): + def __init__(self, oidc_username=None, oidc_token=None): """ - :param oidc_username: The HBP oidc username + :param oidc_username: (optional) The HBP oidc username, required if the token is omitted + :param oidc_token: (optional) The HBP oidc token, required if the username is omitted """ from bbp_client.oidc.client import BBPOIDCClient - self.__oidc_client = BBPOIDCClient.implicit_auth(oidc_username) + if not oidc_username and not oidc_token: + raise ValueError( + "You need to specify either an oidc_username" + " or a token in order to instantiate OIDCHTTPClient." + ) + + if oidc_username: + self.__oidc_client = BBPOIDCClient.implicit_auth(oidc_username) + elif oidc_token: + self.__oidc_client = BBPOIDCClient.bearer_auth(oauth_url=None, token=oidc_token) self.__headers = None def get(self, url): diff --git a/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/tests/test_virtual_coach.py b/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/tests/test_virtual_coach.py index 9f25da1d30afe1d1b1eec8f86fd564a1446de88b..f85c5413273717b6bf83530dfef0e34dbdcbf828 100644 --- a/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/tests/test_virtual_coach.py +++ b/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/tests/test_virtual_coach.py @@ -120,13 +120,20 @@ class TestVirtualCoach(unittest.TestCase): self._mock_exp_list_cloned = [{'uuid': 'MockExperiment1_0', 'name': 'MockExperiment1_0'}, {'uuid': 'MockExperiment2_0', 'name': 'MockExperiment2_0'}] + + def test_init_asserts_no_password(self): + # invalid oidc token + self.assertRaises(AssertionError, VirtualCoach, oidc_token=123) + + # invalid environment + self.assertRaises(AssertionError, VirtualCoach, environment=True) + + @patch('getpass.getpass', return_value='password') def test_init_asserts(self, mock_getpass): # invalid oidc username self.assertRaises(AssertionError, VirtualCoach, oidc_username=123) - # invalid environment - self.assertRaises(AssertionError, VirtualCoach, environment=True) # invalid storage server username self.assertRaises(AssertionError, VirtualCoach, storage_username=123) diff --git a/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/virtual_coach.py b/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/virtual_coach.py index 221be5732f749b2e937b2eb99757dc5aa9c7ee94..ba5b858472301b0091c34be6172aa98af6655dce 100644 --- a/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/virtual_coach.py +++ b/hbp_nrp_virtual_coach/hbp_nrp_virtual_coach/virtual_coach.py @@ -52,7 +52,7 @@ class VirtualCoach(object): view available experiments, query currently running experiments, launch a simulation, and more. """ - def __init__(self, environment=None, oidc_username=None, + def __init__(self, environment=None, oidc_username=None, oidc_token=None, storage_username=None, storage_password=None): """ Instantiates the Virtual Coach by loading the configuration file and logging into OIDC for @@ -66,8 +66,12 @@ class VirtualCoach(object): a key/value pair to the "proxy" section. :param oidc_username: (optional) A string representing the OIDC username for the current user, required if the provided environment requires OIDC - authentication. The user will be interactively asked for a password by + authentication and no token is provided. + The user will be interactively asked for a password by the OIDC client if the token is expired or they have not logged in. + :param oidc_token: (optional) A string representing the OIDC token for the current + user, required if the selected environment requires OIDC + and the username is not provided. :param storage_username: (optional) A string representing the Storage Server username. It is required if the user wants to have access to the storage server to clone experiments and launch cloned experiments. @@ -76,6 +80,7 @@ class VirtualCoach(object): """ assert isinstance(environment, (str, type(None))) assert isinstance(oidc_username, (str, type(None))) + assert isinstance(oidc_token, (str, type(None))) assert isinstance(storage_username, (str, type(None))) # ROS node and logger configuration only if rospy is available @@ -105,10 +110,11 @@ class VirtualCoach(object): self.__oidc_username = oidc_username self.__storage_username = storage_username # if an OIDC username is provided, attempt to login or retrieve the last valid token - if oidc_username: + if oidc_username or oidc_token: # this will interactively prompt the user for a password in terminal if needed - logger.info('Logging into OIDC as: %s', oidc_username) - self.__http_client = OIDCHTTPClient(oidc_username) + if oidc_username: + logger.info('Logging into OIDC as: %s', oidc_username) + self.__http_client = OIDCHTTPClient(oidc_username=oidc_username, oidc_token=oidc_token) authorization = self.__http_client.get_auth_header() # Set self.__http_headers: it is also used