Files
ServerKit/backend/tests/test_security_policy.py
Juan DenisandClaude Opus 4.8 b29fa77313 fix(recovery): rebuild authz-R2 policy + notification digests/chat webhooks
Clusters E+H of plan 38 (plans 24/29/33).

- security_policy_service: require-2FA policy (ok/nudge/enforce), SSO-exempt,
  grace window (plan 29); restored can_operate_app/can_admin_app on
  resource_grant_service for the member-action callers — 23 tests green
- notifications/digest: per-user daily/weekly digest rollups over queued_digest
  deliveries, respecting cadence + last_sent_at (plans 24/33)
- notifications/service: deep-link action_path/action_label on send + inbox
  category/severity filters (plan 24 Phase 5); catalog link builder
- chat_webhook_service: org chat/webhook connections, HMAC-signed delivery,
  category fan-out through the notify bus (plan 33)
- restored digest_cadence/digest_last_sent_at on NotificationPreferences

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 01:41:43 -04:00

119 lines
4.2 KiB
Python

"""Proving tests for SecurityPolicyService — the require-2FA enrollment policy
(plan 29 Phase 2: ok/nudge/enforce, SSO-exempt, activation-anchored grace).
Reconstructed alongside the lost service; there was no surviving test, so this
file is the executable contract.
"""
from datetime import datetime, timedelta
from werkzeug.security import generate_password_hash
from app import db
from app.models import User
from app.services.security_policy_service import (
SecurityPolicyService as SPS,
SETTING_ENABLED_AT,
SETTING_REQUIRE_2FA,
)
def _user(username='u', *, provider='local', totp=False, created_days_ago=1):
u = User(
email=f'{username}@t.local', username=username,
password_hash=generate_password_hash('x'), role='developer',
is_active=True, auth_provider=provider, totp_enabled=totp,
created_at=datetime.utcnow() - timedelta(days=created_days_ago),
)
db.session.add(u)
db.session.commit()
return u
def test_policy_off_is_always_ok(app):
u = _user('off')
assert SPS.require_2fa_enabled() is False
assert SPS.evaluate(u) == SPS.OK
def test_enabling_stamps_activation_once(app):
from app.services.settings_service import SettingsService
assert SettingsService.get(SETTING_ENABLED_AT) in (None, '')
SPS.set_require_2fa(True)
first = SettingsService.get(SETTING_ENABLED_AT)
assert first # stamped on off->on
# Re-affirming ON does not move the anchor.
SPS.set_require_2fa(True)
assert SettingsService.get(SETTING_ENABLED_AT) == first
assert SPS.require_2fa_enabled() is True
def test_veteran_gets_full_grace_on_flip(app):
"""A 100-day-old account without 2FA is only NUDGEd right after the policy
flips on — the grace clock starts at activation, not account age."""
u = _user('vet', created_days_ago=100)
SPS.set_require_2fa(True)
assert SPS.evaluate(u) == SPS.NUDGE
# ...and enforcement only bites once the window from activation elapses.
past_window = datetime.utcnow() + timedelta(days=SPS.GRACE_PERIOD_DAYS + 1)
assert SPS.evaluate(u, now=past_window) == SPS.ENFORCE
def test_enforced_after_grace(app):
# Old account so the anchor is the (backdated) activation, not created_at.
u = _user('late', created_days_ago=100)
SPS.set_require_2fa(True)
# Backdate the activation so the grace window is already gone.
from app.services.settings_service import SettingsService
SettingsService.set(
SETTING_ENABLED_AT,
(datetime.utcnow() - timedelta(days=SPS.GRACE_PERIOD_DAYS + 3)).isoformat(),
)
assert SPS.evaluate(u) == SPS.ENFORCE
def test_user_with_2fa_is_ok(app):
u = _user('has2fa', totp=True)
SPS.set_require_2fa(True)
from app.services.settings_service import SettingsService
SettingsService.set(
SETTING_ENABLED_AT,
(datetime.utcnow() - timedelta(days=99)).isoformat(),
)
# Even past the grace window, an enrolled user is fine.
assert SPS.evaluate(u) == SPS.OK
assert SPS.user_has_2fa(u) is True
def test_sso_user_is_exempt(app):
u = _user('sso', provider='google')
SPS.set_require_2fa(True)
from app.services.settings_service import SettingsService
SettingsService.set(
SETTING_ENABLED_AT,
(datetime.utcnow() - timedelta(days=99)).isoformat(),
)
assert SPS.is_sso_user(u) is True
assert SPS.evaluate(u) == SPS.OK
def test_grace_anchor_is_max_of_created_and_activation(app):
# Account younger than the policy activation -> anchor on the account.
young = _user('young', created_days_ago=0)
SPS.set_require_2fa(True)
from app.services.settings_service import SettingsService
activation = datetime.utcnow() - timedelta(days=30)
SettingsService.set(SETTING_ENABLED_AT, activation.isoformat())
anchor = SPS.grace_anchor(young)
# young.created_at (now-ish) is later than the 30-day-old activation.
assert anchor >= young.created_at - timedelta(seconds=2)
def test_status_snapshot_shape(app):
u = _user('snap')
SPS.set_require_2fa(True)
snap = SPS.status(u)
assert snap['required'] is True
assert snap['result'] in (SPS.NUDGE, SPS.ENFORCE)
assert snap['has_2fa'] is False
assert snap['grace_deadline'] is not None