session()->pull('tenant_onboard_state'); $workspaceId = $request->session()->pull('tenant_onboard_workspace_id'); $tenantKey = $request->string('tenant')->toString(); $state = $request->string('state')->toString(); $tenantIdentifier = $tenantKey ?: $this->parseState($state); if ($expectedState && $expectedState !== $state) { abort(ResponseAlias::HTTP_FORBIDDEN, 'Invalid consent state'); } abort_if(empty($tenantIdentifier), 404); $tenant = $this->resolveTenant($tenantIdentifier, is_numeric($workspaceId) ? (int) $workspaceId : null); $error = $request->string('error')->toString() ?: null; $consentGranted = $request->has('admin_consent') ? filter_var($request->input('admin_consent'), FILTER_VALIDATE_BOOLEAN) : null; $status = match (true) { $error !== null => 'error', $consentGranted === false => 'consent_denied', $consentGranted === true => 'ok', default => 'pending', }; $connection = $this->upsertProviderConnectionForConsent( tenant: $tenant, status: $status, error: $error, ); $legacyStatus = $status === 'ok' ? 'success' : 'failed'; $auditMetadata = [ 'source' => 'admin.consent.callback', 'workspace_id' => (int) $connection->workspace_id, 'status' => $status, 'state' => $state, 'error' => $error, 'consent' => $consentGranted, 'provider_connection_id' => (int) $connection->getKey(), 'provider' => (string) $connection->provider, 'entra_tenant_id' => (string) $connection->entra_tenant_id, 'connection_type' => $connection->connection_type->value, 'consent_status' => $connection->consent_status->value, 'verification_status' => $connection->verification_status->value, ]; $auditLogger->log( tenant: $tenant, action: 'tenant.consent.callback', context: [ 'metadata' => $auditMetadata, ], status: $legacyStatus, resourceType: 'provider_connection', resourceId: (string) $connection->getKey(), ); $auditLogger->log( tenant: $tenant, action: 'provider_connection.consent_result', context: [ 'metadata' => $auditMetadata, ], status: $legacyStatus, resourceType: 'provider_connection', resourceId: (string) $connection->getKey(), ); return view('admin-consent-callback', [ 'tenant' => $tenant, 'connection' => $connection, 'status' => $status, 'error' => $error, 'consentGranted' => $consentGranted, ]); } private function resolveTenant(string $tenantIdentifier, ?int $workspaceId): Tenant { /** @var Tenant|null $tenant */ $tenant = Tenant::withTrashed() ->forTenant($tenantIdentifier) ->first(); if ($tenant?->trashed()) { $tenant->restore(); } if ($tenant instanceof Tenant) { if ($tenant->workspace_id === null && $workspaceId !== null) { $tenant->forceFill(['workspace_id' => $workspaceId])->save(); } return $tenant; } abort_if($workspaceId === null, ResponseAlias::HTTP_FORBIDDEN, 'Missing workspace context'); return Tenant::create([ 'tenant_id' => $tenantIdentifier, 'name' => 'New Tenant', 'workspace_id' => $workspaceId, ]); } private function upsertProviderConnectionForConsent(Tenant $tenant, string $status, ?string $error): ProviderConnection { $hasDefault = ProviderConnection::query() ->where('tenant_id', (int) $tenant->getKey()) ->where('provider', 'microsoft') ->where('is_default', true) ->exists(); $consentStatus = match ($status) { 'ok' => ProviderConsentStatus::Granted, 'error' => ProviderConsentStatus::Failed, default => ProviderConsentStatus::Required, }; $verificationStatus = ProviderVerificationStatus::Unknown; $projectedState = app(ProviderConnectionStateProjector::class)->project( connectionType: ProviderConnectionType::Platform, consentStatus: $consentStatus, verificationStatus: $verificationStatus, ); $reasonCode = match ($status) { 'ok' => null, 'error' => ProviderReasonCodes::ProviderAuthFailed, default => ProviderReasonCodes::ProviderConsentMissing, }; $connection = ProviderConnection::query()->updateOrCreate( [ 'tenant_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => (string) ($tenant->graphTenantId() ?? $tenant->tenant_id ?? $tenant->external_id), ], [ 'workspace_id' => (int) $tenant->workspace_id, 'display_name' => (string) ($tenant->name ?? 'Microsoft Connection'), 'connection_type' => ProviderConnectionType::Platform->value, 'status' => $projectedState['status'], 'consent_status' => $consentStatus->value, 'consent_granted_at' => $status === 'ok' ? now() : null, 'consent_last_checked_at' => now(), 'consent_error_code' => $reasonCode, 'consent_error_message' => $error, 'verification_status' => $verificationStatus->value, 'health_status' => $projectedState['health_status'], 'migration_review_required' => false, 'migration_reviewed_at' => null, 'last_error_reason_code' => $reasonCode, 'last_error_message' => $error, 'is_default' => $hasDefault ? false : true, ], ); $connection->credential()->delete(); if (! $hasDefault && ! $connection->is_default) { $connection->makeDefault(); } return $connection->fresh(); } private function parseState(?string $state): ?string { if (empty($state)) { return null; } if (str_contains($state, '|')) { [, $value] = explode('|', $state, 2); return $value; } return $state; } }