user-engine/tests/test_account_awareness.py
tegwick b987a3de9e
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 40s
Account journey acceptance / journeys (push) Successful in 11s
Name the account site NetKingdom Identity.
Say "Signed in as" the identity, and describe a one-time code as a
higher security level of the NetKingdom sign-in rather than another
sign-in. The account site keeps its own session.

Assistant: grok
Assistant-Session: 01a0d25d-d358-7e13-b84a-d007fbb7e34f
2026-09-26 23:48:00 +02:00

136 lines
7.1 KiB
Python

"""Login state, active sign-in, and allowed memberships stay separate."""
import unittest
from test_web import invoke
from user_engine.domain import Membership
from user_engine.oidc import BrowserSession
from user_engine.testing.fixtures import human_actor_claims
import test_portal_navigation
def _section(body: bytes, element_id: str) -> bytes:
marker = f'id="{element_id}"'.encode()
start = body.index(marker)
end = body.index(b"</ul>", start)
return body[start:end]
class AccountAwarenessTests(unittest.TestCase):
setUp = test_portal_navigation.PortalNavigationTests.setUp
get = test_portal_navigation.PortalNavigationTests.get
def test_signed_out_home_states_only_the_portal_session(self):
_, body = invoke(self.app, "/", query="username=forged&tenant=tenant:evil:one")
self.assertIn(b"NetKingdom Identity", body)
self.assertIn(b"Identity", body)
self.assertIn(b"You are not signed in.", body)
self.assertIn(b"It is not another sign-in.", body)
self.assertNotIn(b"Active now", body)
self.assertNotIn(b"Allowed tenants", body)
self.assertNotIn(b"forged", body)
self.assertNotIn(b"tenant:evil:one", body)
def test_token_tenant_without_membership_is_active_and_not_allowed(self):
session = self.app.service.me(self.oidc.claims("member"), correlation_id="synthetic")
self.assertIsNotNone(
self.app.service.store.tenant_account("tenant:trial:demo-company", session.user.user_id)
)
_, body = self.get("/onboarding", who="member")
active = _section(body, "active-tenant-list")
allowed = _section(body, "allowed-tenant-list")
self.assertIn(b"<strong>tenant:trial:demo-company</strong> - Active", active)
self.assertNotIn(b"tenant:two", active)
self.assertIn(b"No tenant memberships are recorded.", allowed)
self.assertNotIn(b"tenant:trial:demo-company", allowed)
self.assertIn(b"No workload access is recorded.", body)
self.assertIn(b"Workload decisions are not checked.", body)
self.assertNotIn(b"Viewing", body)
self.assertIn(b"An ordinary sign-in uses one tenant.", body)
self.assertIn(b"This session is for the account site.", body)
self.assertIn(b"Signed in as", body)
def test_allowed_tenant_that_is_not_active_uses_sign_in(self):
session = self.app.service.me(self.oidc.claims("member"), correlation_id="synthetic")
self.app.service.store.save_membership(Membership(
membership_id="mem-other", user_id=session.user.user_id,
tenant="tenant:other:company", scope_type="tenant",
scope_id="tenant:other:company", kind="user",
))
_, body = self.get("/onboarding", who="member")
allowed = _section(body, "allowed-tenant-list")
active = _section(body, "active-tenant-list")
self.assertIn(b"tenant:other:company - user - Inactive.", allowed)
self.assertIn(b'href="/login?tenant_hint=tenant%3Aother%3Acompany"', allowed)
self.assertNotIn(b"<form", allowed)
self.assertIn(b"tenant:trial:demo-company", active)
self.assertNotIn(b"tenant:other:company", active)
self.assertIn(b"does not end a session an application already has.", body)
def test_recorded_workload_stays_allowed_and_unchecked(self):
session = self.app.service.me(self.oidc.claims("member"), correlation_id="synthetic")
self.app.service.store.save_membership(Membership(
membership_id="mem-work", user_id=session.user.user_id,
tenant="tenant:trial:demo-company", scope_type="service",
scope_id="vergabe-demo-company", kind="user",
))
_, body = self.get("/onboarding", who="member")
workloads = _section(body, "allowed-workload-list")
allowed_tenants = _section(body, "allowed-tenant-list")
self.assertIn(b"vergabe-demo-company - user (tenant:trial:demo-company) - Allowed, recorded here", workloads)
self.assertIn(b"Workload decisions are not checked.", body)
self.assertIn(b"No tenant memberships are recorded.", allowed_tenants)
def test_ordinary_sign_in_ignores_a_second_active_tenant_claim(self):
self.oidc.sessions["member"].claims["active_tenants"] = [
"tenant:trial:demo-company", "tenant:two:beta",
]
_, body = self.get("/onboarding", who="member")
active = _section(body, "active-tenant-list")
self.assertIn(b"tenant:trial:demo-company", active)
self.assertNotIn(b"tenant:two:beta", active)
def test_exception_role_shows_every_tenant_the_sign_in_lists(self):
for role, kind in [("tenant-admin", "user"), ("platform-root", "user"), ("user", "vendor"), ("user", "multi-hire")]:
with self.subTest(role=role, kind=kind):
subject = f"{role}-{kind}"
claims = human_actor_claims(subject=subject, tenant="tenant:one:alpha")
claims["roles"] = [role]
claims["active_tenants"] = ["tenant:one:alpha", "tenant:two:beta"]
claims["preferred_username"] = subject
self.oidc.sessions[subject] = BrowserSession(claims, 9999999999, subject + "-csrf")
session = self.app.service.me(claims, correlation_id="synthetic")
if kind in {"vendor", "multi-hire"}:
self.app.service.store.save_membership(Membership(
membership_id="mem-" + subject, user_id=session.user.user_id,
tenant="tenant:one:alpha", scope_type="tenant",
scope_id="tenant:one:alpha", kind=kind,
))
_, body = self.get("/onboarding", who=subject)
active = _section(body, "active-tenant-list")
self.assertIn(b"<strong>tenant:one:alpha</strong> - Active", active)
self.assertIn(b"<strong>tenant:two:beta</strong> - Active", active)
self.assertNotIn(b'href="/login?tenant_hint=tenant%3Atwo', body)
def test_exception_without_a_second_tenant_claim_stays_on_one(self):
claims = human_actor_claims(subject="vendor-one", tenant="tenant:one:alpha")
claims["roles"] = ["user"]
claims["preferred_username"] = "vendor-one"
self.oidc.sessions["vendor-one"] = BrowserSession(claims, 9999999999, "vendor-one-csrf")
session = self.app.service.me(claims, correlation_id="synthetic")
self.app.service.store.save_membership(Membership(
membership_id="mem-vendor-one", user_id=session.user.user_id,
tenant="tenant:other:company", scope_type="tenant",
scope_id="tenant:other:company", kind="vendor",
))
_, body = self.get("/onboarding", who="vendor-one")
active = _section(body, "active-tenant-list")
allowed = _section(body, "allowed-tenant-list")
self.assertIn(b"tenant:one:alpha", active)
self.assertNotIn(b"tenant:other:company", active)
self.assertIn(b"tenant:other:company - vendor - Inactive.", allowed)
self.assertIn(b"This sign-in has one active tenant.", body)
if __name__ == "__main__":
unittest.main()