diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 7c60f1f..f490238 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -13,13 +13,13 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest, windows-latest] - php: [8.2, 8.1] - laravel: [10.*] + php: [8.2] + laravel: [11.*] stability: [prefer-lowest, prefer-stable] include: - - laravel: 10.* - testbench: 8.* - carbon: 2.* + - laravel: 11.* + testbench: 9.* + carbon: 3.* name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} diff --git a/README.md b/README.md index 619b539..7f24b3b 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,38 @@ public function panel(Panel $panel): Panel } ``` +### Security + +Using the `canManageMails()` method, you can define which users have access to the mail resources/pages. Here's a comprehensive example that includes additional logic for flexibility: + +```php +use Backstage\FilamentMails\FilamentMailsPlugin; +use Illuminate\Support\Facades\Auth; + +$panel + ->plugins([ + FilamentMailsPlugin::make() + ->canManageMails(function () { + $user = Auth::user(); + + // Allow access for users with specific roles + if ($user->hasRole('admin') || $user->hasRole('supervisor')) { + return true; + } + + // Allow access for users with specific permissions + if ($user->hasPermissionTo('manage mails')) { + return true; + } + + // Restrict access for all other users + return false; + }), + ]); +``` + +This example demonstrates how to combine role-based and permission-based access control, providing a more robust and flexible approach to managing access to mail resources. + ### Tenant middleware and route protection If you want to protect the mail routes with your (tenant) middleware, you can do so by adding the routes to the `tenantRoutes`: diff --git a/src/FilamentMailsPlugin.php b/src/FilamentMailsPlugin.php index 376c99c..d722d38 100644 --- a/src/FilamentMailsPlugin.php +++ b/src/FilamentMailsPlugin.php @@ -5,12 +5,18 @@ use Backstage\FilamentMails\Resources\EventResource; use Backstage\FilamentMails\Resources\MailResource; use Backstage\FilamentMails\Resources\SuppressionResource; +use Closure; use Filament\Contracts\Plugin; use Filament\Panel; use Filament\Support\Colors\Color; +use Filament\Support\Concerns\EvaluatesClosures; class FilamentMailsPlugin implements Plugin { + use EvaluatesClosures; + + public bool | Closure $canManageMails = true; + public function getId(): string { return 'filament-mails'; @@ -46,4 +52,16 @@ public static function get(): static return $plugin; } + + public function canManageMails(bool | Closure $canManageMails = true): static + { + $this->canManageMails = $canManageMails; + + return $this; + } + + public function userCanManageMails(): bool + { + return $this->evaluate($this->canManageMails); + } } diff --git a/src/Resources/EventResource.php b/src/Resources/EventResource.php index cd4c5fc..13bb691 100644 --- a/src/Resources/EventResource.php +++ b/src/Resources/EventResource.php @@ -2,6 +2,7 @@ namespace Backstage\FilamentMails\Resources; +use Backstage\FilamentMails\FilamentMailsPlugin; use Backstage\FilamentMails\Resources\EventResource\Pages\ListEvents; use Backstage\FilamentMails\Resources\EventResource\Pages\ViewEvent; use Backstage\Mails\Enums\EventType; @@ -24,6 +25,11 @@ class EventResource extends Resource protected static bool $shouldRegisterNavigation = true; + public static function canAccess(): bool + { + return FilamentMailsPlugin::get()->userCanManageMails(); + } + public static function getSlug(?Panel $panel = null): string { return config('filament-mails.resources.mail')::getSlug() . '/events'; diff --git a/src/Resources/EventResource/Pages/ListEvents.php b/src/Resources/EventResource/Pages/ListEvents.php index cbb41fd..2655b27 100644 --- a/src/Resources/EventResource/Pages/ListEvents.php +++ b/src/Resources/EventResource/Pages/ListEvents.php @@ -2,6 +2,7 @@ namespace Backstage\FilamentMails\Resources\EventResource\Pages; +use Backstage\FilamentMails\FilamentMailsPlugin; use Backstage\FilamentMails\Resources\EventResource; use Backstage\Mails\Enums\EventType; use Backstage\Mails\Models\MailEvent; @@ -11,6 +12,11 @@ class ListEvents extends ListRecords { + public static function canAccess(array $parameters = []): bool + { + return FilamentMailsPlugin::get()->userCanManageMails(); + } + public static function getResource(): string { return config('filament-mails.resources.event', EventResource::class); diff --git a/src/Resources/EventResource/Pages/ViewEvent.php b/src/Resources/EventResource/Pages/ViewEvent.php index 94c7358..b1432f6 100644 --- a/src/Resources/EventResource/Pages/ViewEvent.php +++ b/src/Resources/EventResource/Pages/ViewEvent.php @@ -2,11 +2,17 @@ namespace Backstage\FilamentMails\Resources\EventResource\Pages; +use Backstage\FilamentMails\FilamentMailsPlugin; use Backstage\FilamentMails\Resources\EventResource; use Filament\Resources\Pages\ViewRecord; class ViewEvent extends ViewRecord { + public static function canAccess(array $parameters = []): bool + { + return FilamentMailsPlugin::get()->userCanManageMails(); + } + public static function getResource(): string { return config('filament-mails.resources.event', EventResource::class); diff --git a/src/Resources/MailResource.php b/src/Resources/MailResource.php index 0405407..9758124 100644 --- a/src/Resources/MailResource.php +++ b/src/Resources/MailResource.php @@ -2,6 +2,7 @@ namespace Backstage\FilamentMails\Resources; +use Backstage\FilamentMails\FilamentMailsPlugin; use Backstage\FilamentMails\Resources\MailResource\Pages\ListMails; use Backstage\FilamentMails\Resources\MailResource\Pages\ViewMail; use Backstage\FilamentMails\Resources\MailResource\Widgets\MailStatsWidget; @@ -45,6 +46,11 @@ class MailResource extends Resource protected static bool $shouldRegisterNavigation = true; + public static function canAccess(): bool + { + return FilamentMailsPlugin::get()->userCanManageMails(); + } + public static function getModel(): string { return config('mails.models.mail'); diff --git a/src/Resources/MailResource/Pages/ListMails.php b/src/Resources/MailResource/Pages/ListMails.php index ae44853..374d3fd 100644 --- a/src/Resources/MailResource/Pages/ListMails.php +++ b/src/Resources/MailResource/Pages/ListMails.php @@ -2,6 +2,7 @@ namespace Backstage\FilamentMails\Resources\MailResource\Pages; +use Backstage\FilamentMails\FilamentMailsPlugin; use Backstage\FilamentMails\Resources\MailResource; use Backstage\FilamentMails\Resources\MailResource\Widgets\MailStatsWidget; use Backstage\Mails\Models\Mail; @@ -11,6 +12,11 @@ class ListMails extends ListRecords { + public static function canAccess(array $parameters = []): bool + { + return FilamentMailsPlugin::get()->userCanManageMails(); + } + public static function getResource(): string { return config('filament-mails.resources.mail', MailResource::class); diff --git a/src/Resources/MailResource/Pages/ViewMail.php b/src/Resources/MailResource/Pages/ViewMail.php index 06a3dd1..00dc549 100644 --- a/src/Resources/MailResource/Pages/ViewMail.php +++ b/src/Resources/MailResource/Pages/ViewMail.php @@ -2,11 +2,17 @@ namespace Backstage\FilamentMails\Resources\MailResource\Pages; +use Backstage\FilamentMails\FilamentMailsPlugin; use Backstage\FilamentMails\Resources\MailResource; use Filament\Resources\Pages\ViewRecord; class ViewMail extends ViewRecord { + public static function canAccess(array $parameters = []): bool + { + return FilamentMailsPlugin::get()->userCanManageMails(); + } + public static function getResource(): string { return config('filament-mails.resources.mail', MailResource::class); diff --git a/src/Resources/MailResource/Widgets/MailStatsWidget.php b/src/Resources/MailResource/Widgets/MailStatsWidget.php index ff3bab5..6f9ba50 100644 --- a/src/Resources/MailResource/Widgets/MailStatsWidget.php +++ b/src/Resources/MailResource/Widgets/MailStatsWidget.php @@ -2,6 +2,7 @@ namespace Backstage\FilamentMails\Resources\MailResource\Widgets; +use Backstage\FilamentMails\FilamentMailsPlugin; use Filament\Facades\Filament; use Filament\Widgets\StatsOverviewWidget as BaseWidget; use Filament\Widgets\StatsOverviewWidget\Stat; @@ -12,6 +13,11 @@ class MailStatsWidget extends BaseWidget protected static bool $isDiscovered = false; + public static function canView(): bool + { + return FilamentMailsPlugin::get()->userCanManageMails(); + } + protected function getStats(): array { $class = config('mails.models.mail'); diff --git a/src/Resources/SuppressionResource.php b/src/Resources/SuppressionResource.php index 3cd7ead..abaf115 100644 --- a/src/Resources/SuppressionResource.php +++ b/src/Resources/SuppressionResource.php @@ -2,6 +2,7 @@ namespace Backstage\FilamentMails\Resources; +use Backstage\FilamentMails\FilamentMailsPlugin; use Backstage\FilamentMails\Resources\SuppressionResource\Pages\ListSuppressions; use Backstage\Mails\Enums\EventType; use Backstage\Mails\Enums\Provider; @@ -22,6 +23,11 @@ class SuppressionResource extends Resource protected static bool $shouldRegisterNavigation = true; + public static function canAccess(): bool + { + return FilamentMailsPlugin::get()->userCanManageMails(); + } + public static function getSlug(?Panel $panel = null): string { return config('filament-mails.resources.mail')::getSlug() . '/suppressions'; diff --git a/src/Resources/SuppressionResource/Pages/ListSuppressions.php b/src/Resources/SuppressionResource/Pages/ListSuppressions.php index 03282a4..e50faae 100644 --- a/src/Resources/SuppressionResource/Pages/ListSuppressions.php +++ b/src/Resources/SuppressionResource/Pages/ListSuppressions.php @@ -2,6 +2,7 @@ namespace Backstage\FilamentMails\Resources\SuppressionResource\Pages; +use Backstage\FilamentMails\FilamentMailsPlugin; use Backstage\FilamentMails\Resources\SuppressionResource; use Filament\Resources\Pages\ListRecords; @@ -13,4 +14,9 @@ public function getTitle(): string { return __('Suppressions'); } + + public static function canAccess(array $parameters = []): bool + { + return FilamentMailsPlugin::get()->userCanManageMails(); + } }