Weave 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

User Policy Bundle Laravel Package

cura/user-policy-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require cura/user-policy-bundle
    

    Add the bundle to config/app.php under providers:

    Cura\UserPolicyBundle\UserPolicyBundle::class,
    

    Publish the migration and config:

    php artisan vendor:publish --provider="Cura\UserPolicyBundle\UserPolicyBundle" --tag="migrations"
    php artisan vendor:publish --provider="Cura\UserPolicyBundle\UserPolicyBundle" --tag="config"
    

    Run the migration:

    php artisan migrate
    
  2. First Use Case: Assigning a Policy Define a policy in config/user-policies.php:

    'policies' => [
        'admin' => [
            'name' => 'Administrator Access',
            'description' => 'Full access to all features',
        ],
        'editor' => [
            'name' => 'Content Editor',
            'description' => 'Can edit and publish content',
        ],
    ],
    

    Assign a policy to a user in a controller or seeder:

    use Cura\UserPolicyBundle\Models\UserPolicy;
    
    $user->policies()->attach('admin'); // Attach by policy key
    // OR
    $user->policies()->attach(1); // Attach by ID
    
  3. Check Policy in Middleware Create middleware to verify policies:

    namespace App\Http\Middleware;
    
    use Closure;
    use Cura\UserPolicyBundle\Services\UserPolicyService;
    
    class CheckPolicy
    {
        protected $policyService;
    
        public function __construct(UserPolicyService $policyService)
        {
            $this->policyService = $policyService;
        }
    
        public function handle($request, Closure $next, $policyKey)
        {
            if (!$this->policyService->userHasPolicy($request->user(), $policyKey)) {
                abort(403);
            }
            return $next($request);
        }
    }
    

    Register in app/Http/Kernel.php:

    'check.policy' => \App\Http\Middleware\CheckPolicy::class,
    

Implementation Patterns

Workflows

  1. Dynamic Policy Assignment Use events to assign policies dynamically (e.g., on user registration or role change):

    // In EventServiceProvider
    protected $listen = [
        'App\Events\UserRegistered' => [
            'App\Listeners\AssignDefaultPolicy',
        ],
    ];
    

    Listener example:

    public function handle(UserRegistered $event)
    {
        $event->user->policies()->attach('editor');
    }
    
  2. Policy-Based Route Groups Group routes by policy requirements in routes/web.php:

    Route::middleware(['auth', 'check.policy:admin'])->group(function () {
        Route::get('/admin/dashboard', 'AdminController@dashboard');
    });
    
  3. Policy Scopes for Eloquent Extend Eloquent queries with policy-based scopes:

    namespace App\Models;
    
    use Cura\UserPolicyBundle\Scopes\UserPolicyScope;
    
    class Post extends Model
    {
        public function scopeEditableBy($query, $user)
        {
            return $query->whereHas('user.policies', function ($q) use ($user) {
                $q->whereIn('key', ['editor', 'admin'])
                  ->wherePivotUserId($user->id);
            });
        }
    }
    

Integration Tips

  • Laravel Nova Integration Extend Nova toolbars or detail views to display user policies:

    public function fields(Request $request)
    {
        return array_merge(parent::fields($request), [
            Text::make('Policies', function () {
                return $this->user->policies->pluck('name')->implode(', ');
            }),
        ]);
    }
    
  • API Resource Policies Use policies in API resources for authorization:

    public function toArray($request)
    {
        return [
            'data' => $this->resource,
            'authorized' => $request->user()->hasPolicy('editor'),
        ];
    }
    
  • Policy-Based Notifications Trigger notifications based on policy changes:

    $user->policies()->syncWithoutDetaching(['admin']);
    event(new PolicyUpdated($user, 'admin'));
    

Gotchas and Tips

Pitfalls

  1. Circular Dependencies Avoid circular references when defining policies (e.g., admin policy granting access to modify other admin policies). Use middleware to break cycles:

    if ($request->user()->hasPolicy('super_admin')) { ... }
    
  2. Mass Assignment Risks Policies are pivot tables; ensure guarded or fillable is configured in UserPolicy model:

    protected $guarded = ['user_id', 'policy_id'];
    
  3. Caching Quirks Clear policy-related caches after bulk updates:

    php artisan cache:clear
    php artisan view:clear
    

Debugging

  • Policy Assignment Issues Verify pivot table structure:

    php artisan schema:dump
    

    Check for missing foreign keys or constraints.

  • Middleware Debugging Log policy checks in middleware:

    \Log::debug('Policy check for ' . $policyKey, [
        'user_id' => $request->user()->id,
        'has_policy' => $this->policyService->userHasPolicy($request->user(), $policyKey),
    ]);
    

Extension Points

  1. Custom Policy Providers Override the default policy provider in config/user-policies.php:

    'provider' => \App\Services\CustomPolicyProvider::class,
    

    Implement Cura\UserPolicyBundle\Contracts\PolicyProvider:

    public function getPolicies()
    {
        return [
            'custom_policy' => [
                'name' => 'Custom Policy',
                'description' => 'Dynamic policy',
            ],
        ];
    }
    
  2. Policy Events Extend the bundle’s events for custom logic:

    // Listen for policy attachment
    PolicyAttached::class => function (PolicyAttached $event) {
        \Log::info("User {$event->user->id} assigned policy {$event->policy->key}");
    },
    
  3. Policy Validation Add validation rules for policy keys:

    use Cura\UserPolicyBundle\Rules\ValidPolicy;
    
    $request->validate([
        'policy' => ['required', new ValidPolicy],
    ]);
    

Config Quirks

  • Policy Key Case Sensitivity Policy keys are case-sensitive by default. Normalize keys in CustomPolicyProvider if needed:

    return array_change_key_case($policies, CASE_LOWER);
    
  • Default Policy Handling Set a default policy in config/user-policies.php:

    'default_policy' => 'guest',
    

    Use in middleware:

    if (!$this->policyService->userHasPolicy($user, $policyKey)) {
        $user->policies()->attach(config('user-policies.default_policy'));
    }
    
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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel