Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle removal of invalid cached HANA tokens #538

Merged
merged 3 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions neon_utils/hana_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import json

from typing import Optional
from os import makedirs
from os import makedirs, remove
from os.path import join, isfile, isdir, dirname
from time import time
from ovos_utils.log import LOG
Expand Down Expand Up @@ -78,7 +78,8 @@ def _init_client(backend_address: str):
"""
global _client_config
global _headers

# TODO: Config on disk could be invalid here; consider validating tokens now
# instead of waiting for exception handling with a failed request
if not _client_config:
client_config_path = _get_client_config_path(backend_address)
if isfile(client_config_path):
Expand Down Expand Up @@ -175,7 +176,6 @@ def request_backend(endpoint: str, request_data: dict,
resp = requests.post(**request_kwargs)
if resp.ok:
return resp.json()

else:
try:
error = resp.json()["detail"]
Expand All @@ -192,4 +192,10 @@ def request_backend(endpoint: str, request_data: dict,
# Clear cached config to force re-evaluation on next request
_client_config = {}
_headers = {}
if resp.status_code == 403:
# Invalid token supplied; remove it from local cache
config_file = _get_client_config_path(server_url)
if isfile(config_file):
LOG.warning(f"Removing invalid token cache: {config_file}")
remove(config_file)
raise ServerException(f"Error response {resp.status_code}: {resp.text}")
20 changes: 19 additions & 1 deletion tests/hana_util_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@

from os import remove
from os.path import join, dirname, isfile
from time import time
from shutil import copy
from time import time, sleep
from unittest.mock import patch


Expand Down Expand Up @@ -71,6 +72,22 @@ def test_request_backend(self, config_path):
"user_profile": {}}, self.test_server)
self.assertEqual(resp['lang_code'], "en-us")
self.assertIsInstance(resp['answer'], str)

# Test expired/invalid token
old_token_path = join(dirname(__file__), "outdated_hana_token.json")
copy(old_token_path, self.test_path)
neon_utils.hana_utils._client_config = {}
neon_utils.hana_utils._headers = {}
from neon_utils.hana_utils import ServerException
with self.assertRaises(ServerException):
# Request fails due to invalid token
request_backend("/neon/get_response",
{"lang_code": "en-us",
"utterance": "who are you",
"user_profile": {}}, self.test_server)
# Invalid cached token is removed
self.assertFalse(isfile(self.test_path))

# TODO: Test invalid route, invalid request data

@patch("neon_utils.hana_utils._get_client_config_path")
Expand Down Expand Up @@ -135,6 +152,7 @@ def _write_token(*_, **__):
self.assertEqual(credentials_on_disk, _client_config)

# Test refresh of existing token (no auth)
sleep(1) # sleep to ensure new credentials expire later than existing
_refresh_token(self.test_server)
get_token.assert_called_once()
with open(self.test_path) as f:
Expand Down
7 changes: 7 additions & 0 deletions tests/outdated_hana_token.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"username": "guest",
"client_id": "474d2cd7-aca5-4d57-a2cd-0021a93c6b25",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiI0NzRkMmNkNy1hY2E1LTRkNTctYTJjZC0wMDIxYTkzYzZiMjUiLCJ1c2VybmFtZSI6Imd1ZXN0IiwicGFzc3dvcmQiOiJwYXNzd29yZCIsImV4cGlyZSI6MTczNTM0NjI4MC40MzUyNzd9.4hyJZTWtg25xEJ-heKmikPSMDJ7FM889S4pA7SEpCiI",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnRfaWQiOiI0NzRkMmNkNy1hY2E1LTRkNTctYTJjZC0wMDIxYTkzYzZiMjUiLCJ1c2VybmFtZSI6Imd1ZXN0IiwicGFzc3dvcmQiOiJwYXNzd29yZCIsImV4cGlyZSI6MTczNTg2NDY4MC40MzU0ODEzLCJhY2Nlc3NfdG9rZW4iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKamJHbGxiblJmYVdRaU9pSTBOelJrTW1Oa055MWhZMkUxTFRSa05UY3RZVEpqWkMwd01ESXhZVGt6WXpaaU1qVWlMQ0oxYzJWeWJtRnRaU0k2SW1kMVpYTjBJaXdpY0dGemMzZHZjbVFpT2lKd1lYTnpkMjl5WkNJc0ltVjRjR2x5WlNJNk1UY3pOVE0wTmpJNE1DNDBNelV5TnpkOS40aHlKWlRXdGcyNXhFSi1oZUttaWtQU01ESjdGTTg4OVM0cEE3U0VwQ2lJIn0.GT4SVSXZUNaKVrv6XBOw5v3Hca5vwu6ADer_5JLeBKI",
"expiration": 1735346280.435277
}
Loading