247 lines
9.1 KiB
PHP
247 lines
9.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Resources\BackupScheduleResource;
|
|
use App\Filament\Resources\BackupScheduleResource\Pages\ListBackupSchedules;
|
|
use App\Filament\Resources\BackupSetResource;
|
|
use App\Filament\Resources\BackupSetResource\Pages\ListBackupSets;
|
|
use App\Filament\Resources\EntraGroupResource;
|
|
use App\Filament\Resources\EntraGroupResource\Pages\ListEntraGroups;
|
|
use App\Filament\Resources\FindingResource;
|
|
use App\Filament\Resources\FindingResource\Pages\ListFindings;
|
|
use App\Filament\Resources\InventoryItemResource;
|
|
use App\Filament\Resources\InventoryItemResource\Pages\ListInventoryItems;
|
|
use App\Filament\Resources\PolicyResource;
|
|
use App\Filament\Resources\PolicyResource\Pages\ListPolicies;
|
|
use App\Filament\Resources\PolicyVersionResource;
|
|
use App\Filament\Resources\PolicyVersionResource\Pages\ListPolicyVersions;
|
|
use App\Filament\Resources\RestoreRunResource;
|
|
use App\Filament\Resources\RestoreRunResource\Pages\ListRestoreRuns;
|
|
use App\Models\BackupSchedule;
|
|
use App\Models\BackupSet;
|
|
use App\Models\EntraGroup;
|
|
use App\Models\Finding;
|
|
use App\Models\InventoryItem;
|
|
use App\Models\Policy;
|
|
use App\Models\PolicyVersion;
|
|
use App\Models\RestoreRun;
|
|
use App\Models\Tenant;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Filament\Facades\Filament;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Livewire\Livewire;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
function tenantOwnedAdminSession(Tenant $tenant): array
|
|
{
|
|
return [
|
|
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
|
WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY => [
|
|
(string) $tenant->workspace_id => (int) $tenant->getKey(),
|
|
],
|
|
];
|
|
}
|
|
|
|
dataset('tenant-owned-list-pages', [
|
|
'policy list' => [
|
|
ListPolicies::class,
|
|
static fn (Tenant $tenant, string $label): Policy => Policy::factory()->for($tenant)->create([
|
|
'display_name' => $label,
|
|
]),
|
|
],
|
|
'policy-version list' => [
|
|
ListPolicyVersions::class,
|
|
static function (Tenant $tenant, string $label): PolicyVersion {
|
|
$policy = Policy::factory()->for($tenant)->create([
|
|
'display_name' => $label.' policy',
|
|
]);
|
|
|
|
return PolicyVersion::factory()->for($tenant)->for($policy)->create([
|
|
'version_number' => random_int(1, 9999),
|
|
]);
|
|
},
|
|
],
|
|
'backup-schedule list' => [
|
|
ListBackupSchedules::class,
|
|
static function (Tenant $tenant, string $label): BackupSchedule {
|
|
return BackupSchedule::create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'name' => $label,
|
|
'is_enabled' => true,
|
|
'timezone' => 'UTC',
|
|
'frequency' => 'daily',
|
|
'time_of_day' => '10:00:00',
|
|
'days_of_week' => null,
|
|
'policy_types' => ['deviceConfiguration'],
|
|
'include_foundations' => true,
|
|
'retention_keep_last' => 30,
|
|
'next_run_at' => now()->addHour(),
|
|
]);
|
|
},
|
|
],
|
|
'backup-set list' => [
|
|
ListBackupSets::class,
|
|
static fn (Tenant $tenant, string $label): BackupSet => BackupSet::factory()->for($tenant)->create([
|
|
'name' => $label,
|
|
]),
|
|
],
|
|
'restore-run list' => [
|
|
ListRestoreRuns::class,
|
|
static function (Tenant $tenant, string $label): RestoreRun {
|
|
$backupSet = BackupSet::factory()->for($tenant)->create([
|
|
'name' => $label.' backup set',
|
|
]);
|
|
|
|
return RestoreRun::factory()->for($tenant)->for($backupSet)->create();
|
|
},
|
|
],
|
|
'inventory-item list' => [
|
|
ListInventoryItems::class,
|
|
static fn (Tenant $tenant, string $label): InventoryItem => InventoryItem::factory()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'display_name' => $label,
|
|
]),
|
|
],
|
|
'finding list' => [
|
|
ListFindings::class,
|
|
static fn (Tenant $tenant, string $label): Finding => Finding::factory()->for($tenant)->create(),
|
|
],
|
|
'entra-group list' => [
|
|
ListEntraGroups::class,
|
|
static fn (Tenant $tenant, string $label): EntraGroup => EntraGroup::factory()->for($tenant)->create([
|
|
'display_name' => $label,
|
|
]),
|
|
],
|
|
]);
|
|
|
|
dataset('tenant-owned-detail-pages', [
|
|
'policy view' => [
|
|
PolicyResource::class,
|
|
'view',
|
|
static fn (Tenant $tenant, string $label): Policy => Policy::factory()->for($tenant)->create([
|
|
'display_name' => $label,
|
|
]),
|
|
],
|
|
'policy-version view' => [
|
|
PolicyVersionResource::class,
|
|
'view',
|
|
static function (Tenant $tenant, string $label): PolicyVersion {
|
|
$policy = Policy::factory()->for($tenant)->create([
|
|
'display_name' => $label.' policy',
|
|
]);
|
|
|
|
return PolicyVersion::factory()->for($tenant)->for($policy)->create([
|
|
'version_number' => random_int(1, 9999),
|
|
]);
|
|
},
|
|
],
|
|
'backup-set view' => [
|
|
BackupSetResource::class,
|
|
'view',
|
|
static fn (Tenant $tenant, string $label): BackupSet => BackupSet::factory()->for($tenant)->create([
|
|
'name' => $label,
|
|
]),
|
|
],
|
|
'restore-run view' => [
|
|
RestoreRunResource::class,
|
|
'view',
|
|
static function (Tenant $tenant, string $label): RestoreRun {
|
|
$backupSet = BackupSet::factory()->for($tenant)->create([
|
|
'name' => $label.' backup set',
|
|
]);
|
|
|
|
return RestoreRun::factory()->for($tenant)->for($backupSet)->create();
|
|
},
|
|
],
|
|
'inventory-item view' => [
|
|
InventoryItemResource::class,
|
|
'view',
|
|
static fn (Tenant $tenant, string $label): InventoryItem => InventoryItem::factory()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'display_name' => $label,
|
|
]),
|
|
],
|
|
'finding view' => [
|
|
FindingResource::class,
|
|
'view',
|
|
static fn (Tenant $tenant, string $label): Finding => Finding::factory()->for($tenant)->create(),
|
|
],
|
|
'entra-group view' => [
|
|
EntraGroupResource::class,
|
|
'view',
|
|
static fn (Tenant $tenant, string $label): EntraGroup => EntraGroup::factory()->for($tenant)->create([
|
|
'display_name' => $label,
|
|
]),
|
|
],
|
|
'backup-schedule edit' => [
|
|
BackupScheduleResource::class,
|
|
'edit',
|
|
static function (Tenant $tenant, string $label): BackupSchedule {
|
|
return BackupSchedule::create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'name' => $label,
|
|
'is_enabled' => true,
|
|
'timezone' => 'UTC',
|
|
'frequency' => 'daily',
|
|
'time_of_day' => '10:00:00',
|
|
'days_of_week' => null,
|
|
'policy_types' => ['deviceConfiguration'],
|
|
'include_foundations' => true,
|
|
'retention_keep_last' => 30,
|
|
'next_run_at' => now()->addHour(),
|
|
]);
|
|
},
|
|
],
|
|
]);
|
|
|
|
it('scopes covered tenant-owned admin lists to the remembered canonical tenant', function (string $pageClass, Closure $makeRecord): void {
|
|
$tenantA = Tenant::factory()->create();
|
|
[$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');
|
|
$tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]);
|
|
createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner');
|
|
|
|
$allowed = $makeRecord($tenantA, 'Allowed record');
|
|
$blocked = $makeRecord($tenantB, 'Blocked record');
|
|
|
|
$this->actingAs($user);
|
|
Filament::setCurrentPanel('admin');
|
|
Filament::setTenant(null, true);
|
|
Filament::bootCurrentPanel();
|
|
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id);
|
|
session()->put(WorkspaceContext::LAST_TENANT_IDS_SESSION_KEY, [
|
|
(string) $tenantA->workspace_id => (int) $tenantA->getKey(),
|
|
]);
|
|
|
|
Livewire::actingAs($user)->test($pageClass)
|
|
->assertCanSeeTableRecords([$allowed])
|
|
->assertCanNotSeeTableRecords([$blocked]);
|
|
})->with('tenant-owned-list-pages');
|
|
|
|
it('returns not found for covered tenant-owned admin detail pages outside the remembered canonical tenant', function (string $resourceClass, string $page, Closure $makeRecord): void {
|
|
$tenantA = Tenant::factory()->create();
|
|
[$user, $tenantA] = createUserWithTenant(tenant: $tenantA, role: 'owner');
|
|
$tenantB = Tenant::factory()->create(['workspace_id' => (int) $tenantA->workspace_id]);
|
|
createUserWithTenant(tenant: $tenantB, user: $user, role: 'owner');
|
|
|
|
$allowed = $makeRecord($tenantA, 'Allowed record');
|
|
$blocked = $makeRecord($tenantB, 'Blocked record');
|
|
|
|
$this->actingAs($user);
|
|
Filament::setCurrentPanel('admin');
|
|
Filament::setTenant(null, true);
|
|
Filament::bootCurrentPanel();
|
|
|
|
$session = tenantOwnedAdminSession($tenantA);
|
|
|
|
$this->withSession($session)
|
|
->get($resourceClass::getUrl($page, ['record' => $allowed], panel: 'admin'))
|
|
->assertSuccessful();
|
|
|
|
$this->withSession($session)
|
|
->get($resourceClass::getUrl($page, ['record' => $blocked], panel: 'admin'))
|
|
->assertNotFound();
|
|
})->with('tenant-owned-detail-pages');
|