Committing and publishing the current Spec 420 package changes. Includes updated services, coverage tests, browser smoke coverage, and the spec/plan/tasks artifacts for the package. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #487
113 lines
4.3 KiB
PHP
113 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Jobs\TenantConfiguration\CaptureTenantConfigurationEvidenceJob;
|
|
use App\Models\OperationRun;
|
|
use App\Models\ProviderConnection;
|
|
use App\Services\Audit\AuditRecorder;
|
|
use App\Services\Graph\GraphClientInterface;
|
|
use App\Services\Graph\GraphResponse;
|
|
use App\Services\OperationRunService;
|
|
use App\Services\TenantConfiguration\GenericContentEvidenceCaptureService;
|
|
use App\Services\TenantConfiguration\ResourceTypeRegistry;
|
|
use App\Services\TenantConfiguration\StartTenantConfigurationCapture;
|
|
use App\Support\OperationRunOutcome;
|
|
use App\Support\OperationRunStatus;
|
|
use App\Support\OperationRunType;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
|
|
it('Spec420 rejects cross-environment provider connections before run creation', function (): void {
|
|
Queue::fake();
|
|
|
|
[$user, $environment] = createMinimalUserWithTenant(role: 'owner');
|
|
[, $otherEnvironment] = createMinimalUserWithTenant(role: 'owner');
|
|
$foreignConnection = ProviderConnection::factory()->create([
|
|
'workspace_id' => (int) $otherEnvironment->workspace_id,
|
|
'managed_environment_id' => (int) $otherEnvironment->getKey(),
|
|
]);
|
|
|
|
expect(fn () => app(StartTenantConfigurationCapture::class)->start($environment, $foreignConnection, $user, [
|
|
'conditionalAccessPolicy',
|
|
]))->toThrow(NotFoundHttpException::class);
|
|
|
|
Queue::assertNothingPushed();
|
|
});
|
|
|
|
it('Spec420 revalidates provider connection scope in the queued job before graph work', function (): void {
|
|
app(ResourceTypeRegistry::class)->syncDefaults();
|
|
|
|
[$user, $environment] = createMinimalUserWithTenant(role: 'owner');
|
|
[, $otherEnvironment] = createMinimalUserWithTenant(role: 'owner');
|
|
$foreignConnection = ProviderConnection::factory()->withCredential()->create([
|
|
'workspace_id' => (int) $otherEnvironment->workspace_id,
|
|
'managed_environment_id' => (int) $otherEnvironment->getKey(),
|
|
]);
|
|
$graph = spec420ScopeGraphClient();
|
|
app()->instance(GraphClientInterface::class, $graph);
|
|
|
|
$run = OperationRun::factory()->withUser($user)->forTenant($environment)->create([
|
|
'type' => OperationRunType::TenantConfigurationCapture->value,
|
|
'status' => OperationRunStatus::Queued->value,
|
|
'outcome' => OperationRunOutcome::Pending->value,
|
|
'context' => [
|
|
'target_scope' => [
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'provider_connection_id' => (int) $foreignConnection->getKey(),
|
|
],
|
|
'resource_types' => ['conditionalAccessPolicy'],
|
|
'required_capability' => 'evidence.manage',
|
|
],
|
|
]);
|
|
|
|
expect(fn () => app(CaptureTenantConfigurationEvidenceJob::class, ['run' => $run])->handle(
|
|
app(GenericContentEvidenceCaptureService::class),
|
|
app(OperationRunService::class),
|
|
app(AuditRecorder::class),
|
|
))->toThrow(RuntimeException::class, 'same-scope provider connection');
|
|
|
|
expect($graph->calls)->toBe([]);
|
|
});
|
|
|
|
function spec420ScopeGraphClient(): GraphClientInterface
|
|
{
|
|
return new class implements GraphClientInterface
|
|
{
|
|
public array $calls = [];
|
|
|
|
public function listPolicies(string $policyType, array $options = []): GraphResponse
|
|
{
|
|
$this->calls[] = ['policy_type' => $policyType, 'options' => $options];
|
|
|
|
return new GraphResponse(true, []);
|
|
}
|
|
|
|
public function getPolicy(string $policyType, string $policyId, array $options = []): GraphResponse
|
|
{
|
|
return new GraphResponse(false, [], 501);
|
|
}
|
|
|
|
public function getOrganization(array $options = []): GraphResponse
|
|
{
|
|
return new GraphResponse(false, [], 501);
|
|
}
|
|
|
|
public function applyPolicy(string $policyType, string $policyId, array $payload, array $options = []): GraphResponse
|
|
{
|
|
return new GraphResponse(false, [], 501);
|
|
}
|
|
|
|
public function getServicePrincipalPermissions(array $options = []): GraphResponse
|
|
{
|
|
return new GraphResponse(false, [], 501);
|
|
}
|
|
|
|
public function request(string $method, string $path, array $options = []): GraphResponse
|
|
{
|
|
return new GraphResponse(false, [], 501);
|
|
}
|
|
};
|
|
}
|