Fix: resolve tenants by identifier, not only internal tenant_id
Found via a real cross-service check while implementing key-cape's KEY-WP-0005-T02: key-cape's Go adapter called GET /tenants/tenant:coulomb/roles and got a genuine 404 for a tenant that existed. External callers (key-cape, flex-auth) only ever have a tenant's profile identifier, never tenant-engine's internal tenant_id (caller-chosen at creation, otherwise opaque). Every existing test happened to use identical strings for both fields, so this was invisible until a real, independent second caller exercised the documented contract. InMemoryTenantStore gained a _by_identifier index and a _resolve() helper every method calls first; create_tenant now also rejects a duplicate identifier under a different internal id (an oversight the same fix surfaced). 5 new tests, including the exact HTTP-level scenario with colon characters in the URL path. 65 total, all 60 pre-existing tests unaffected. Re-verified end-to-end for real: fresh flex-auth + tenant-engine + key-cape's actual adapter code, over real HTTP -- roles=[IAM] ok=true resolving by identifier. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
18f510070f
commit
31e237cfa6
4 changed files with 193 additions and 17 deletions
|
|
@ -64,6 +64,19 @@ def test_cache_read_roles_returns_active_roles() -> None:
|
|||
assert response.json() == {"tenant_id": "t-binky", "roles": ["CUS"]}
|
||||
|
||||
|
||||
def test_cache_read_roles_resolves_by_identifier_not_only_internal_id() -> None:
|
||||
"""The real scenario key-cape's KEY-WP-0005-T02 hits: it only knows the
|
||||
|
||||
tenant's profile identifier (the IAM Profile `tenant` claim value), via
|
||||
a URL path segment containing colons -- never the internal tenant_id.
|
||||
"""
|
||||
client = TestClient(create_app(store=_seeded_store()))
|
||||
response = client.get("/tenants/tenant:friendly:binky/roles")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"tenant_id": "tenant:friendly:binky", "roles": ["CUS"]}
|
||||
|
||||
|
||||
def test_cache_read_roles_unknown_tenant_is_404() -> None:
|
||||
client = TestClient(create_app(store=_seeded_store()))
|
||||
response = client.get("/tenants/does-not-exist/roles")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue