TenantAtlas/apps/platform/database/factories/ProviderResourceBindingFactory.php
Ahmed Darrazi fb2642e941
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m9s
feat(resources): implement provider resource identity binding
Added ProviderResourceBinding model, migrations, policies, and supporting framework for canonical resource identity mapping as defined in Spec 381.
2026-06-15 17:37:06 +02:00

142 lines
5.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Database\Factories;
use App\Models\ManagedEnvironment;
use App\Models\ProviderResourceBinding;
use App\Models\User;
use App\Support\Baselines\BaselineSubjectKey;
use App\Support\Baselines\SubjectClass;
use App\Support\Resources\ProviderResourceBindingStatus;
use App\Support\Resources\ProviderResourceResolutionMode;
use App\Support\Resources\ResourceIdentity;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<ProviderResourceBinding>
*/
class ProviderResourceBindingFactory extends Factory
{
protected $model = ProviderResourceBinding::class;
/**
* @return array<string, mixed>
*/
public function definition(): array
{
$identity = ResourceIdentity::providerResource('fake-provider', 'policy', fake()->uuid());
$subjectDomain = 'baseline';
$subjectClass = SubjectClass::PolicyBacked;
$subjectTypeKey = 'deviceConfiguration';
return [
'managed_environment_id' => ManagedEnvironment::factory(),
'workspace_id' => function (array $attributes): int {
$tenantId = $attributes['managed_environment_id'] ?? null;
if (! is_numeric($tenantId)) {
return (int) ManagedEnvironment::factory()->create()->workspace_id;
}
$tenant = ManagedEnvironment::query()->whereKey((int) $tenantId)->firstOrFail();
return (int) $tenant->workspace_id;
},
'provider_key' => $identity->providerKey,
'provider_connection_id' => null,
'subject_domain' => $subjectDomain,
'subject_class' => $subjectClass->value,
'subject_type_key' => $subjectTypeKey,
'legacy_subject_key' => null,
'canonical_subject_key' => BaselineSubjectKey::forProviderResourceIdentity(
$subjectDomain,
$subjectClass,
$subjectTypeKey,
$identity,
),
'provider_resource_type' => $identity->providerResourceType,
'provider_resource_id' => $identity->providerResourceId,
'provider_resource_discriminator' => $identity->canonicalDiscriminator,
'provider_resource_identity_kind' => $identity->identityKind,
'provider_resource_fingerprint' => $identity->fingerprint(),
'display_label' => fake()->words(3, true),
'binding_status' => ProviderResourceBindingStatus::Active->value,
'resolution_mode' => ProviderResourceResolutionMode::ExactProviderIdentity->value,
'resolution_reason' => null,
'operator_note' => 'Binding decision recorded for test coverage.',
'source_operation_run_id' => null,
'source_baseline_snapshot_id' => null,
'source_inventory_item_id' => null,
'source_policy_version_id' => null,
'decided_by_user_id' => User::factory(),
'decided_at' => now(),
'ended_at' => null,
];
}
public function fakeProvider(): static
{
return $this->state(fn (): array => [
'provider_key' => 'fake-provider',
]);
}
public function providerResource(?ResourceIdentity $identity = null): static
{
$identity ??= ResourceIdentity::providerResource('fake-provider', 'policy', fake()->uuid());
return $this->withIdentity($identity, ProviderResourceResolutionMode::ExactProviderIdentity);
}
public function canonicalBuiltin(?ResourceIdentity $identity = null): static
{
$identity ??= ResourceIdentity::canonicalBuiltin('fake-provider', 'target', 'all-principals');
return $this->withIdentity($identity, ProviderResourceResolutionMode::CanonicalBuiltin);
}
public function revoked(): static
{
return $this->state(fn (): array => [
'binding_status' => ProviderResourceBindingStatus::Revoked->value,
'ended_at' => now(),
]);
}
public function superseded(): static
{
return $this->state(fn (): array => [
'binding_status' => ProviderResourceBindingStatus::Superseded->value,
'ended_at' => now(),
]);
}
private function withIdentity(ResourceIdentity $identity, ProviderResourceResolutionMode $resolutionMode): static
{
$subjectDomain = 'baseline';
$subjectClass = SubjectClass::PolicyBacked;
$subjectTypeKey = 'deviceConfiguration';
return $this->state(fn (): array => [
'provider_key' => $identity->providerKey,
'subject_domain' => $subjectDomain,
'subject_class' => $subjectClass->value,
'subject_type_key' => $subjectTypeKey,
'canonical_subject_key' => BaselineSubjectKey::forProviderResourceIdentity(
$subjectDomain,
$subjectClass,
$subjectTypeKey,
$identity,
),
'provider_resource_type' => $identity->providerResourceType,
'provider_resource_id' => $identity->providerResourceId,
'provider_resource_discriminator' => $identity->canonicalDiscriminator,
'provider_resource_identity_kind' => $identity->identityKind,
'provider_resource_fingerprint' => $identity->fingerprint(),
'resolution_mode' => $resolutionMode->value,
]);
}
}