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

albegali/acl-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require albegali/acl-bundle
    

    Enable the bundle in config/bundles.php:

    Albegali\AclBundle\AlbegaliAclBundle::class => ['all' => true],
    
  2. Configuration: Add ACL configuration to config/packages/albegali_acl.yaml:

    albegali_acl:
        driver: doctrine # or 'orm' (alias for doctrine)
        remove_orphans: false
    
  3. First Use Case: Define an ACL entry for a route or entity in a controller or service:

    use Albegali\AclBundle\Manager\AclManager;
    
    class SomeController extends AbstractController
    {
        public function __construct(private AclManager $aclManager) {}
    
        public function index()
        {
            $this->aclManager->createMask('ROLE_USER', 'OBJECT_IDENTIFIER', 'MASK');
            // OR for routes:
            $this->aclManager->createRouteMask('ROLE_USER', 'ROUTE_NAME', 'MASK');
        }
    }
    

Key Entry Points

  • AclManager: Central class for creating/updating ACL entries.
  • Doctrine Listeners: Auto-cleanup of ACL entries when entities are deleted.
  • Controller Integration: Built-in methods to check ACLs in controllers.

Implementation Patterns

Workflows

  1. Entity-Level ACLs:

    // In a service or controller:
    $this->aclManager->createMask(
        'ROLE_ADMIN', // Role
        'OBJECT_IDENTIFIER', // e.g., 'POST_123' or 'USER_456'
        'UPDATE' // Mask (e.g., 'CREATE', 'READ', 'UPDATE', 'DELETE')
    );
    
    // Check access:
    if (!$this->aclManager->isGranted('OBJECT_IDENTIFIER', 'UPDATE')) {
        throw $this->createAccessDeniedException();
    }
    
  2. Route-Level ACLs:

    // In a controller or event subscriber:
    $this->aclManager->createRouteMask(
        'ROLE_SUPER_ADMIN',
        'app_admin_dashboard',
        'ACCESS'
    );
    
    // Check in controller:
    if (!$this->aclManager->isGrantedRoute('app_admin_dashboard')) {
        return $this->redirectToRoute('home');
    }
    
  3. Dynamic ACLs: Use Symfony’s ExpressionLanguage for dynamic rules:

    # config/packages/albegali_acl.yaml
    albegali_acl:
        expression_language:
            providers:
                - 'security.token_provider'
    
    $this->aclManager->createMask(
        'is_granted("ROLE_USER") and object.getOwner() == user',
        'POST_123',
        'DELETE'
    );
    

Integration Tips

  • Doctrine Entities: Annotate entities to auto-generate ACL identifiers:

    use Albegali\AclBundle\Model\AclAwareInterface;
    
    class Post implements AclAwareInterface
    {
        public function getAclObjectIdentifier(): string
        {
            return 'POST_' . $this->id;
        }
    }
    
  • Fixtures: Load ACLs via DoctrineFixturesBundle:

    use Albegali\AclBundle\Manager\AclManager;
    
    public function load(ObjectManager $manager)
    {
        $aclManager = $this->container->get('albegali_acl.manager');
        $aclManager->createMask('ROLE_USER', 'POST_1', 'READ');
    }
    
  • Symfony Events: Attach ACL checks to kernel events:

    use Albegali\AclBundle\EventListener\AclListener;
    
    public function onKernelRequest(GetResponseEvent $event)
    {
        $aclListener = new AclListener($this->aclManager);
        $aclListener->onKernelRequest($event);
    }
    

Gotchas and Tips

Pitfalls

  1. Object Identifiers:

    • Issue: Duplicate ACL entries if getAclObjectIdentifier() returns inconsistent values (e.g., due to lazy-loading).
    • Fix: Ensure identifiers are deterministic (e.g., USER_{$this->id} instead of USER_{$this->getUser()->id}).
  2. Doctrine ORM vs. ODM:

    • Issue: The bundle defaults to Doctrine ORM. For MongoDB ODM, explicitly set driver: odm in config.
    • Fix:
      albegali_acl:
          driver: odm
      
  3. Circular Dependencies:

    • Issue: ACL checks in entity listeners may cause circular dependencies if not handled carefully.
    • Fix: Use AclManager::isGranted() sparingly in listeners; prefer role-based checks.
  4. Performance:

    • Issue: Overusing dynamic expressions (e.g., is_granted() in masks) can slow down ACL checks.
    • Fix: Cache frequent checks or use simpler masks where possible.

Debugging

  • Enable Logging:

    albegali_acl:
        debug: true
    

    Logs ACL operations to var/log/dev.log.

  • Dump ACLs: Use the CLI command to inspect ACLs:

    php bin/console albegali:acl:dump
    
  • Common Errors:

    • "Class not found": Ensure Symfony\Security\Acl is installed (composer require symfony/security-acl).
    • "Invalid mask": Masks must be uppercase constants (e.g., MASK instead of mask).

Extension Points

  1. Custom Drivers: Extend Albegali\AclBundle\Driver\DriverInterface for non-Doctrine storage (e.g., Redis):

    class RedisAclDriver implements DriverInterface
    {
        public function createMask($role, $objectIdentifier, $mask) { /* ... */ }
        // Implement other methods...
    }
    

    Register in config:

    albegali_acl:
        driver: your_bundle.redis_acl_driver
    
  2. Custom Masks: Extend the mask system by overriding Albegali\AclBundle\Security\Acl\MaskBuilder.

  3. Event Subscribers: Listen to albegali.acl.pre_mask_create or albegali.acl.post_mask_update events for pre/post-processing:

    use Albegali\AclBundle\Event\AclEvent;
    
    public function onPreMaskCreate(AclEvent $event)
    {
        if ($event->getMask() === 'DELETE') {
            $event->setMask('UPDATE'); // Override
        }
    }
    

Configuration Quirks

  • remove_orphans: Set to true to auto-delete ACL entries when their referenced entity is deleted (default: false).

    albegali_acl:
        remove_orphans: true
    
  • Expression Language: Requires symfony/expression-language (≥3.0). For complex expressions, use:

    $this->aclManager->createMask(
        '(attribute(user) == "admin") and (object.getCategory() == "premium")',
        'POST_123',
        'DELETE'
    );
    
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