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

Acl Bundle Laravel Package

baconmanager/acl-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup for Laravel (Symfony-inspired)

Since this is a Symfony2 bundle, we'll adapt it for Laravel using Laravel Symfony Bridge or Laravel Symfony Integration (e.g., spatie/laravel-symfony-support). Here’s how to start:

  1. Install Dependencies

    composer require baconmanager/acl-bundle
    composer require symfony/console symfony/dependency-injection symfony/http-kernel
    
  2. Register the Bundle In config/app.php, add the bundle to the extra.bundles array:

    'extra.bundles' => [
        // ...
        Bacon\Bundle\AclBundle\BaconAclBundle::class,
    ],
    
  3. Configure ACL In config/acl.php (create if missing):

    return [
        'user_class' => App\Models\User::class,
        'group_class' => App\Models\Group::class,
        'route_redirect_after_save' => 'fos_user_group_list',
        'configuration' => [
            'entities' => [
                'module_class' => Bacon\Bundle\AclBundle\Entity\Module::class,
                'module_actions' => App\Models\ModuleActions::class,
                'module_actions_group' => App\Models\ModuleActionsGroup::class,
            ],
        ],
    ];
    
  4. Define Routes In routes/web.php:

    Route::group(['prefix' => 'admin'], function () {
        // FOSUser Group Routes
        Route::resource('group', \FOS\UserBundle\Controller\GroupController::class)
            ->names('fos_user_group');
    
        // ACL Module Routes
        Route::resource('acl/module', \Bacon\Bundle\AclBundle\Controller\ModuleController::class)
            ->names('bacon_acl_module');
    });
    
  5. Create Required Entities Adapt the provided Symfony entities to Laravel Eloquent models (e.g., User, Group, ModuleActions, ModuleActionsGroup). Example for ModuleActionsGroup:

    namespace App\Models;
    
    use Bacon\Bundle\AclBundle\Model\ModuleActionsGroupInterface;
    use Bacon\Bundle\CoreBundle\Entity\BaseEntity;
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\Relations\BelongsTo;
    
    class ModuleActionsGroup extends Model implements ModuleActionsGroupInterface
    {
        protected $table = 'module_actions_has_group';
    
        public function group(): BelongsTo
        {
            return $this->belongsTo(Group::class, 'group_id');
        }
    
        public function module(): BelongsTo
        {
            return $this->belongsTo(\Bacon\Bundle\AclBundle\Entity\Module::class, 'module_id');
        }
    
        public function moduleActions(): BelongsTo
        {
            return $this->belongsTo(ModuleActions::class, 'module_actions_id');
        }
    }
    
  6. Run Migrations Generate and run migrations for the new tables (e.g., module_actions, module_actions_has_group).

  7. First Use Case: Assign Permissions Use the admin panel at /admin/acl/module to define modules (e.g., "Users", "Products") and their actions (e.g., "view", "edit"). Assign these to groups via /admin/group.


Implementation Patterns

1. Role-Based Access Control (RBAC) Workflow

  • Define Modules/Actions: Create Module entities (e.g., "Dashboard", "Orders") and associate them with ModuleActions (e.g., "create", "delete").

    $module = new \Bacon\Bundle\AclBundle\Entity\Module();
    $module->setName('Orders');
    $module->setRoute('orders.index');
    $module->save();
    
    $action = new App\Models\ModuleActions();
    $action->setModule($module);
    $action->setName('delete');
    $action->save();
    
  • Assign to Groups: Link actions to groups via ModuleActionsGroup:

    $group = App\Models\Group::find(1); // "Admins" group
    $moduleActionsGroup = new App\Models\ModuleActionsGroup();
    $moduleActionsGroup->setGroup($group);
    $moduleActionsGroup->setModuleActions($action);
    $moduleActionsGroup->setEnabled(true);
    $moduleActionsGroup->save();
    
  • Check Permissions in Code: Use a service or repository to check if a user (via their groups) has access:

    public function isAllowed($user, $moduleRoute, $action)
    {
        $groupIds = $user->groups->pluck('id');
        return App\Models\ModuleActionsGroup::whereIn('group_id', $groupIds)
            ->where('module.route', $moduleRoute)
            ->where('module_actions.name', $action)
            ->where('enabled', true)
            ->exists();
    }
    

2. Middleware for Route Protection

Create a middleware to enforce ACL checks:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class AclMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $user = auth()->user();
        $moduleRoute = $request->route()->getName();
        $action = $request->method(); // e.g., "GET", "POST"

        if (!$this->isAllowed($user, $moduleRoute, strtolower($action))) {
            abort(403, 'Unauthorized action.');
        }

        return $next($request);
    }

    protected function isAllowed($user, $moduleRoute, $action)
    {
        // Implement logic from the previous example.
    }
}

Register it in app/Http/Kernel.php:

protected $routeMiddleware = [
    'acl' => \App\Http\Middleware\AclMiddleware::class,
];

Apply to routes:

Route::get('/admin/orders/{order}/delete', function () {
    // ...
})->middleware('acl');

3. Dynamic UI Permissions

Use Blade directives to hide/show UI elements based on ACL:

@php
    $canEdit = \App\Http\Middleware\AclMiddleware::isAllowed(
        auth()->user(),
        'orders.index',
        'edit'
    );
@endphp

@if($canEdit)
    <button class="btn btn-edit">Edit</button>
@endif

4. Bulk Permission Management

For admin panels, fetch all permissions for a group:

$group = App\Models\Group::find(1);
$permissions = App\Models\ModuleActionsGroup::where('group_id', $group->id)
    ->with(['moduleActions', 'module'])
    ->get();

Render in a table with checkboxes for toggling enabled.


Gotchas and Tips

1. Entity Configuration Quirks

  • Laravel vs. Symfony ORM: The bundle assumes Doctrine ORM. For Laravel, ensure:

    • Table names match the Symfony examples (e.g., module_actions_has_group).
    • Relationships use Laravel conventions (e.g., belongsTo instead of @ORM\ManyToOne).
    • Foreign keys are named consistently (e.g., module_id, group_id).
  • Base Classes: The bundle provides base classes (e.g., BaseModuleActions). Extend these in Laravel by copying their properties/methods to your Eloquent models.

2. Route and Redirect Issues

  • route_redirect_after_save: The config expects a Symfony route name (e.g., fos_user_group_list). In Laravel, use the route name defined in routes/web.php (e.g., group.index). If redirects fail, debug with:

    dd(Route::getRoutes()->getByName('fos_user_group_list')); // Check if route exists.
    
  • Admin Prefix: The bundle assumes routes are prefixed with /admin/. Adjust the prefix in routing.yml (Laravel: routes/web.php) if needed.

3. Permission Caching

  • Performance: ACL checks can be slow for large datasets. Cache results:
    public function isAllowed($user, $moduleRoute, $action)
    {
        $cacheKey = "acl:{$user->id}:{$moduleRoute}:{$action}";
        return cache()->remember($cacheKey, now()->addHours(1), function () use ($user, $moduleRoute, $action) {
            return App\Models\ModuleActionsGroup::whereIn('group_id', $user->groups->pluck('id'))
                ->where('module.route', $moduleRoute)
                ->where('module_actions.name', $action)
                ->where('enabled', true)
                ->exists();
        });
    }
    

4. Debugging ACL Logic

  • Log Missing Permissions: Add logging to identify why a user is denied access:
    if (!$this->isAllowed($user, $moduleRoute, $action)) {
        \Log::debug("ACL Denied", [
            'user_id' => $user->id,
            'module_route' => $moduleRoute
    
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware