/", "/'app_client_secret'\\s*=>/", '/->app_client_id\s*=/', '/->app_client_secret\s*=/', ]; /** @var Collection $files */ $files = collect($directories) ->filter(fn (string $dir): bool => is_dir($dir)) ->flatMap(function (string $dir): array { $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS) ); $paths = []; foreach ($iterator as $file) { if (! $file->isFile()) { continue; } $path = $file->getPathname(); if (! str_ends_with($path, '.php')) { continue; } $paths[] = $path; } return $paths; }) ->filter(function (string $path) use ($excludedPaths, $self): bool { if ($self && realpath($path) === $self) { return false; } foreach ($excludedPaths as $excluded) { if (str_starts_with($path, $excluded)) { return false; } } return true; }) ->values(); $hits = []; foreach ($files as $path) { $relative = str_replace($root.'/', '', $path); if (in_array($relative, $allowlist, true)) { continue; } $contents = file_get_contents($path); if (! is_string($contents) || $contents === '') { continue; } foreach ($forbiddenPatterns as $pattern) { if (! preg_match($pattern, $contents)) { continue; } $lines = preg_split('/\R/', $contents) ?: []; foreach ($lines as $index => $line) { if (preg_match($pattern, $line)) { $hits[] = $relative.':'.($index + 1).' -> '.trim($line); } } } } expect($hits)->toBeEmpty("Legacy tenant credential writes detected:\n".implode("\n", $hits)); }); it('Spec081 blocks new runtime reads of legacy tenant credentials outside the current cutover allowlist', function (): void { $root = base_path(); $self = realpath(__FILE__); $directories = [ $root.'/app', ]; $excludedPaths = [ $root.'/vendor', $root.'/storage', $root.'/specs', $root.'/spechistory', $root.'/references', $root.'/bootstrap/cache', ]; $allowlist = [ // NOTE: Shrink this list while finishing Spec081 service cutovers. 'app/Models/Tenant.php', 'app/Filament/Resources/TenantResource.php', 'app/Services/Intune/TenantConfigService.php', 'app/Services/Intune/TenantPermissionService.php', 'app/Console/Commands/ReclassifyEnrollmentConfigurations.php', 'app/Console/Commands/TenantpilotBackfillMicrosoftDefaultProviderConnections.php', 'app/Services/Providers/ProviderConnectionBackfillService.php', ]; $forbiddenPatterns = [ '/->app_client_id\b/', '/->app_client_secret\b/', ]; /** @var Collection $files */ $files = collect($directories) ->filter(fn (string $dir): bool => is_dir($dir)) ->flatMap(function (string $dir): array { $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS) ); $paths = []; foreach ($iterator as $file) { if (! $file->isFile()) { continue; } $path = $file->getPathname(); if (! str_ends_with($path, '.php')) { continue; } $paths[] = $path; } return $paths; }) ->filter(function (string $path) use ($excludedPaths, $self): bool { if ($self && realpath($path) === $self) { return false; } foreach ($excludedPaths as $excluded) { if (str_starts_with($path, $excluded)) { return false; } } return true; }) ->values(); $hits = []; foreach ($files as $path) { $relative = str_replace($root.'/', '', $path); if (in_array($relative, $allowlist, true)) { continue; } $contents = file_get_contents($path); if (! is_string($contents) || $contents === '') { continue; } foreach ($forbiddenPatterns as $pattern) { if (! preg_match($pattern, $contents)) { continue; } $lines = preg_split('/\R/', $contents) ?: []; foreach ($lines as $index => $line) { if (preg_match($pattern, $line)) { $hits[] = $relative.':'.($index + 1).' -> '.trim($line); } } } } expect($hits)->toBeEmpty( "Legacy tenant credential reads found outside allowlist (shrink allowlist over time):\n".implode("\n", $hits) ); }); it('Spec081 blocks Tenant::graphOptions helper usage in cutover runtime services and workers', function (): void { $root = base_path(); $files = [ 'app/Services/Inventory/InventorySyncService.php', 'app/Services/Graph/ScopeTagResolver.php', 'app/Services/Intune/PolicySyncService.php', 'app/Services/Intune/PolicySnapshotService.php', 'app/Services/Intune/RestoreService.php', 'app/Services/Intune/RbacOnboardingService.php', 'app/Services/Intune/RbacHealthService.php', 'app/Jobs/SyncPoliciesJob.php', 'app/Jobs/Operations/TenantSyncWorkerJob.php', 'app/Jobs/Operations/CapturePolicySnapshotWorkerJob.php', 'app/Jobs/ExecuteRestoreRunJob.php', ]; $hits = []; foreach ($files as $relativePath) { $absolutePath = $root.'/'.$relativePath; if (! is_file($absolutePath)) { continue; } $contents = file_get_contents($absolutePath); if (! is_string($contents) || $contents === '') { continue; } if (! preg_match('/\$tenant->graphOptions\(|Tenant::graphOptions\(/', $contents)) { continue; } $lines = preg_split('/\R/', $contents) ?: []; foreach ($lines as $index => $line) { if (preg_match('/\$tenant->graphOptions\(|Tenant::graphOptions\(/', $line)) { $hits[] = $relativePath.':'.($index + 1).' -> '.trim($line); } } } expect($hits)->toBeEmpty("Tenant::graphOptions usage detected in cutover runtime paths:\n".implode("\n", $hits)); }); it('Spec081 enforces ProviderGateway as the single runtime entry point for provider credential reads', function (): void { $root = base_path(); $self = realpath(__FILE__); $directories = [ $root.'/app', ]; $excludedPaths = [ $root.'/vendor', $root.'/storage', $root.'/specs', $root.'/spechistory', $root.'/references', $root.'/bootstrap/cache', ]; $allowlist = [ 'app/Services/Providers/CredentialManager.php', 'app/Services/Providers/ProviderGateway.php', ]; $forbiddenPattern = '/->getClientCredentials\(/'; /** @var Collection $files */ $files = collect($directories) ->filter(fn (string $dir): bool => is_dir($dir)) ->flatMap(function (string $dir): array { $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS) ); $paths = []; foreach ($iterator as $file) { if (! $file->isFile()) { continue; } $path = $file->getPathname(); if (! str_ends_with($path, '.php')) { continue; } $paths[] = $path; } return $paths; }) ->filter(function (string $path) use ($excludedPaths, $self): bool { if ($self && realpath($path) === $self) { return false; } foreach ($excludedPaths as $excluded) { if (str_starts_with($path, $excluded)) { return false; } } return true; }) ->values(); $hits = []; foreach ($files as $path) { $relative = str_replace($root.'/', '', $path); if (in_array($relative, $allowlist, true)) { continue; } $contents = file_get_contents($path); if (! is_string($contents) || $contents === '') { continue; } if (! preg_match($forbiddenPattern, $contents)) { continue; } $lines = preg_split('/\R/', $contents) ?: []; foreach ($lines as $index => $line) { if (preg_match($forbiddenPattern, $line)) { $hits[] = $relative.':'.($index + 1).' -> '.trim($line); } } } expect($hits)->toBeEmpty( "Direct CredentialManager::getClientCredentials usage detected outside ProviderGateway:\n".implode("\n", $hits) ); });