Skip to content

Commit

Permalink
fix(api) add api token expiry (#124)
Browse files Browse the repository at this point in the history
This introduces expiry for the API service generated token. By setting 
the env variable `NESIS_API_MEMCACHE_SESSION_EXPIRY`, we are able to
control the expiry of the API token. We've defaulted it to `30` minutes.
  • Loading branch information
mawandm authored Jun 18, 2024
1 parent 8417fb8 commit 4a46ed7
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
4 changes: 3 additions & 1 deletion nesis/api/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
},
"memcache": {
"hosts": [os.environ.get("NESIS_MEMCACHE_HOSTS", "127.0.0.1:11211")],
"session": {"expiry": 0},
"session": {
"expiry": os.environ.get("NESIS_API_MEMCACHE_SESSION_EXPIRY") or 1800
},
"cache": {
"timeout_default": 300,
},
Expand Down
5 changes: 4 additions & 1 deletion nesis/api/core/services/app_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,10 @@ def create(self, **kwargs) -> Dict[str, Any]:
if token is None:
raise UnauthorizedAccess("Token not supplied")

encoded_secret = base64.b64decode(token).decode("utf-8")
try:
encoded_secret = base64.b64decode(token).decode("utf-8")
except UnicodeDecodeError:
raise UnauthorizedAccess("Invalid app token supplied")
encoded_secret_parts = encoded_secret.split(":")
if len(encoded_secret_parts) != 2:
raise UnauthorizedAccess("Invalid app token supplied")
Expand Down
34 changes: 33 additions & 1 deletion nesis/api/tests/core/services/test_management.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import uuid
from time import sleep

import yaml

Expand All @@ -13,7 +14,12 @@
import nesis.api.core.services as services
from nesis.api.core.models import initialize_engine, DBSession
from nesis.api.core.models.entities import Datasource
from nesis.api.core.services import PermissionException
from nesis.api.core.services import (
PermissionException,
DatasourceService,
UserSessionService,
UnauthorizedAccess,
)
from nesis.api.tests.core.services import (
create_user_session,
create_role,
Expand Down Expand Up @@ -136,3 +142,29 @@ def test_datasource_permissions(http_client, tc):
token=given_user_session.token,
)
assert role_record.id is not None


def test_session_expiry(http_client, tc):
"""
Test that the api token can expire
"""

tests.config["memcache"]["session"]["expiry"] = 5
services.init_services(config=tests.config, http_client=http_client)

admin_user = create_user_session(
service=services.user_session_service,
email=tests.admin_email,
password=tests.admin_password,
)
datasource: Datasource = create_datasource(token=admin_user.token)
assert datasource.id is not None
assert datasource.uuid is not None

# Sleep to simulate inactivity
sleep(10)

# Token should have expired from the cache
with pytest.raises(UnauthorizedAccess) as ex_info:
create_datasource(token=admin_user.token)
assert "Invalid app token supplied" in str(ex_info)

0 comments on commit 4a46ed7

Please sign in to comment.