Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Authorization Laravel Package

directorytree/authorization

Native role & permission management for Laravel. Install via Composer, run migrations, add the Authorizable trait to your User model, then check roles/permissions, use caching, gate registration, and middleware. Includes customizable migrations/models and tests.

View on GitHub
Deep Wiki
Context7
## Getting Started

### First Steps
1. **Installation**: Add the package via Composer:
   ```bash
   composer require directorytree/authorization

Run migrations to create the required tables:

php artisan migrate
  1. User Model Setup: Attach the Authorizable trait to your User model:

    use DirectoryTree\Authorization\Traits\Authorizable;
    
    class User extends Authenticatable
    {
        use Authorizable;
    }
    
  2. First Use Case: Create a permission and assign it to a role:

    // Create a permission
    $createPost = Permission::create(['name' => 'posts.create', 'label' => 'Create Post']);
    
    // Create a role
    $editor = Role::create(['name' => 'editor', 'label' => 'Editor']);
    
    // Assign permission to role
    $editor->permissions()->save($createPost);
    
    // Assign role to user
    $user->roles()->save($editor);
    
  3. Check Permissions: Use Laravel's built-in can() method:

    if (auth()->user()->can('posts.create')) {
        // User has permission
    }
    

Implementation Patterns

Core Workflows

  1. Role-Based Access Control (RBAC):

    • Define roles (admin, editor, user) and assign permissions to them.
    • Assign roles to users via the roles() relationship.
    $adminRole = Role::create(['name' => 'admin']);
    $user->roles()->attach($adminRole);
    
  2. Permission Management:

    • Create permissions dynamically or via migrations.
    • Use grant()/revoke() methods for flexibility:
      $user->grant(['posts.create', 'posts.edit']); // Grant multiple permissions
      $user->revoke('posts.delete'); // Revoke a single permission
      
  3. Middleware Integration:

    • Protect routes using permission or role middleware:
      Route::get('/admin', function () {
          // ...
      })->middleware('permission:posts.create');
      
    • Combine multiple permissions/roles:
      Route::get('/admin', function () {
          // ...
      })->middleware('permission:posts.create,posts.edit');
      
  4. Caching:

    • Enable/disable caching globally or per request:
      Authorization::disablePermissionCache(); // Disable caching
      
    • Customize cache key and expiry:
      Authorization::cacheKey('custom.key');
      Authorization::cacheExpiresIn(now()->addHours(1));
      
  5. Gate Integration:

    • Register permissions as Laravel Gates automatically (disable with Authorization::disableGateRegistration()).
    • Use Gates in policies or controllers:
      public function update(Request $request, Post $post)
      {
          $this->authorize('posts.update');
          // ...
      }
      
  6. Bulk Operations:

    • Sync permissions for a role/user:
      $role->grantOnly(['posts.create', 'posts.edit']); // Only these permissions remain
      $user->revokeAll(); // Remove all permissions
      

Integration Tips

  • Seeding: Use database seeds to predefine roles/permissions:

    public function run()
    {
        $admin = Role::create(['name' => 'admin']);
        $createPost = Permission::create(['name' => 'posts.create']);
        $admin->permissions()->save($createPost);
    }
    
  • APIs: Use the same methods in API controllers:

    public function store(Request $request)
    {
        $this->authorize('posts.create');
        // ...
    }
    
  • Views: Leverage @can directives:

    @can('posts.create')
        <button>Create Post</button>
    @endcan
    
  • Testing: Register permissions in setUp():

    protected function setUp(): void
    {
        parent::setUp();
        app(PermissionRegistrar::class)->register();
    }
    

Gotchas and Tips

Pitfalls

  1. Cache Invalidation:

    • Forgetting to clear the cache after manual permission changes:
      php artisan cache:clear
      
    • Fix: Use ClearsCachedPermissions trait on models to auto-flush:
      class Permission extends Model
      {
          use ClearsCachedPermissions;
      }
      
  2. Middleware Order:

    • Placing permission middleware after auth ensures unauthenticated users bypass permission checks.
    • Example:
      Route::get('/profile', function () {
          // ...
      })->middleware(['auth', 'permission:profile.view']);
      
  3. Permission Naming:

    • Use dot notation (posts.create) for consistency with Laravel Gates.
    • Avoid spaces or special characters in permission names.
  4. Model Customization:

    • Forgetting to update traits when extending models:
      // Missing trait on custom Role model:
      class Role extends Model
      {
          // Forgot: use ManagesPermissions;
      }
      
    • Fix: Ensure all custom models include required traits (ManagesPermissions, HasUsers, etc.).
  5. Gate Registration:

    • Disabling disableGateRegistration() may break existing Gate-based checks:
      Gate::allows('posts.create'); // Fails if not registered
      
  6. Testing Quirks:

    • Tests may fail if PermissionRegistrar isn’t initialized in setUp().
    • Fix: Add to TestCase:
      protected function setUp(): void
      {
          parent::setUp();
          app(PermissionRegistrar::class)->register();
      }
      

Debugging Tips

  1. Check Cache:

    • Inspect cached permissions:
      Cache::get('authorization.permissions');
      
  2. Log Permissions:

    • Temporarily log permission checks:
      if (auth()->user()->can('posts.create')) {
          \Log::info('Permission granted: posts.create');
      }
      
  3. Verify Relationships:

    • Debug role/permission assignments:
      $user->roles; // Check assigned roles
      $role->permissions; // Check role permissions
      
  4. Middleware Debugging:

    • Use dd() to inspect middleware parameters:
      Route::get('/debug', function () {
          dd(request()->route()->middleware());
      })->middleware('permission:posts.create');
      

Extension Points

  1. Custom Permission Logic:

    • Override hasPermission() in your User model:
      public function hasPermission($permission)
      {
          // Custom logic here
          return parent::hasPermission($permission);
      }
      
  2. Dynamic Permissions:

    • Generate permissions on-the-fly (e.g., posts.{id}.edit):
      $user->grant("posts.$postId.edit");
      
  3. Policy Integration:

    • Combine with Laravel Policies for resource-specific checks:
      public function update(Request $request, Post $post)
      {
          $this->authorize('posts.update', $post);
          // ...
      }
      
  4. Event Listeners:

    • Listen for permission changes:
      Permission::created(function ($permission) {
          // Clear cache or log changes
      });
      
  5. API Tokens:

    • Extend to support API tokens (e.g., Sanctum):
      if (auth()->check() && auth()->user()->can('api.access')) {
          // Allow token-based access
      }
      

Configuration Quirks

  1. Default Cache Driver:

    • Ensure your .env cache driver is configured (e.g., CACHE_DRIVER=file for testing).
  2. Model Binding:

    • Custom models must implement the same interfaces as defaults:
      class User extends Model
      {
          use Authorizable; // Required for core functionality
      }
      
  3. Laravel Version Compatibility:

    • Verify package support for your Laravel version (e.g., v1.4.0 for Laravel 13).
    • Fix: Downgrade or upgrade the package if needed.
  4. Migration Conflicts:

    • If publishing migrations, resolve conflicts with existing roles/permissions tables:
      php artisan vendor:publish --tag=authorization-migrations --force
      
  5. Permission Registrar:

    • Forgetting to register permissions in tests can cause silent failures.
    • Fix: Always include app(PermissionRegistrar::class)->register() in test setups.

```markdown
### Daily Developer Workflow Example
1. **Morning Setup**:
   - Add a new permission for a feature:
     ```php
     Permission::create(['name' => 'reports.generate', 'label' => 'Generate Reports']);
     ```
   - Assign to the `analyst` role:
     ```php
     $analystRole->grant('reports.generate');
     ```

2. **Route Protection**:
   -
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope