From 0dbe2cea3d261ecc7ba3a714880e9ef2983ba827 Mon Sep 17 00:00:00 2001 From: zhiren Date: Tue, 5 Dec 2023 17:25:09 -0500 Subject: [PATCH 1/3] add the new error handler for 401 when portal has shared login session with cli --- app/services/dataset_manager/dataset_list.py | 2 ++ app/services/project_manager/project.py | 2 ++ app/services/user_authentication/token_manager.py | 3 +++ app/utils/aggregated.py | 2 ++ .../user_authentication/test_token_manager.py | 12 ++++++++++++ 5 files changed, 21 insertions(+) diff --git a/app/services/dataset_manager/dataset_list.py b/app/services/dataset_manager/dataset_list.py index 75b50a2f..0f128c05 100644 --- a/app/services/dataset_manager/dataset_list.py +++ b/app/services/dataset_manager/dataset_list.py @@ -42,6 +42,8 @@ def list_datasets(self, page, page_size): return res_to_dict elif response.status_code == 404: SrvErrorHandler.customized_handle(ECustomizedError.USER_DISABLED, True) + elif response.status_code == 401: + SrvErrorHandler.customized_handle(ECustomizedError.INVALID_TOKEN, if_exit=True) else: SrvErrorHandler.default_handle(response.content, True) except Exception as e: diff --git a/app/services/project_manager/project.py b/app/services/project_manager/project.py index 8a8c930b..79c08dca 100644 --- a/app/services/project_manager/project.py +++ b/app/services/project_manager/project.py @@ -43,6 +43,8 @@ def list_projects(self, page, page_size, order, order_by): return res_to_dict elif response.status_code == 404: SrvErrorHandler.customized_handle(ECustomizedError.USER_DISABLED, True) + elif response.status_code == 401: + SrvErrorHandler.customized_handle(ECustomizedError.INVALID_TOKEN, if_exit=True) else: SrvErrorHandler.default_handle(response.content, True) except Exception: diff --git a/app/services/user_authentication/token_manager.py b/app/services/user_authentication/token_manager.py index ebc574d0..314adbe8 100644 --- a/app/services/user_authentication/token_manager.py +++ b/app/services/user_authentication/token_manager.py @@ -12,6 +12,7 @@ from app.configs.user_config import UserConfig from app.models.enums import LoginMethod from app.models.service_meta_class import MetaService +from app.services.output_manager.error_handler import ECustomizedError from app.services.output_manager.error_handler import SrvErrorHandler from app.services.user_authentication.user_login_logout import exchange_api_key @@ -93,6 +94,8 @@ def refresh(self, azp: str) -> None: response = requests.post(url, data=payload, headers=headers) if response.status_code == 200: self.update_token(response.json()['access_token'], response.json()['refresh_token']) + elif response.status_code == 401: + SrvErrorHandler.customized_handle(ECustomizedError.INVALID_TOKEN, if_exit=True) else: SrvErrorHandler.default_handle(response.content) diff --git a/app/utils/aggregated.py b/app/utils/aggregated.py index a9052ece..a888fd14 100644 --- a/app/utils/aggregated.py +++ b/app/utils/aggregated.py @@ -44,6 +44,8 @@ def search_item(project_code, zone, folder_relative_path, item_type, container_t SrvErrorHandler.customized_handle(ECustomizedError.PERMISSION_DENIED, project_code) elif res.status_code == 404: pass + elif res.status_code == 401: + SrvErrorHandler.customized_handle(ECustomizedError.INVALID_TOKEN, if_exit=True) elif res.status_code != 200: SrvErrorHandler.default_handle(res.text, True) diff --git a/tests/app/services/user_authentication/test_token_manager.py b/tests/app/services/user_authentication/test_token_manager.py index 50379c80..6cefb48a 100644 --- a/tests/app/services/user_authentication/test_token_manager.py +++ b/tests/app/services/user_authentication/test_token_manager.py @@ -38,3 +38,15 @@ def test_refresh_api_key_calls_keycloak_and_stores_access_token_in_config(self, assert manager.config.access_token == access_token assert manager.config.refresh_token == '' + + def test_refresh_failed_with_invalid_token(self, requests_mock, settings): + manager = SrvTokenManager() + requests_mock.get( + f'{settings.url_keycloak_realm}/api-key/{manager.config.api_key}', + status_code=401, + ) + + manager.refresh_api_key() + + assert manager.config.access_token == '' + assert manager.config.refresh_token == '' From 7ddad8ca3e67667cd38b6b4e0d8f59ebce696146 Mon Sep 17 00:00:00 2001 From: zhiren Date: Tue, 5 Dec 2023 17:34:39 -0500 Subject: [PATCH 2/3] add the test cases for token refresh --- .../user_authentication/test_token_manager.py | 22 +++++++++++++------ tests/app/utils/test_aggregated.py | 2 +- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/app/services/user_authentication/test_token_manager.py b/tests/app/services/user_authentication/test_token_manager.py index 6cefb48a..6846ae20 100644 --- a/tests/app/services/user_authentication/test_token_manager.py +++ b/tests/app/services/user_authentication/test_token_manager.py @@ -3,9 +3,12 @@ # Contact Indoc Systems for any questions regarding the use of this source code. import jwt +import pytest +from app.configs.app_config import AppConfig from app.configs.user_config import UserConfig from app.services.user_authentication.token_manager import SrvTokenManager +from tests.conftest import decoded_token class TestSrvTokenManager: @@ -39,14 +42,19 @@ def test_refresh_api_key_calls_keycloak_and_stores_access_token_in_config(self, assert manager.config.access_token == access_token assert manager.config.refresh_token == '' - def test_refresh_failed_with_invalid_token(self, requests_mock, settings): + def test_refresh_failed_with_invalid_token(self, requests_mock, mocker, settings, capsys): manager = SrvTokenManager() - requests_mock.get( - f'{settings.url_keycloak_realm}/api-key/{manager.config.api_key}', - status_code=401, + mocker.patch( + 'app.services.user_authentication.token_manager.SrvTokenManager.decode_access_token', + return_value=decoded_token(), ) - manager.refresh_api_key() + requests_mock.post( + AppConfig.Connections.url_keycloak_token, + status_code=401, + ) - assert manager.config.access_token == '' - assert manager.config.refresh_token == '' + with pytest.raises(SystemExit): + manager.refresh('test_azp') + out, _ = capsys.readouterr() + assert out.rstrip() == 'Your login session has expired. Please try again or log in again.' diff --git a/tests/app/utils/test_aggregated.py b/tests/app/utils/test_aggregated.py index 9ddadd2f..08932873 100644 --- a/tests/app/utils/test_aggregated.py +++ b/tests/app/utils/test_aggregated.py @@ -99,4 +99,4 @@ def test_search_file_error_handling_with_401(requests_mock, mocker, capsys): with pytest.raises(SystemExit): search_item(test_project_code, 'zone', 'folder_relative_path', 'file', 'project') out, _ = capsys.readouterr() - assert out.rstrip() == 'Authentication failed.' + assert out.rstrip() == 'Your login session has expired. Please try again or log in again.' From 951a5b1325602a00cd90d5238d9b750e41a2be83 Mon Sep 17 00:00:00 2001 From: zhiren Date: Fri, 8 Dec 2023 09:07:31 -0500 Subject: [PATCH 3/3] update version to next patch --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 08678608..85770675 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "app" -version = "2.9.1" +version = "2.9.2" description = "This service is designed to support pilot platform" authors = ["Indoc Systems"]