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.
## 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
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);
Check Permissions:
if (Bouncer::can($user, 'edit', Post::class)) {
// User can edit posts
}
Key Files to Review:
config/bouncer.php (customization)database/migrations/ (schema)app/Providers/BouncerServiceProvider.php (custom models)// 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
}
// 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);
// 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
}
// 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
});
// 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
}
Bouncer::runBeforePolicies()).// In a policy
public function delete(User $user, Post $post)
{
return $post->isPublished() && Bouncer::can($user, 'delete', Post::class);
}
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);
}
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();
}
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
}
// In DatabaseSeeder.php
$admin = Bouncer::createRole('admin');
Bouncer::allow($admin)->to(['create', 'edit', 'delete'], Post::class);
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);
}
Bouncer::refresh(); // Clears cache
Bouncer::refresh() is called after schema changes or bulk updates.Bouncer::scope()->removeOnce() to temporarily remove scopes for specific queries.Bouncer::runBeforePolicies();
Bouncer::runAfterPolicies().Bouncer::clean(); // Removes soft-deleted records from pivots
php artisan bouncer:clean
DB::table('permissions')
->where(['entity_type' => MyModel::class])
->update(['entity_type' => (new MyModel)->getMorphClass()]);
entity_id and entity_type columns in permissions table to be nullable.allowEveryone():
php artisan migrate
.env.Enable debug mode in config/bouncer.php:
'debug' => env('BOUNCER_DEBUG', false),
Logs will appear in storage/logs/bouncer.log.
// Get all abilities for a user
$abilities = Bouncer::abilities($user);
// Get all roles for a user
$roles = Bouncer::roles($user);
// Check if cache is enabled
Bouncer::isCached();
// Manually clear cache
Bouncer::refresh();
Run the bouncer:check Artisan command:
php artisan bouncer:check
BouncerServiceProvider.config/bouncer.php forHow can I help you explore Laravel packages today?