Implements specs 070–072 (workspace foundation, workspace-scoped tenant selection, managed-tenants workspace enforcement).
Highlights
- Adds Workspace + WorkspaceMembership models/migrations + middleware to persist/enforce current workspace context.
- Scopes tenant selection to the current workspace.
- Makes legacy `/admin/managed-tenants*` routes redirect into workspace-scoped URLs.
- Enforces tenant routes under `/admin/t/{tenant}` to 404 when workspace context is missing or mismatched.
- Fixes Filament page Blade wrappers so header actions render on choose-workspace / choose-tenant / no-access pages.
Verification
- Pint: `vendor/bin/sail bin pint --dirty`
- Tests: `vendor/bin/sail artisan test --compact tests/Feature/Guards/NoAdHocFilamentAuthPatternsTest.php tests/Feature/Workspaces tests/Feature/Filament/ChooseTenantIsWorkspaceScopedTest.php tests/Feature/Filament/ChooseTenantRequiresWorkspaceTest.php tests/Feature/Filament/TenantSwitcherUrlResolvesTenantTest.php tests/Feature/ManagedTenants tests/Feature/AdminNewRedirectTest.php`
Notes
- Filament v5 / Livewire v4 compatible.
- Panel provider registration stays in `bootstrap/providers.php` (Laravel 11+ rule).
- No new heavy frontend assets added.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #85
91 lines
2.4 KiB
PHP
91 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Support\Auth;
|
|
|
|
/**
|
|
* Canonical Capability Registry
|
|
*
|
|
* This is the single source of truth for all capability strings in the system.
|
|
* All role-to-capability mappings must reference only these constants.
|
|
*/
|
|
class Capabilities
|
|
{
|
|
/**
|
|
* @var array<string>|null
|
|
*/
|
|
private static ?array $all = null;
|
|
|
|
// Workspaces
|
|
public const WORKSPACE_VIEW = 'workspace.view';
|
|
|
|
public const WORKSPACE_MANAGE = 'workspace.manage';
|
|
|
|
public const WORKSPACE_ARCHIVE = 'workspace.archive';
|
|
|
|
// Workspace memberships
|
|
public const WORKSPACE_MEMBERSHIP_VIEW = 'workspace_membership.view';
|
|
|
|
public const WORKSPACE_MEMBERSHIP_MANAGE = 'workspace_membership.manage';
|
|
|
|
// Tenants
|
|
public const TENANT_VIEW = 'tenant.view';
|
|
|
|
public const TENANT_MANAGE = 'tenant.manage';
|
|
|
|
public const TENANT_DELETE = 'tenant.delete';
|
|
|
|
public const TENANT_SYNC = 'tenant.sync';
|
|
|
|
// Inventory
|
|
public const TENANT_INVENTORY_SYNC_RUN = 'tenant_inventory_sync.run';
|
|
|
|
// Findings
|
|
public const TENANT_FINDINGS_ACKNOWLEDGE = 'tenant_findings.acknowledge';
|
|
|
|
// Tenant memberships
|
|
public const TENANT_MEMBERSHIP_VIEW = 'tenant_membership.view';
|
|
|
|
public const TENANT_MEMBERSHIP_MANAGE = 'tenant_membership.manage';
|
|
|
|
// Optional mappings (no Graph resolution in v1)
|
|
public const TENANT_ROLE_MAPPING_VIEW = 'tenant_role_mapping.view';
|
|
|
|
public const TENANT_ROLE_MAPPING_MANAGE = 'tenant_role_mapping.manage';
|
|
|
|
// Backup schedules
|
|
public const TENANT_BACKUP_SCHEDULES_MANAGE = 'tenant_backup_schedules.manage';
|
|
|
|
public const TENANT_BACKUP_SCHEDULES_RUN = 'tenant_backup_schedules.run';
|
|
|
|
// Providers (existing gate names used throughout the app)
|
|
public const PROVIDER_VIEW = 'provider.view';
|
|
|
|
public const PROVIDER_MANAGE = 'provider.manage';
|
|
|
|
public const PROVIDER_RUN = 'provider.run';
|
|
|
|
// Audit
|
|
public const AUDIT_VIEW = 'audit.view';
|
|
|
|
/**
|
|
* Get all capability constants
|
|
*
|
|
* @return array<string>
|
|
*/
|
|
public static function all(): array
|
|
{
|
|
if (self::$all !== null) {
|
|
return self::$all;
|
|
}
|
|
|
|
$reflection = new \ReflectionClass(self::class);
|
|
|
|
return self::$all = array_values($reflection->getConstants());
|
|
}
|
|
|
|
public static function isKnown(string $capability): bool
|
|
{
|
|
return in_array($capability, self::all(), true);
|
|
}
|
|
}
|