'baseline', 'subject_class' => SubjectClass::PolicyBacked, 'subject_type_key' => 'deviceConfiguration', 'operator_note' => 'Authorization test decision note.', ], $overrides); } it('allows managers to create provider resource bindings', function (): void { [$manager, $tenant] = createUserWithTenant(role: 'manager'); $binding = app(ProviderResourceBindingService::class)->createExactProviderIdentity( actor: $manager, environment: $tenant, identity: ResourceIdentity::providerResource('fake-provider', 'policy', 'manager-allowed'), attributes: providerResourceBindingAuthorizationAttributes(), ); expect($binding->exists)->toBeTrue(); }); it('returns forbidden for entitled readonly users missing baseline manage capability', function (): void { [$readonly, $tenant] = createUserWithTenant(role: 'readonly'); try { app(ProviderResourceBindingService::class)->createManualBinding( actor: $readonly, environment: $tenant, identity: ResourceIdentity::providerResource('fake-provider', 'policy', 'readonly-denied'), attributes: providerResourceBindingAuthorizationAttributes(), ); $this->fail('Expected authorization denial.'); } catch (AuthorizationException $exception) { expect($exception->status())->toBe(403); } }); it('returns deny-as-not-found for users outside the binding workspace', function (): void { [$actor] = createUserWithTenant(role: 'owner'); [, $foreignTenant] = createUserWithTenant(role: 'owner'); try { app(ProviderResourceBindingService::class)->createManualBinding( actor: $actor, environment: $foreignTenant, identity: ResourceIdentity::providerResource('fake-provider', 'policy', 'foreign-denied'), attributes: providerResourceBindingAuthorizationAttributes(), ); $this->fail('Expected not-found authorization denial.'); } catch (AuthorizationException $exception) { expect($exception->status())->toBe(404); } }); it('rejects provider connections from another managed environment as not found', function (): void { [$actor, $tenant] = createUserWithTenant(role: 'owner'); [, $foreignTenant] = createUserWithTenant(role: 'owner'); $foreignConnection = ProviderConnection::factory()->create([ 'workspace_id' => (int) $foreignTenant->workspace_id, 'managed_environment_id' => (int) $foreignTenant->getKey(), 'provider' => 'fake-provider', ]); expect(fn () => app(ProviderResourceBindingService::class)->createManualBinding( actor: $actor, environment: $tenant, identity: ResourceIdentity::providerResource('fake-provider', 'policy', 'foreign-connection'), attributes: providerResourceBindingAuthorizationAttributes([ 'provider_connection_id' => (int) $foreignConnection->getKey(), ]), ))->toThrow(ModelNotFoundException::class); }); it('rejects source references from another managed environment as not found', function (): void { [$actor, $tenant] = createUserWithTenant(role: 'owner'); [, $foreignTenant] = createUserWithTenant(role: 'owner'); $foreignInventory = InventoryItem::factory()->create([ 'managed_environment_id' => (int) $foreignTenant->getKey(), ]); expect(fn () => app(ProviderResourceBindingService::class)->createManualBinding( actor: $actor, environment: $tenant, identity: ResourceIdentity::providerResource('fake-provider', 'policy', 'foreign-source'), attributes: providerResourceBindingAuthorizationAttributes([ 'source_inventory_item_id' => (int) $foreignInventory->getKey(), ]), ))->toThrow(ModelNotFoundException::class); }); it('rejects baseline snapshot references not assigned to the binding managed environment as not found', function (): void { [$actor, $tenant] = createUserWithTenant(role: 'owner'); $foreignTenant = ManagedEnvironment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); $foreignProfile = BaselineProfile::factory()->active()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); $foreignSnapshot = BaselineSnapshot::factory()->complete()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'baseline_profile_id' => (int) $foreignProfile->getKey(), ]); BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'managed_environment_id' => (int) $foreignTenant->getKey(), 'baseline_profile_id' => (int) $foreignProfile->getKey(), ]); expect(fn () => app(ProviderResourceBindingService::class)->createManualBinding( actor: $actor, environment: $tenant, identity: ResourceIdentity::providerResource('fake-provider', 'policy', 'foreign-baseline-snapshot'), attributes: providerResourceBindingAuthorizationAttributes([ 'source_baseline_snapshot_id' => (int) $foreignSnapshot->getKey(), ]), ))->toThrow(ModelNotFoundException::class); }); it('uses baseline capabilities in the registered policy', function (): void { [$owner, $tenant] = createUserWithTenant(role: 'owner'); [$readonly] = createUserWithTenant(tenant: $tenant, role: 'readonly'); $binding = ProviderResourceBinding::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'managed_environment_id' => (int) $tenant->getKey(), ]); expect(Gate::forUser($owner)->inspect('revoke', $binding)->allowed())->toBeTrue() ->and(Gate::forUser($readonly)->inspect('view', $binding)->allowed())->toBeTrue() ->and(Gate::forUser($readonly)->inspect('revoke', $binding)->status())->toBe(403); });