TenantAtlas/apps/platform/app/Services/Auth/RoleCapabilityMap.php
ahmido 2f45ff5a84 feat: add portfolio triage review state tracking (#220)
## Summary
- add tenant triage review-state persistence, fingerprinting, resolver logic, service layer, and migration for current affected-set tracking
- surface review-state and affected-set progress across tenant registry, tenant dashboard arrival continuity, and workspace overview
- extend RBAC, audit/badge support, specs, and test coverage for portfolio triage review-state workflows
- suppress expected hidden-page background transport failures in the global unhandled rejection logger while keeping visible-page failures logged

## Validation
- targeted Pest coverage added for tenant registry, workspace overview, arrival context, RBAC authorization, badges, fingerprinting, resolver behavior, and logger asset behavior
- code formatted with `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`

## Notes
- full suite was not re-run in this final step
- branch includes the spec artifacts under `specs/189-portfolio-triage-review-state/`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #220
2026-04-10 21:35:17 +00:00

188 lines
6.0 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::TENANT_TRIAGE_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::TENANT_TRIAGE_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::TENANT_TRIAGE_REVIEW_MANAGE,
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);
}
}