101 lines
3.8 KiB
Python
101 lines
3.8 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, timedelta, timezone
|
|
from types import SimpleNamespace
|
|
from unittest import TestCase
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from govoplan_access.backend.security.api_keys import authenticate_api_key
|
|
from govoplan_access.backend.security.sessions import authenticate_session_token
|
|
|
|
|
|
class AuthenticationActivityTouchTests(TestCase):
|
|
def test_session_activity_is_touched_only_after_the_interval(self) -> None:
|
|
now = datetime(2026, 7, 29, 10, 0, tzinfo=timezone.utc)
|
|
for age_seconds, should_touch in ((60, False), (301, True)):
|
|
with self.subTest(age_seconds=age_seconds):
|
|
model = SimpleNamespace(
|
|
expires_at=now + timedelta(hours=1),
|
|
last_seen_at=now - timedelta(seconds=age_seconds),
|
|
)
|
|
session = MagicMock()
|
|
(
|
|
session.query.return_value.options.return_value
|
|
.filter.return_value.one_or_none
|
|
).return_value = model
|
|
|
|
with (
|
|
patch(
|
|
"govoplan_access.backend.security.sessions.hash_session_token",
|
|
return_value="hashed",
|
|
),
|
|
patch(
|
|
"govoplan_access.backend.security.sessions.utc_now",
|
|
return_value=now,
|
|
),
|
|
):
|
|
result = authenticate_session_token(
|
|
session,
|
|
"token",
|
|
touch_interval_seconds=300,
|
|
)
|
|
|
|
self.assertIs(model, result)
|
|
if should_touch:
|
|
self.assertEqual(now, model.last_seen_at)
|
|
session.add.assert_called_once_with(model)
|
|
else:
|
|
self.assertEqual(
|
|
now - timedelta(seconds=age_seconds),
|
|
model.last_seen_at,
|
|
)
|
|
session.add.assert_not_called()
|
|
|
|
def test_api_key_activity_is_touched_only_after_the_interval(self) -> None:
|
|
now = datetime(2026, 7, 29, 10, 0, tzinfo=timezone.utc)
|
|
for age_seconds, should_touch in ((60, False), (301, True)):
|
|
with self.subTest(age_seconds=age_seconds):
|
|
model = SimpleNamespace(
|
|
expires_at=None,
|
|
last_used_at=now - timedelta(seconds=age_seconds),
|
|
key_hash="hashed",
|
|
)
|
|
session = MagicMock()
|
|
(
|
|
session.query.return_value.options.return_value
|
|
.filter.return_value.all
|
|
).return_value = [model]
|
|
|
|
with (
|
|
patch(
|
|
"govoplan_access.backend.security.api_keys.verify_api_key",
|
|
return_value=True,
|
|
),
|
|
patch(
|
|
"govoplan_access.backend.security.api_keys.utc_now",
|
|
return_value=now,
|
|
),
|
|
):
|
|
result = authenticate_api_key(
|
|
session,
|
|
"mm_test-token",
|
|
touch_interval_seconds=300,
|
|
)
|
|
|
|
self.assertIs(model, result)
|
|
if should_touch:
|
|
self.assertEqual(now, model.last_used_at)
|
|
session.add.assert_called_once_with(model)
|
|
else:
|
|
self.assertEqual(
|
|
now - timedelta(seconds=age_seconds),
|
|
model.last_used_at,
|
|
)
|
|
session.add.assert_not_called()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import unittest
|
|
|
|
unittest.main()
|