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

Bouncer Laravel Package

silber/bouncer

Bouncer adds roles and abilities to Laravel with a fluent, Eloquent-powered API. Define permissions, assign roles to users, and authorize actions via gates and middleware. Supports caching, scoped abilities, and a simple, expressive permission model.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require silber/bouncer

Publish the migrations and config:

php artisan vendor:publish --provider="Bouncer\BouncerServiceProvider"
php artisan migrate
  1. First Use Case: Define a role and assign it to a user:

    use Bouncer;
    
    // Create a role
    $adminRole = Bouncer::createRole('admin');
    
    // Assign role to a user
    $user = User::find(1);
    $user->assign($adminRole);
    
    // Grant an ability
    Bouncer::allow($user)->to('edit', Post::class);
    
  2. Check Permissions:

    if (Bouncer::can($user, 'edit', Post::class)) {
        // User can edit posts
    }
    
  3. Key Files to Review:

    • config/bouncer.php (customization)
    • database/migrations/ (schema)
    • app/Providers/BouncerServiceProvider.php (custom models)

Implementation Patterns

Core Workflows

1. Role-Based Access Control (RBAC)

// Create roles
$admin = Bouncer::createRole('admin');
$editor = Bouncer::createRole('editor');

// Assign roles to users
$user->assign($admin);
$user->assign($editor);

// Check role membership
if (Bouncer::is($user, $admin)) {
    // User is an admin
}

2. Ability-Based Access Control (ABAC)

// Grant abilities
Bouncer::allow($user)->to('publish', Post::class);
Bouncer::allow($user)->to('delete', Comment::class);

// Check abilities
if (Bouncer::can($user, 'publish', Post::class)) {
    // User can publish posts
}

// Bulk grant abilities
Bouncer::allow($user)->to(['edit', 'view'], Post::class);

3. Role + Ability Hybrid

// Grant abilities to a role
Bouncer::allow($admin)->to('delete', Post::class);

// Check if a role has an ability
if (Bouncer::can($admin, 'delete', Post::class)) {
    // Admin role can delete posts
}

4. Multi-Tenancy

// Set tenant scope
Bouncer::scope()->to(1); // Tenant ID 1

// Grant abilities scoped to tenant
Bouncer::allow($user)->to('view', Post::class);

// Temporary scope for a block of code
Bouncer::scope()->onceTo(2, function () {
    // All queries in this block use tenant ID 2
});

5. Global Abilities (Everyone)

// Grant abilities to all users
Bouncer::allowEveryone()->to('view', Post::class);

// Check if everyone has an ability
if (Bouncer::canEveryone('view', Post::class)) {
    // Everyone can view posts
}

Integration Tips

1. Policies and Gates

  • Bouncer runs after Laravel's policies by default (configurable via Bouncer::runBeforePolicies()).
  • Use policies for business logic (e.g., "can delete if not locked") and Bouncer for permission checks.
// In a policy
public function delete(User $user, Post $post)
{
    return $post->isPublished() && Bouncer::can($user, 'delete', Post::class);
}

2. Middleware

Create middleware to check permissions:

public function handle(Request $request, Closure $next)
{
    if (!Bouncer::can($request->user(), 'edit', Post::class)) {
        abort(403);
    }
    return $next($request);
}

3. API Resources

Filter collections based on permissions:

public function toArray($request)
{
    return Post::where(function ($query) use ($request) {
        if (Bouncer::can($request->user(), 'view_all', Post::class)) {
            return;
        }
        $query->where('user_id', $request->user()->id);
    })->get();
}

4. Eloquent Models

Use traits for seamless integration:

use Bouncer\Traits\Authorizable;

class User extends Authenticatable
{
    use Authorizable;
}
// Check permissions directly on a model
if ($user->can('edit', $post)) {
    // User can edit the post
}

5. Seeding Roles/Abilities

// In DatabaseSeeder.php
$admin = Bouncer::createRole('admin');
Bouncer::allow($admin)->to(['create', 'edit', 'delete'], Post::class);

6. Custom Models

Override default models in config/bouncer.php:

'models' => [
    'role' => App\Models\CustomRole::class,
    'ability' => App\Models\CustomAbility::class,
],

Register custom models in BouncerServiceProvider:

public function boot()
{
    Bouncer::useRoleModel(App\Models\CustomRole::class);
    Bouncer::useAbilityModel(App\Models\CustomAbility::class);
}

Gotchas and Tips

Pitfalls

1. Caching Issues

  • Bouncer caches roles/abilities for performance. Clear cache after bulk operations:
    Bouncer::refresh(); // Clears cache
    
  • If using cross-request caching, ensure Bouncer::refresh() is called after schema changes or bulk updates.

2. Multi-Tenancy Scope Leaks

  • Abilities granted within a tenant scope do not leak to the global scope (fixed in v1.0.1).
  • Use Bouncer::scope()->removeOnce() to temporarily remove scopes for specific queries.

3. Policy Precedence

  • Bouncer runs after policies by default. If you need Bouncer to run first, use:
    Bouncer::runBeforePolicies();
    
  • This is a global setting; reset with Bouncer::runAfterPolicies().

4. Soft Deletes

  • Soft-deleted roles/abilities are not automatically removed from pivots. Use:
    Bouncer::clean(); // Removes soft-deleted records from pivots
    
  • Or manually:
    php artisan bouncer:clean
    

5. Morph Map Conflicts

  • Custom models must be registered with Laravel's morph map if not using default tables.
  • If migrating from raw class names to morph map, run:
    DB::table('permissions')
        ->where(['entity_type' => MyModel::class])
        ->update(['entity_type' => (new MyModel)->getMorphClass()]);
    

6. Global Abilities

  • Requires entity_id and entity_type columns in permissions table to be nullable.
  • Run migrations after enabling allowEveryone():
    php artisan migrate
    

7. PostgreSQL/Oracle

  • Ensure your database driver is properly configured in .env.
  • Bouncer supports PostgreSQL/Oracle, but some edge cases (e.g., JSON columns) may require manual schema adjustments.

Debugging Tips

1. Log Permission Checks

Enable debug mode in config/bouncer.php:

'debug' => env('BOUNCER_DEBUG', false),

Logs will appear in storage/logs/bouncer.log.

2. Inspect User Abilities

// Get all abilities for a user
$abilities = Bouncer::abilities($user);

// Get all roles for a user
$roles = Bouncer::roles($user);

3. Check Cache

// Check if cache is enabled
Bouncer::isCached();

// Manually clear cache
Bouncer::refresh();

4. Validate Schema

Run the bouncer:check Artisan command:

php artisan bouncer:check

5. Common Errors

  • "Class not found": Ensure custom models are registered in BouncerServiceProvider.
  • "Column not found": Run migrations or check config/bouncer.php for
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony