TenantAtlas/app/Providers/Filament/AdminPanelProvider.php
Ahmed Darrazi 3b16b1b94c Merge remote-tracking branch 'origin/069-managed-tenant-onboarding-wizard-session-1769903080' into feat/999-merge-integration-session-1769990000
# Conflicts:
#	.github/agents/copilot-instructions.md
#	app/Filament/Resources/TenantResource/Pages/CreateTenant.php
#	app/Filament/Resources/TenantResource/Pages/ListTenants.php
#	app/Models/Tenant.php
#	app/Providers/Filament/AdminPanelProvider.php
#	routes/web.php
#	tests/Feature/BulkSyncPoliciesTest.php
#	tests/Feature/Filament/TenantSetupTest.php
#	tests/Feature/Rbac/TenantAdminAuthorizationTest.php
2026-02-01 19:31:16 +01:00

187 lines
7.3 KiB
PHP

<?php
namespace App\Providers\Filament;
use App\Filament\Pages\Auth\Login;
use App\Filament\Pages\ChooseTenant;
use App\Filament\Pages\ChooseWorkspace;
use App\Filament\Pages\ManagedTenants\ArchivedStatus;
use App\Filament\Pages\ManagedTenants\Current;
use App\Filament\Pages\ManagedTenants\EditManagedTenant;
use App\Filament\Pages\ManagedTenants\Index as ManagedTenantsIndex;
use App\Filament\Pages\ManagedTenants\Onboarding;
use App\Filament\Pages\ManagedTenants\ViewManagedTenant;
use App\Filament\Pages\NoAccess;
use App\Filament\Pages\TenantOnboardingWizard;
use App\Filament\Pages\TenantDashboard;
use App\Models\Tenant;
use App\Models\User;
use App\Models\WorkspaceMembership;
use App\Services\Auth\CapabilityResolver;
use App\Support\Auth\Capabilities;
use App\Support\ManagedTenants\ManagedTenantContext;
use App\Support\Middleware\DenyNonMemberTenantAccess;
use App\Support\Middleware\EnsureFilamentTenantSelected;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\AuthenticateSession;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Filament\View\PanelsRenderHook;
use Filament\Widgets\AccountWidget;
use Filament\Widgets\FilamentInfoWidget;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Support\Facades\Route;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
$panel = $panel
->default()
->id('admin')
->path('admin')
->login(Login::class)
->authenticatedRoutes(function (Panel $panel): void {
ChooseTenant::registerRoutes($panel);
ChooseWorkspace::registerRoutes($panel);
NoAccess::registerRoutes($panel);
TenantOnboardingWizard::registerRoutes($panel);
if ($panel->hasTenantRegistration()) {
$tenantRegistrationPage = $panel->getTenantRegistrationPage();
Route::get($tenantRegistrationPage::getRoutePath($panel), $tenantRegistrationPage)
->middleware($tenantRegistrationPage::getRouteMiddleware($panel))
->withoutMiddleware($tenantRegistrationPage::getWithoutRouteMiddleware($panel))
->name('tenant.registration');
}
ManagedTenantsIndex::registerRoutes($panel);
Onboarding::registerRoutes($panel);
Current::registerRoutes($panel);
ArchivedStatus::registerRoutes($panel);
ViewManagedTenant::registerRoutes($panel);
EditManagedTenant::registerRoutes($panel);
Route::get('managed-tenants/{managedTenant}/open', function (string $managedTenant) {
$user = auth()->user();
if (! $user instanceof User) {
abort(403);
}
if (! $user->tenantMemberships()->exists()) {
abort(404);
}
$managedTenant = Tenant::withTrashed()->findOrFail($managedTenant);
/** @var CapabilityResolver $resolver */
$resolver = app(CapabilityResolver::class);
if (! $resolver->isMember($user, $managedTenant)) {
abort(404);
}
if (! $resolver->can($user, $managedTenant, Capabilities::TENANT_MANAGED_TENANTS_VIEW)) {
abort(403);
}
if ($managedTenant->isActive()) {
ManagedTenantContext::setCurrentTenant($managedTenant);
ManagedTenantContext::clearArchivedTenant();
return redirect('/admin/managed-tenants/current');
}
ManagedTenantContext::setArchivedTenant($managedTenant);
return redirect('/admin/managed-tenants/archived');
});
})
->tenant(Tenant::class, slugAttribute: 'external_id')
->tenantRoutePrefix('t')
->tenantMenu(fn (): bool => filled(Filament::getTenant()))
->searchableTenantMenu()
->colors([
'primary' => Color::Amber,
])
->renderHook(
PanelsRenderHook::HEAD_END,
fn () => view('filament.partials.livewire-intercept-shim')->render()
)
->renderHook(
PanelsRenderHook::BODY_END,
fn () => (bool) config('tenantpilot.bulk_operations.progress_widget_enabled', true)
? view('livewire.bulk-operation-progress-wrapper')->render()
: ''
)
->discoverClusters(in: app_path('Filament/Clusters'), for: 'App\Filament\Clusters')
->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources')
->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages')
->pages([
TenantDashboard::class,
])
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets')
->widgets([
AccountWidget::class,
FilamentInfoWidget::class,
])
->databaseNotifications()
->userMenuItems([
Action::make('switch-workspace')
->label('Switch workspace')
->icon('heroicon-o-squares-2x2')
->url('/admin/choose-workspace')
->visible(function (): bool {
$user = auth()->user();
if (! $user instanceof User) {
return false;
}
return WorkspaceMembership::query()
->where('user_id', $user->getKey())
->count() > 1;
})
->sort(0),
])
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
'ensure-correct-guard:web',
EnsureFilamentTenantSelected::class,
DenyNonMemberTenantAccess::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
])
->authMiddleware([
Authenticate::class,
'ensure-workspace-selected',
]);
if (! app()->runningUnitTests()) {
$panel->viteTheme('resources/css/filament/admin/theme.css');
}
return $panel;
}
}