Some checks failed
Main Confidence / confidence (push) Failing after 45s
Implements support diagnostics bundle, moves audit writes to action mountUsing to avoid side-effects during render, replaces custom slide-over with Filament-native schema, updates tests and adds spec docs. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #278
187 lines
7.7 KiB
PHP
187 lines
7.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Pages\TenantDashboard;
|
|
use App\Models\AuditLog;
|
|
use App\Models\EvidenceSnapshot;
|
|
use App\Models\Finding;
|
|
use App\Models\OperationRun;
|
|
use App\Models\ProviderConnection;
|
|
use App\Models\ReviewPack;
|
|
use App\Models\StoredReport;
|
|
use App\Models\Tenant;
|
|
use App\Models\TenantReview;
|
|
use App\Models\User;
|
|
use App\Models\WorkspaceMembership;
|
|
use App\Support\Auth\UiTooltips;
|
|
use App\Support\OperationRunOutcome;
|
|
use App\Support\OperationRunStatus;
|
|
use App\Support\OperationRunType;
|
|
use App\Support\Providers\ProviderReasonCodes;
|
|
use App\Support\Providers\ProviderVerificationStatus;
|
|
use App\Support\TenantReviewStatus;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Filament\Actions\Action;
|
|
use Livewire\Livewire;
|
|
|
|
function tenantSupportDiagnosticsComponent(User $user, Tenant $tenant): \Livewire\Features\SupportTesting\Testable
|
|
{
|
|
test()->actingAs($user);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
|
|
setTenantPanelContext($tenant);
|
|
|
|
return Livewire::actingAs($user)->test(TenantDashboard::class);
|
|
}
|
|
|
|
it('opens a redacted tenant support diagnostic bundle from the tenant dashboard', function (): void {
|
|
$tenant = Tenant::factory()->create(['name' => 'Contoso Support Tenant']);
|
|
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'operator');
|
|
|
|
$connection = ProviderConnection::factory()
|
|
->withCredential()
|
|
->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'display_name' => 'Contoso Microsoft connection',
|
|
'verification_status' => ProviderVerificationStatus::Blocked->value,
|
|
'last_error_reason_code' => ProviderReasonCodes::ProviderPermissionMissing,
|
|
'last_error_message' => 'raw-provider-secret-message',
|
|
'last_health_check_at' => now()->subMinutes(15),
|
|
]);
|
|
|
|
$run = OperationRun::factory()
|
|
->forTenant($tenant)
|
|
->create([
|
|
'type' => OperationRunType::BaselineCompare->value,
|
|
'status' => OperationRunStatus::Completed->value,
|
|
'outcome' => OperationRunOutcome::Failed->value,
|
|
'context' => [
|
|
'provider_connection_id' => (int) $connection->getKey(),
|
|
'raw_response_body' => 'secret-provider-body',
|
|
],
|
|
'failure_summary' => [[
|
|
'message' => 'Compare failed after provider permission validation.',
|
|
]],
|
|
'completed_at' => now()->subMinutes(10),
|
|
]);
|
|
|
|
$finding = Finding::factory()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'current_operation_run_id' => (int) $run->getKey(),
|
|
'severity' => Finding::SEVERITY_HIGH,
|
|
'last_seen_at' => now()->subMinutes(8),
|
|
]);
|
|
|
|
StoredReport::factory()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE,
|
|
'payload' => [
|
|
'raw_response_body' => 'stored-report-secret-body',
|
|
],
|
|
'fingerprint' => 'permission-fingerprint',
|
|
]);
|
|
|
|
$evidenceSnapshot = EvidenceSnapshot::query()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'operation_run_id' => (int) $run->getKey(),
|
|
'initiated_by_user_id' => (int) $user->getKey(),
|
|
'fingerprint' => fake()->sha256(),
|
|
'status' => 'active',
|
|
'completeness_state' => 'complete',
|
|
'summary' => [
|
|
'dimension_count' => 1,
|
|
'missing_dimensions' => 0,
|
|
'stale_dimensions' => 0,
|
|
],
|
|
'generated_at' => now()->subMinutes(7),
|
|
]);
|
|
|
|
$review = TenantReview::factory()->ready()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'evidence_snapshot_id' => (int) $evidenceSnapshot->getKey(),
|
|
'operation_run_id' => (int) $run->getKey(),
|
|
'status' => TenantReviewStatus::Ready->value,
|
|
'generated_at' => now()->subMinutes(7),
|
|
]);
|
|
|
|
$pack = ReviewPack::factory()->ready()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'tenant_review_id' => (int) $review->getKey(),
|
|
'operation_run_id' => (int) $run->getKey(),
|
|
'generated_at' => now()->subMinutes(6),
|
|
]);
|
|
|
|
$review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save();
|
|
|
|
AuditLog::query()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'operation_run_id' => (int) $run->getKey(),
|
|
'action' => 'operation.failed',
|
|
'resource_type' => 'operation_run',
|
|
'resource_id' => (string) $run->getKey(),
|
|
'target_label' => 'Operation #'.$run->getKey(),
|
|
'metadata' => [
|
|
'raw_response_body' => 'audit-secret-body',
|
|
'reason_code' => 'provider_permission_missing',
|
|
],
|
|
'outcome' => 'success',
|
|
'recorded_at' => now()->subMinutes(5),
|
|
]);
|
|
|
|
tenantSupportDiagnosticsComponent($user, $tenant)
|
|
->assertActionVisible('openSupportDiagnostics')
|
|
->assertActionEnabled('openSupportDiagnostics')
|
|
->assertActionExists('openSupportDiagnostics', fn (Action $action): bool => $action->getLabel() === 'Open support diagnostics')
|
|
->mountAction('openSupportDiagnostics')
|
|
->assertMountedActionModalSee('Support diagnostics')
|
|
->assertMountedActionModalSee('Contoso Support Tenant')
|
|
->assertMountedActionModalSee('Permissions missing')
|
|
->assertMountedActionModalSee('provider app is missing required Microsoft Graph permissions')
|
|
->assertMountedActionModalSee('Operation #'.$run->getKey())
|
|
->assertMountedActionModalSee('High finding #'.$finding->getKey())
|
|
->assertMountedActionModalSee('permission posture report')
|
|
->assertMountedActionModalSee('Tenant review #'.$review->getKey())
|
|
->assertMountedActionModalSee('Review pack #'.$pack->getKey())
|
|
->assertMountedActionModalSee('Operation failed')
|
|
->assertMountedActionModalSee('default-redacted')
|
|
->assertMountedActionModalSee('[REDACTED]')
|
|
->assertMountedActionModalDontSee('raw-provider-secret-message')
|
|
->assertMountedActionModalDontSee('secret-provider-body')
|
|
->assertMountedActionModalDontSee('stored-report-secret-body')
|
|
->assertMountedActionModalDontSee('audit-secret-body');
|
|
});
|
|
|
|
it('denies non-entitled tenant dashboard access as not found', function (): void {
|
|
$tenant = Tenant::factory()->create();
|
|
$user = User::factory()->create();
|
|
|
|
WorkspaceMembership::factory()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'user_id' => (int) $user->getKey(),
|
|
'role' => 'operator',
|
|
]);
|
|
|
|
$this
|
|
->actingAs($user)
|
|
->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
|
|
->get(TenantDashboard::getUrl(panel: 'tenant', tenant: $tenant))
|
|
->assertNotFound();
|
|
});
|
|
|
|
it('shows support diagnostics as disabled for entitled members without the support capability', function (): void {
|
|
$tenant = Tenant::factory()->create();
|
|
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
|
|
|
|
tenantSupportDiagnosticsComponent($user, $tenant)
|
|
->assertActionVisible('openSupportDiagnostics')
|
|
->assertActionDisabled('openSupportDiagnostics')
|
|
->assertActionExists('openSupportDiagnostics', fn (Action $action): bool => $action->getTooltip() === UiTooltips::insufficientPermission());
|
|
});
|