TenantAtlas/app/Services/Auth/RoleCapabilityMap.php
ahmido a4f2629493 feat: add tenant review layer (#185)
## Summary
- add the tenant review domain with tenant-scoped review library, canonical workspace review register, lifecycle actions, and review-derived executive pack export
- extend review pack, operations, audit, capability, and badge infrastructure to support review composition, publication, export, and recurring review cycles
- add product backlog and audit documentation updates for tenant review and semantic-clarity follow-up candidates

## Testing
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact --filter="TenantReview"`
- `CI=1 vendor/bin/sail artisan test --compact`

## Notes
- Livewire v4+ compliant via existing Filament v5 stack
- panel providers remain in `bootstrap/providers.php` via existing Laravel 12 structure; no provider registration moved to `bootstrap/app.php`
- `TenantReviewResource` is not globally searchable, so the Filament edit/view global-search constraint does not apply
- destructive review actions use action handlers with confirmation and policy enforcement

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #185
2026-03-21 22:03:01 +00:00

185 lines
5.8 KiB
PHP

<?php
namespace App\Services\Auth;
use App\Support\Auth\Capabilities;
use App\Support\TenantRole;
/**
* Role to Capability Mapping (Single Source of Truth)
*
* This class defines which capabilities each role has.
* All capability strings MUST be references from the Capabilities registry.
*/
class RoleCapabilityMap
{
private static array $roleCapabilities = [
TenantRole::Owner->value => [
Capabilities::TENANT_VIEW,
Capabilities::TENANT_MANAGE,
Capabilities::TENANT_DELETE,
Capabilities::TENANT_SYNC,
Capabilities::TENANT_INVENTORY_SYNC_RUN,
Capabilities::TENANT_FINDINGS_VIEW,
Capabilities::TENANT_FINDINGS_TRIAGE,
Capabilities::TENANT_FINDINGS_ASSIGN,
Capabilities::TENANT_FINDINGS_RESOLVE,
Capabilities::TENANT_FINDINGS_CLOSE,
Capabilities::TENANT_FINDINGS_RISK_ACCEPT,
Capabilities::TENANT_FINDINGS_ACKNOWLEDGE,
Capabilities::FINDING_EXCEPTION_VIEW,
Capabilities::FINDING_EXCEPTION_MANAGE,
Capabilities::TENANT_VERIFICATION_ACKNOWLEDGE,
Capabilities::TENANT_MEMBERSHIP_VIEW,
Capabilities::TENANT_MEMBERSHIP_MANAGE,
Capabilities::TENANT_ROLE_MAPPING_VIEW,
Capabilities::TENANT_ROLE_MAPPING_MANAGE,
Capabilities::TENANT_BACKUP_SCHEDULES_MANAGE,
Capabilities::TENANT_BACKUP_SCHEDULES_RUN,
Capabilities::PROVIDER_VIEW,
Capabilities::PROVIDER_MANAGE,
Capabilities::PROVIDER_MANAGE_DEDICATED,
Capabilities::PROVIDER_RUN,
Capabilities::AUDIT_VIEW,
Capabilities::ENTRA_ROLES_VIEW,
Capabilities::ENTRA_ROLES_MANAGE,
Capabilities::REVIEW_PACK_VIEW,
Capabilities::REVIEW_PACK_MANAGE,
Capabilities::TENANT_REVIEW_VIEW,
Capabilities::TENANT_REVIEW_MANAGE,
Capabilities::EVIDENCE_VIEW,
Capabilities::EVIDENCE_MANAGE,
],
TenantRole::Manager->value => [
Capabilities::TENANT_VIEW,
Capabilities::TENANT_MANAGE,
Capabilities::TENANT_SYNC,
Capabilities::TENANT_INVENTORY_SYNC_RUN,
Capabilities::TENANT_FINDINGS_VIEW,
Capabilities::TENANT_FINDINGS_TRIAGE,
Capabilities::TENANT_FINDINGS_ASSIGN,
Capabilities::TENANT_FINDINGS_RESOLVE,
Capabilities::TENANT_FINDINGS_CLOSE,
Capabilities::TENANT_FINDINGS_RISK_ACCEPT,
Capabilities::TENANT_FINDINGS_ACKNOWLEDGE,
Capabilities::FINDING_EXCEPTION_VIEW,
Capabilities::FINDING_EXCEPTION_MANAGE,
Capabilities::TENANT_VERIFICATION_ACKNOWLEDGE,
Capabilities::TENANT_MEMBERSHIP_VIEW,
Capabilities::TENANT_ROLE_MAPPING_VIEW,
Capabilities::TENANT_BACKUP_SCHEDULES_MANAGE,
Capabilities::TENANT_BACKUP_SCHEDULES_RUN,
Capabilities::PROVIDER_VIEW,
Capabilities::PROVIDER_MANAGE,
Capabilities::PROVIDER_RUN,
Capabilities::AUDIT_VIEW,
Capabilities::ENTRA_ROLES_VIEW,
Capabilities::ENTRA_ROLES_MANAGE,
Capabilities::REVIEW_PACK_VIEW,
Capabilities::REVIEW_PACK_MANAGE,
Capabilities::TENANT_REVIEW_VIEW,
Capabilities::TENANT_REVIEW_MANAGE,
Capabilities::EVIDENCE_VIEW,
Capabilities::EVIDENCE_MANAGE,
],
TenantRole::Operator->value => [
Capabilities::TENANT_VIEW,
Capabilities::TENANT_SYNC,
Capabilities::TENANT_INVENTORY_SYNC_RUN,
Capabilities::TENANT_FINDINGS_VIEW,
Capabilities::TENANT_FINDINGS_TRIAGE,
Capabilities::TENANT_FINDINGS_ACKNOWLEDGE,
Capabilities::FINDING_EXCEPTION_VIEW,
Capabilities::TENANT_MEMBERSHIP_VIEW,
Capabilities::TENANT_ROLE_MAPPING_VIEW,
Capabilities::TENANT_BACKUP_SCHEDULES_RUN,
Capabilities::PROVIDER_VIEW,
Capabilities::PROVIDER_RUN,
Capabilities::AUDIT_VIEW,
Capabilities::ENTRA_ROLES_VIEW,
Capabilities::REVIEW_PACK_VIEW,
Capabilities::TENANT_REVIEW_VIEW,
Capabilities::EVIDENCE_VIEW,
],
TenantRole::Readonly->value => [
Capabilities::TENANT_VIEW,
Capabilities::TENANT_FINDINGS_VIEW,
Capabilities::FINDING_EXCEPTION_VIEW,
Capabilities::TENANT_MEMBERSHIP_VIEW,
Capabilities::TENANT_ROLE_MAPPING_VIEW,
Capabilities::PROVIDER_VIEW,
Capabilities::AUDIT_VIEW,
Capabilities::ENTRA_ROLES_VIEW,
Capabilities::REVIEW_PACK_VIEW,
Capabilities::TENANT_REVIEW_VIEW,
Capabilities::EVIDENCE_VIEW,
],
];
/**
* Get all capabilities for a given role
*
* @return array<string>
*/
public static function getCapabilities(TenantRole|string $role): array
{
$roleValue = $role instanceof TenantRole ? $role->value : $role;
return self::$roleCapabilities[$roleValue] ?? [];
}
/**
* Get all role values that grant a given capability.
*
* @return array<string>
*/
public static function rolesWithCapability(string $capability): array
{
$roles = [];
foreach (self::$roleCapabilities as $role => $capabilities) {
if (in_array($capability, $capabilities, true)) {
$roles[] = $role;
}
}
return $roles;
}
/**
* Check if a role has a specific capability
*/
public static function hasCapability(TenantRole|string $role, string $capability): bool
{
return in_array($capability, self::getCapabilities($role), true);
}
}