Appearance
Authorization
The Module Manager provides a comprehensive authorization system that automatically integrates with Laravel policies and Filament resources.
Policy Loading
Module Manager loads all the policies in App\Policies\ModuleName\ModelNamePolicy
. For example, if you have a Post
model in the Blog
module, the policy would be located at App\Policies\Blog\PostPolicy
.
This approach allows you to define policies at the application level, giving you full control over module authorization.
Policy Generation
To streamline creating policies for your modules, Module Manager includes a command that generates policy files for your models:
bash
php artisan mm:generate-policies
# Or for a specific module
php artisan mm:generate-policies --module=Blog
See the Generate Policies documentation for more details.
Authorization Helpers
Basic Authorization
The Module Manager provides a helper function to check if a user has access to perform actions on models:
php
use ModuleManager\ModuleManager\Enums\AuthorizeAction;
// Check permission using enum
$canCreate = authorizeAction(AuthorizeAction::CREATE, Post::class);
// Check permission on a model instance
$canUpdate = authorizeAction(AuthorizeAction::UPDATE, $post);
// You can also use string values, but enum is preferred for type safety
$canView = authorizeAction('view', $post);
The authorizeAction()
helper checks if the user has permission to perform the specified action on the model. It returns true
or false
.
If the policy is not defined, the default behavior returns true
(but you can configure this in the Module Manager config).
Policy Checker Facade
For more complex authorization scenarios, Module Manager provides a PolicyChecker
facade that offers a fluent interface:
php
use ModuleManager\ModuleManager\Enums\AuthorizeAction;
use ModuleManager\ModuleManager\Facades\PolicyChecker;
// Basic check with enum
$canAccess = PolicyChecker::from(AuthorizeAction::VIEW, $post)->validate();
// Multiple checks - ALL must pass (logical AND)
$canManage = PolicyChecker::from(AuthorizeAction::CREATE, Post::class)
->and(AuthorizeAction::UPDATE, $post)
->validate();
// Multiple checks - ANY should pass (logical OR)
$hasAccess = PolicyChecker::from(AuthorizeAction::VIEW, $post)
->or(AuthorizeAction::UPDATE, $post)
->anyOf()
->validate();
Blade Directive
In Blade templates, you can use the @authorizeAction
directive:
php
@authorizeAction(AuthorizeAction::CREATE, \Modules\Blog\Models\Post::class)
<button>Create Post</button>
@endauthorizeAction
ConfigurableResource Integration
The ConfigurableResource
class automatically integrates with the authorization system. When a resource extends this class, all standard Filament authorization methods (canViewAny
, canCreate
, etc.) are automatically handled through the corresponding policy methods:
php
// In your resource class
use ModuleManager\ModuleManager\Filament\Panels\ConfigurableResource;
class PostResource extends ConfigurableResource
{
protected static string $model = Post::class;
// No need to manually override canViewAny(), canCreate(), etc.
// They are automatically handled by the Module Manager!
}
Creating Policies
Here's an example of a policy that would work with Module Manager:
php
<?php
namespace App\Policies\Blog;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Database\Eloquent\Builder;
use Modules\Blog\Models\Post;
class PostPolicy
{
use HandlesAuthorization;
public function viewAny(User $user): bool
{
return true; // Everyone can view posts
}
public function view(User $user, Post $post): bool
{
return $post->user_id === $user->id || $user->hasRole('admin');
}
public function viewRow(User $user, Builder $query): Builder
{
// Special method that allows row-level filtering
// in resource table listings
return $query->where(function (Builder $query) use ($user) {
$query->where('user_id', $user->id)
->orWhere('is_public', true);
});
}
public function create(User $user): bool
{
return true; // Anyone can create posts
}
public function update(User $user, Post $post): bool
{
return $post->user_id === $user->id;
}
public function delete(User $user, Post $post): bool
{
return $post->user_id === $user->id || $user->hasRole('admin');
}
// Additional policy methods...
public function restore(User $user, Post $post): bool
{
return $user->hasRole('admin');
}
public function forceDelete(User $user, Post $post): bool
{
return $user->hasRole('admin');
}
}
Multi-Tenancy Considerations
When using multi-tenancy, policies should also check tenant access when appropriate:
php
public function view(User $user, Post $post): bool
{
// First, check tenant access if multi-tenancy is enabled
if (isMultiTenant() && tenant()->getKey() !== $post->getTenantId()) {
return false;
}
// Then check normal permissions
return $post->user_id === $user->id || $user->hasRole('admin');
}
Disabling Authorization
You can globally disable permission checking by setting the check_permissions
key to false
in the Module Manager configuration:
php
// config/module-manager.php
return [
'check_permissions' => false,
// ...
];
Additional Methods
The authorization system in Module Manager includes comprehensive support for all policy methods defined in the AuthorizeAction
enum:
viewAny
(AuthorizeAction::VIEW_ANY
) - Can the user view any records?view
(AuthorizeAction::VIEW
) - Can the user view a specific record?create
(AuthorizeAction::CREATE
) - Can the user create new records?update
(AuthorizeAction::UPDATE
) - Can the user update a specific record?delete
(AuthorizeAction::DELETE
) - Can the user delete a specific record?deleteAny
(AuthorizeAction::DELETE_ANY
) - Can the user delete any records?restore
(AuthorizeAction::RESTORE
) - Can the user restore a specific soft-deleted record?forceDelete
(AuthorizeAction::FORCE_DELETE
) - Can the user permanently delete a specific record?updateAny
(AuthorizeAction::UPDATE_ANY
) - Can the user update any records?reorder
(AuthorizeAction::REORDER
) - Can the user reorder records?viewRow
- Filter which specific rows a user can view