$payload * @param array $sourceMetadata */ public function upsert( ManagedEnvironment $tenant, ProviderConnection $providerConnection, TenantConfigurationResourceType $resourceType, array $payload, array $sourceMetadata = [], ): TenantConfigurationResource { $this->assertScoped($tenant, $providerConnection); $identity = $this->identityEvaluator->evaluate( result: $this->identityResolver->resolve($resourceType, $payload, $sourceMetadata), tenant: $tenant, providerConnection: $providerConnection, resourceType: $resourceType, ); $canonicalType = (string) $resourceType->canonical_type; $sourceClass = $resourceType->source_class instanceof SourceClass ? $resourceType->source_class->value : (string) $resourceType->source_class; $claimState = $this->claimStateFor($resourceType, $identity); $resource = TenantConfigurationResource::query()->firstOrNew([ 'workspace_id' => (int) $tenant->workspace_id, 'managed_environment_id' => (int) $tenant->getKey(), 'provider_connection_id' => (int) $providerConnection->getKey(), 'resource_type_id' => (int) $resourceType->getKey(), 'canonical_resource_key' => $identity->canonicalResourceKey, ]); $resource->fill([ 'source_class' => $sourceClass, 'canonical_type' => $canonicalType, 'canonical_key_kind' => $identity->keyKind->value, 'source_resource_id' => $identity->sourceResourceId, 'source_display_name' => $this->extractDisplayName($payload), 'source_metadata' => $this->jsonObject($sourceMetadata), 'identity_strategy' => $identity->strategyIdentifier, 'source_identity' => $identity->sourceIdentity, 'secondary_identity_keys' => $this->jsonObject($identity->secondaryKeys), 'identity_diagnostics' => $this->jsonObject($identity->diagnostics), 'identity_evaluated_at' => now(), 'latest_identity_state' => $identity->identityState->value, 'latest_claim_state' => $claimState->value, ]); if (! $resource->exists) { $resource->forceFill([ 'latest_evidence_state' => EvidenceState::NotCaptured->value, ]); } $resource->save(); return $resource; } private function claimStateFor( TenantConfigurationResourceType $resourceType, CanonicalIdentityResult $identity, ): ClaimState { $guarded = $this->claimGuard->evaluate( scopeKey: 'intune_tcm_core', requestedLevel: $resourceType->default_coverage_level, actualLevel: $resourceType->default_coverage_level, scopeComplete: true, sourceClass: $resourceType->source_class, restoreTier: $resourceType->restore_tier, identityState: $identity->identityState, allowsBetaClaims: (bool) $resourceType->allows_beta_claims, allowsCertifiedClaims: (bool) $resourceType->allows_certified_claims, allowsDerivedIdentityClaims: $identity->derivedClaimsAllowed, ); $default = $resourceType->default_claim_state; $default = $default instanceof ClaimState ? $default : ClaimState::from((string) $default); return $this->mostRestrictiveClaimState($guarded, $default); } private function mostRestrictiveClaimState(ClaimState $guarded, ClaimState $default): ClaimState { return $this->claimStateRank($guarded) >= $this->claimStateRank($default) ? $guarded : $default; } private function claimStateRank(ClaimState $claimState): int { return match ($claimState) { ClaimState::ClaimAllowed => 0, ClaimState::ClaimLimited => 10, ClaimState::InternalOnly => 20, ClaimState::ClaimBlocked => 30, }; } private function jsonObject(array $value): array|object { return $value === [] ? (object) [] : $value; } private function assertScoped(ManagedEnvironment $tenant, ProviderConnection $providerConnection): void { if ((int) $providerConnection->managed_environment_id !== (int) $tenant->getKey()) { throw new InvalidArgumentException('Provider connection does not belong to the managed environment.'); } if ((int) $providerConnection->workspace_id !== (int) $tenant->workspace_id) { throw new InvalidArgumentException('Provider connection does not belong to the managed environment workspace.'); } } /** * @param array $payload */ private function extractDisplayName(array $payload): ?string { $displayName = $payload['displayName'] ?? $payload['name'] ?? null; if (! is_scalar($displayName)) { return null; } $displayName = trim((string) $displayName); return $displayName !== '' ? $displayName : null; } }