diff --git a/python/aistore/sdk/authn/authn_client.py b/python/aistore/sdk/authn/authn_client.py index 80f4273886a..5d844074e0c 100644 --- a/python/aistore/sdk/authn/authn_client.py +++ b/python/aistore/sdk/authn/authn_client.py @@ -114,6 +114,24 @@ def login( logger.error("Login failed for username: %s, error: %s", username, err) raise + def logout(self) -> None: + """ + Logs out and revokes current token from the AuthN Server. + + Raises: + AISError: If the logout request fails. + """ + if not self.client.token: + raise ValueError("Must be logged in first (no token)") + + try: + logger.info("Logging out") + self.token_manager().revoke(token=self.client.token) + self.client.token = None + except Exception as err: + logger.error("Logout failed, error: %s", err) + raise + def cluster_manager(self) -> ClusterManager: """ Factory method to create a ClusterManager instance. diff --git a/python/aistore/sdk/request_client.py b/python/aistore/sdk/request_client.py index 959021319c4..3bbbc51e727 100644 --- a/python/aistore/sdk/request_client.py +++ b/python/aistore/sdk/request_client.py @@ -92,13 +92,8 @@ def token(self, token: str): Set the token for Authorization. Args: - token (str): Token for Authorization. Must be a non-empty string. - - Raises: - ValueError: If the provided token is empty. + token (str): Token for Authorization. """ - if not token: - raise ValueError("Token must be a non-empty string.") self._token = token def request_deserialize( diff --git a/python/tests/integration/sdk/authn/test_authn_client.py b/python/tests/integration/sdk/authn/test_authn_client.py index f6fc256ce00..6efc974614f 100644 --- a/python/tests/integration/sdk/authn/test_authn_client.py +++ b/python/tests/integration/sdk/authn/test_authn_client.py @@ -43,6 +43,14 @@ def test_login_success(self): token = self.authn_client.login(AIS_AUTHN_SU_NAME, AIS_AUTHN_SU_PASS) self.assertIsNotNone(token) + @pytest.mark.authn + def test_logout(self): + token = self.authn_client.login(AIS_AUTHN_SU_NAME, AIS_AUTHN_SU_PASS) + self.assertIsNotNone(token) + + self.authn_client.logout() + self.assertIsNone(self.authn_client.client.token) + @pytest.mark.authn def test_create_bucket_without_token(self): ais_client = Client(CLUSTER_ENDPOINT)