From 5de39a8e9d4cc0a00668c5759b6a182f64931c1b Mon Sep 17 00:00:00 2001 From: Varun Valada Date: Wed, 5 Feb 2025 09:51:15 -0600 Subject: [PATCH] Use 401 error for expired authorization token --- cli/testflinger_cli/__init__.py | 36 ++++++++++++++++----------- cli/testflinger_cli/tests/test_cli.py | 2 +- server/src/api/v1.py | 2 +- server/tests/test_v1_authorization.py | 2 +- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/cli/testflinger_cli/__init__.py b/cli/testflinger_cli/__init__.py index 92cccb29..0269c980 100644 --- a/cli/testflinger_cli/__init__.py +++ b/cli/testflinger_cli/__init__.py @@ -592,24 +592,32 @@ def submit_job_data(self, data: dict): "Received 404 error from server. Are you " "sure this is a testflinger server?" ) - if exc.status == 401: + + if exc.status == 403: sys.exit( - "Received 401 error from server. You are " - "attempting to use a feature that requires " - "client authorisation without using client " - "credentials. See https://testflinger.readthedocs" - ".io/en/latest/how-to/authentication/ for more details" + "Received 403 error from server with reason " + f"{exc.msg}" + "The specified client credentials do not have " + "sufficient permissions for the resource(s) " + "you are trying to access." ) - if exc.status == 403: - if "expired" in exc.msg and retry_count < 2: - retry_count += 1 + if exc.status == 401: + if "expired" in exc.msg: + if retry_count < 2: + retry_count += 1 + else: + sys.exit( + "Received 401 error from server due to " + "expired authorization token." + ) else: sys.exit( - "Received 403 error from server with reason " - f"{exc.msg}" - "The specified client credentials do not have " - "sufficient permissions for the resource(s) " - "you are trying to access." + "Received 401 error from server with reason " + f"{exc.msg} You are attempting to use a feature " + "that requires client authorisation " + "without using client credentials. " + "See https://testflinger.readthedocs.io/en/latest" + "/how-to/authentication/ for more details" ) else: # This shouldn't happen, so let's get more information diff --git a/cli/testflinger_cli/tests/test_cli.py b/cli/testflinger_cli/tests/test_cli.py index e83d5341..25f2cca7 100644 --- a/cli/testflinger_cli/tests/test_cli.py +++ b/cli/testflinger_cli/tests/test_cli.py @@ -527,7 +527,7 @@ def test_submit_token_timeout_retry(tmp_path, requests_mock): fake_jwt = "my_jwt" requests_mock.post(f"{URL}/v1/oauth2/token", text=fake_jwt) requests_mock.post( - f"{URL}/v1/job", text="Token has expired", status_code=403 + f"{URL}/v1/job", text="Token has expired", status_code=401 ) requests_mock.get( URL + "/v1/queues/fake/agents", diff --git a/server/src/api/v1.py b/server/src/api/v1.py index 43ef3647..7fa022b3 100644 --- a/server/src/api/v1.py +++ b/server/src/api/v1.py @@ -120,7 +120,7 @@ def decode_jwt_token(auth_token: str, secret_key: str) -> dict: options={"require": ["exp", "iat", "sub"]}, ) except jwt.exceptions.ExpiredSignatureError: - abort(403, "Token has expired") + abort(401, "Token has expired") except jwt.exceptions.InvalidTokenError: abort(403, "Invalid Token") diff --git a/server/tests/test_v1_authorization.py b/server/tests/test_v1_authorization.py index bdf6b9a3..79040340 100644 --- a/server/tests/test_v1_authorization.py +++ b/server/tests/test_v1_authorization.py @@ -156,7 +156,7 @@ def test_priority_expired_token(mongo_app_with_permissions): job_response = app.post( "/v1/job", json=job, headers={"Authorization": token} ) - assert 403 == job_response.status_code + assert 401 == job_response.status_code assert "Token has expired" in job_response.text