TenantAtlas/specs/083-required-permissions-hardening/tasks.md
ahmido 55166cf9b8 Spec 083: Required permissions hardening (canonical /admin/tenants, DB-only, 404 semantics) (#101)
Implements Spec 083 (Canonical Required Permissions manage surface hardening + issues-first UX).

Highlights:
- Enforces canonical route: /admin/tenants/{tenant}/required-permissions
- Legacy tenant-plane URL /admin/t/{tenant}/required-permissions stays non-existent (404)
- Deny-as-not-found (404) for non-workspace members and non-tenant-entitled users
- Strict tenant resolution (no cross-plane fallback)
- DB-only render (no external provider calls on page load)
- Issues-first layout + canonical next-step links (re-run verification -> /admin/onboarding)
- Freshness/stale detection (missing or >30 days -> warning)

Tests (Sail):
- vendor/bin/sail artisan test --compact tests/Feature/RequiredPermissions
- vendor/bin/sail artisan test --compact tests/Unit/TenantRequiredPermissionsFreshnessTest.php tests/Unit/TenantRequiredPermissionsOverallStatusTest.php

Notes:
- Filament v5 / Livewire v4 compliant.
- No destructive actions added in this spec; link-only CTAs.

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #101
2026-02-08 23:13:25 +00:00

163 lines
8.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
description: "Task list for Spec 083-required-permissions-hardening"
---
# Tasks: 083-required-permissions-hardening
**Input**: Design documents from `/specs/083-required-permissions-hardening/`
- Spec: [spec.md](spec.md)
- Plan: [plan.md](plan.md)
- Research: [research.md](research.md)
- Data model: [data-model.md](data-model.md)
- Contracts: [contracts/routes.md](contracts/routes.md)
- Quickstart: [quickstart.md](quickstart.md)
**Tests**: REQUIRED (Pest) — runtime behavior changes.
## Phase 1: Setup (Shared Infrastructure)
- [X] T001 Run prerequisites check via .specify/scripts/bash/check-prerequisites.sh --json
- [X] T002 Ensure agent context is up to date via .specify/scripts/bash/update-agent-context.sh copilot
- [X] T003 [P] Create feature test directory tests/Feature/RequiredPermissions/ (add .gitkeep if needed)
---
## Phase 2: Foundational (Blocking Prerequisites)
- [X] T004 Review current canonical page implementation in app/Filament/Pages/TenantRequiredPermissions.php (identify tenant fallback + current access checks)
- [X] T005 [P] Review existing DB-only render guard patterns in tests/Feature/Auth/DbOnlyPagesDoNotMakeHttpRequestsTest.php (copy the Http::preventStrayRequests() approach)
- [X] T006 [P] Review existing cross-plane 404 patterns in tests/Feature/Auth/CrossScopeAccessTest.php (align with 404 semantics)
- [X] T007 [P] Confirm factories exist for required models (Workspace, WorkspaceMembership, Tenant, TenantMembership, TenantPermission, User) under database/factories/
**Checkpoint**: Foundational ready — implement US1/US2/US3.
---
## Phase 3: User Story 1 — Required Permissions sicher ansehen (Priority: P1) 🎯 MVP
**Goal**: Canonical manage surface renders issues-first from DB-only state with correct 200/404 semantics.
**Independent Test**: A single GET to `/admin/tenants/{external_id}/required-permissions` returns 200 for tenant-entitled users and triggers no outbound HTTP.
### Tests (US1)
- [X] T008 [P] [US1] Add DB-only render test in tests/Feature/RequiredPermissions/RequiredPermissionsDbOnlyRenderTest.php
- [X] T009 [P] [US1] Add happy-path entitlement test (tenant-entitled → 200) in tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php
- [X] T030 [P] [US1] Add empty-data state test ("Keine Daten verfügbar" + Start verification CTA) in tests/Feature/RequiredPermissions/RequiredPermissionsEmptyStateTest.php
- [X] T031 [P] [US1] Add test that "Technical details" is rendered after Issues/Passed and is collapsed by default in tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php
### Implementation (US1)
- [X] T010 [US1] Enforce explicit 404 denial rules on page entry in app/Filament/Pages/TenantRequiredPermissions.php (workspace selected, tenant in workspace, workspace member, tenant-entitled)
- [X] T011 [US1] Remove cross-plane fallback by making resolveScopedTenant() strict (no Tenant::current()) in app/Filament/Pages/TenantRequiredPermissions.php
- [X] T012 [US1] Add freshness derivation (last_refreshed_at, is_stale) based on tenant_permissions.last_checked_at in app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
- [X] T013 [US1] Update summary overall status derivation to treat stale freshness as a warning (Blocked > Needs attention > Ready) in app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
- [X] T014 [US1] Render Summary → Issues → Passed → Technical layout (issues-first) using viewModel fields in resources/views/filament/pages/tenant-required-permissions.blade.php
- [X] T032 [US1] Render explicit empty-data state and keep "Technical details" collapsed by default in resources/views/filament/pages/tenant-required-permissions.blade.php
---
## Phase 4: User Story 2 — Next steps finden, ohne Mutationsrechte zu benötigen (Priority: P2)
**Goal**: Each issue includes link-only next steps that point to canonical manage surfaces; re-run verification links to Start verification.
**Independent Test**: Page renders next-step links that are canonical and the “Re-run verification” CTA points to `/admin/onboarding`.
### Tests (US2)
- [X] T015 [P] [US2] Add CTA/link assertion test for re-run verification pointing to /admin/onboarding in tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php
- [X] T016 [P] [US2] Add test asserting no legacy tenant-plane links are emitted (no /admin/t/...) in tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php
### Implementation (US2)
- [X] T017 [US2] Change reRunVerificationUrl() to return the canonical Start verification surface via route helper (target: /admin/onboarding) in app/Filament/Pages/TenantRequiredPermissions.php
- [X] T018 [US2] Ensure issue cards only contain link-only next steps and canonical manage URLs in resources/views/filament/pages/tenant-required-permissions.blade.php
---
## Phase 5: User Story 3 — Tenant-Discovery verhindern (Deny-as-not-found) (Priority: P3)
**Goal**: Non-entitled users cannot discover tenant existence/posture via status codes or legacy routes.
**Independent Test**: Requests for non-members/non-entitled return 404, and legacy `/admin/t/{tenant}/required-permissions` is 404.
### Tests (US3)
- [X] T019 [P] [US3] Add test: workspace-member but not tenant-entitled → 404 in tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php
- [X] T020 [P] [US3] Add test: not a workspace member → 404 in tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php
- [X] T021 [P] [US3] Add test: legacy /admin/t/{tenant}/required-permissions returns 404 in tests/Feature/RequiredPermissions/RequiredPermissionsLegacyRouteTest.php
- [X] T022 [P] [US3] Add regression test: route tenant invalid does not fall back to a current tenant context (still 404) in tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php
### Implementation (US3)
- [X] T023 [US3] Ensure all deny-as-not-found conditions abort(404) (not 403) in app/Filament/Pages/TenantRequiredPermissions.php
---
## Phase 6: Polish & Cross-Cutting Concerns
- [X] T024 [P] Update existing unit coverage for overall status if signature/logic changed in tests/Unit/TenantRequiredPermissionsOverallStatusTest.php
- [X] T025 [P] Add new unit tests for freshness/stale threshold (missing or >30 days) in tests/Unit/TenantRequiredPermissionsFreshnessTest.php
- [X] T026 Run formatting via vendor/bin/sail bin pint --dirty
- [X] T027 Run targeted tests via vendor/bin/sail artisan test --compact tests/Feature/RequiredPermissions
- [X] T028 Run targeted unit tests via vendor/bin/sail artisan test --compact tests/Unit/TenantRequiredPermissions
- [X] T029 Validate quickstart steps remain accurate in specs/083-required-permissions-hardening/quickstart.md
---
## Dependencies & Execution Order
### User Story completion order
```mermaid
graph TD
P1[US1: View canonical page safely] --> P2[US2: Canonical next steps links]
P1 --> P3[US3: Deny-as-not-found + legacy 404]
P2 --> Polish[Polish & regression coverage]
P3 --> Polish
```
- Setup (T001T003) → Foundational (T004T007) → US1 (T008T014, T030T032) → US2 (T015T018) + US3 (T019T023) → Polish (T024T029)
### Parallel opportunities
- Phase 1: T003 can run in parallel.
- Phase 2: T005T007 are parallel.
- US1 tests (T008T009, T030T031) can be written in parallel.
- US2 tests (T015T016) can be written in parallel.
- US3 tests (T019T022) can be written in parallel.
- Polish: T024T025 are parallel; T026T028 are sequential validation.
---
## Parallel execution examples (per story)
### US1
- Run in parallel:
- T008: tests/Feature/RequiredPermissions/RequiredPermissionsDbOnlyRenderTest.php
- T009: tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php
- T030: tests/Feature/RequiredPermissions/RequiredPermissionsEmptyStateTest.php
- T031: tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php
### US2
- Run in parallel:
- T015: tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php (CTA)
- T016: tests/Feature/RequiredPermissions/RequiredPermissionsLinksTest.php (no legacy links)
### US3
- Run in parallel:
- T019: tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php (non-entitled 404)
- T020: tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php (non-member 404)
- T021: tests/Feature/RequiredPermissions/RequiredPermissionsLegacyRouteTest.php
- T022: tests/Feature/RequiredPermissions/RequiredPermissionsAccessTest.php (no fallback)
---
## Task completeness validation
- Every user story has:
- At least one independently runnable verification test task
- Implementation tasks with concrete file paths
- A clear checkpoint goal and independent test criteria