feat: login time window rules (EPIC_000014)
- Implemented RuleManager and JSON storage - Added background enforcement scheduler - Added Web UI for rule management at /ui/rules - Bumped version to 0.3.0
This commit is contained in:
95
tests/test_rules.py
Normal file
95
tests/test_rules.py
Normal file
@ -0,0 +1,95 @@
|
||||
import unittest
|
||||
import os
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
# Adjust path if necessary, assuming run from project root
|
||||
from backend.models import AccessRule, TimeWindow, DayOfWeek
|
||||
from backend.rules import RuleManager
|
||||
|
||||
class TestRules(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tmp_fd, self.rules_file = tempfile.mkstemp()
|
||||
os.close(self.tmp_fd)
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.exists(self.rules_file):
|
||||
os.remove(self.rules_file)
|
||||
|
||||
@patch("backend.rules.get_settings")
|
||||
def test_load_save_rules(self, mock_settings):
|
||||
mock_settings.return_value.rules_file = self.rules_file
|
||||
manager = RuleManager()
|
||||
|
||||
# Should be empty initially
|
||||
rules = manager.load_rules()
|
||||
self.assertEqual(rules.rules, {})
|
||||
|
||||
# Save a rule
|
||||
rule = AccessRule(
|
||||
user="testuser",
|
||||
allowed_windows=[
|
||||
TimeWindow(days=[DayOfWeek.MONDAY], start_time="09:00", end_time="17:00")
|
||||
]
|
||||
)
|
||||
manager.set_rule(rule)
|
||||
|
||||
# Load back
|
||||
loaded = manager.get_rule("testuser")
|
||||
self.assertIsNotNone(loaded)
|
||||
self.assertEqual(loaded.user, "testuser")
|
||||
self.assertEqual(loaded.allowed_windows[0].start_time, "09:00")
|
||||
|
||||
@patch("backend.rules.get_settings")
|
||||
def test_access_logic(self, mock_settings):
|
||||
mock_settings.return_value.rules_file = self.rules_file
|
||||
manager = RuleManager()
|
||||
|
||||
# No rule -> Allowed
|
||||
self.assertTrue(manager.is_login_allowed("unknown"))
|
||||
|
||||
# Add rule: Mon 10-12
|
||||
rule = AccessRule(
|
||||
user="kid",
|
||||
allowed_windows=[
|
||||
TimeWindow(days=[DayOfWeek.MONDAY], start_time="10:00", end_time="12:00")
|
||||
]
|
||||
)
|
||||
manager.set_rule(rule)
|
||||
|
||||
# Monday 11:00 -> Allowed
|
||||
# Jan 2 2023 is Monday
|
||||
mon_11 = datetime(2023, 1, 2, 11, 0)
|
||||
self.assertTrue(manager.is_login_allowed("kid", mon_11))
|
||||
|
||||
# Monday 09:00 -> Denied
|
||||
mon_09 = datetime(2023, 1, 2, 9, 0)
|
||||
self.assertFalse(manager.is_login_allowed("kid", mon_09))
|
||||
|
||||
# Tuesday 11:00 -> Denied
|
||||
# Jan 3 2023 is Tuesday
|
||||
tue_11 = datetime(2023, 1, 3, 11, 0)
|
||||
self.assertFalse(manager.is_login_allowed("kid", tue_11))
|
||||
|
||||
@patch("backend.rules.get_settings")
|
||||
def test_disabled_rule(self, mock_settings):
|
||||
mock_settings.return_value.rules_file = self.rules_file
|
||||
manager = RuleManager()
|
||||
|
||||
# Add disabled rule
|
||||
rule = AccessRule(
|
||||
user="kid",
|
||||
enabled=False,
|
||||
allowed_windows=[
|
||||
TimeWindow(days=[DayOfWeek.MONDAY], start_time="10:00", end_time="12:00")
|
||||
]
|
||||
)
|
||||
manager.set_rule(rule)
|
||||
|
||||
# Should be allowed even if time doesn't match, because rule is disabled (default allow)
|
||||
mon_09 = datetime(2023, 1, 2, 9, 0)
|
||||
self.assertTrue(manager.is_login_allowed("kid", mon_09))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user