fix(04-rbac): revise plans based on checker feedback
This commit is contained in:
@@ -16,6 +16,7 @@ files_modified:
|
||||
- migrations/versions/006_rbac_roles.py
|
||||
- tests/unit/test_rbac_guards.py
|
||||
- tests/unit/test_invitations.py
|
||||
- tests/unit/test_portal_auth.py
|
||||
autonomous: true
|
||||
requirements:
|
||||
- RBAC-01
|
||||
@@ -54,6 +55,9 @@ must_haves:
|
||||
- path: "tests/unit/test_invitations.py"
|
||||
provides: "Unit tests for HMAC token and invitation flow"
|
||||
min_lines: 40
|
||||
- path: "tests/unit/test_portal_auth.py"
|
||||
provides: "Unit tests for auth/verify endpoint returning role + tenant_ids claims"
|
||||
min_lines: 30
|
||||
key_links:
|
||||
- from: "packages/shared/shared/api/rbac.py"
|
||||
to: "packages/shared/shared/models/auth.py"
|
||||
@@ -266,10 +270,11 @@ class AuditEvent(Base): # Reuse for impersonation logging in Plan 03
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 3: Unit tests for RBAC guards and invitation system</name>
|
||||
<name>Task 3: Unit tests for RBAC guards, invitation system, and portal auth</name>
|
||||
<files>
|
||||
tests/unit/test_rbac_guards.py,
|
||||
tests/unit/test_invitations.py
|
||||
tests/unit/test_invitations.py,
|
||||
tests/unit/test_portal_auth.py
|
||||
</files>
|
||||
<behavior>
|
||||
- test_platform_admin_passes: platform_admin caller gets through require_platform_admin
|
||||
@@ -285,6 +290,9 @@ class AuditEvent(Base): # Reuse for impersonation logging in Plan 03
|
||||
- test_invite_accept_creates_user: accepting invite creates PortalUser + UserTenantRole
|
||||
- test_invite_accept_rejects_expired: expired invitation returns error
|
||||
- test_invite_resend_updates_token: resend generates new token_hash and extends expires_at
|
||||
- test_auth_verify_returns_role: auth/verify response contains role field (not is_admin)
|
||||
- test_auth_verify_returns_tenant_ids: auth/verify response contains tenant_ids list
|
||||
- test_auth_verify_returns_active_tenant: auth/verify response contains active_tenant_id
|
||||
</behavior>
|
||||
<action>
|
||||
Create `tests/unit/test_rbac_guards.py`:
|
||||
@@ -309,18 +317,27 @@ class AuditEvent(Base): # Reuse for impersonation logging in Plan 03
|
||||
- Test invitation acceptance via POST /api/portal/invitations/accept (mock DB session with pending invitation)
|
||||
- Test resend updates token_hash and extends expires_at
|
||||
|
||||
Create `tests/unit/test_portal_auth.py`:
|
||||
- Test the updated auth/verify endpoint returns role (not is_admin) in the response
|
||||
- Test auth/verify returns tenant_ids as a list of UUID strings for a user with UserTenantRole memberships
|
||||
- Test auth/verify returns active_tenant_id as the first tenant ID (or None for users with no memberships)
|
||||
- Test auth/verify for platform_admin returns all tenant IDs from the tenants table
|
||||
- Test auth/verify for customer_admin returns only tenant IDs from their UserTenantRole rows
|
||||
- Mock the DB session with appropriate PortalUser (role field) and UserTenantRole rows
|
||||
- Use httpx.AsyncClient with the app, following existing test patterns (make_app(session) factory)
|
||||
|
||||
Follow existing test patterns: use `make_app(session)` factory from tests/ or direct httpx.AsyncClient with app.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/adelorenzo/repos/konstruct && pytest tests/unit/test_rbac_guards.py tests/unit/test_invitations.py -x -v</automated>
|
||||
<automated>cd /home/adelorenzo/repos/konstruct && pytest tests/unit/test_rbac_guards.py tests/unit/test_invitations.py tests/unit/test_portal_auth.py -x -v</automated>
|
||||
</verify>
|
||||
<done>All RBAC guard unit tests pass. All invitation token and API unit tests pass. Coverage includes platform_admin bypass, tenant membership checks, token tampering, and expiry validation.</done>
|
||||
<done>All RBAC guard unit tests pass. All invitation token and API unit tests pass. All portal auth unit tests pass verifying role + tenant_ids claims. Coverage includes platform_admin bypass, tenant membership checks, token tampering, expiry validation, and auth/verify response shape.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- `pytest tests/unit/test_rbac_guards.py tests/unit/test_invitations.py -x -v` — all pass
|
||||
- `pytest tests/unit/test_rbac_guards.py tests/unit/test_invitations.py tests/unit/test_portal_auth.py -x -v` — all pass
|
||||
- `python -c "from shared.models.auth import UserRole; assert len(UserRole) == 3"` — enum has 3 values
|
||||
- `python -c "from shared.api.rbac import require_platform_admin"` — guard imports clean
|
||||
- `python -c "from shared.invite_token import generate_invite_token, validate_invite_token"` — token utils import clean
|
||||
@@ -335,7 +352,7 @@ class AuditEvent(Base): # Reuse for impersonation logging in Plan 03
|
||||
- HMAC invite tokens generate and validate with 48h TTL
|
||||
- SMTP email utility exists (sync, for Celery)
|
||||
- Auth/verify returns role + tenant_ids
|
||||
- All unit tests pass
|
||||
- All unit tests pass (including test_portal_auth.py for JWT callback claims)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
|
||||
Reference in New Issue
Block a user