{"id":15287263,"url":"https://github.com/programarivm/easy-acl-bundle","last_synced_at":"2025-04-13T05:08:34.939Z","repository":{"id":57044988,"uuid":"237597074","full_name":"programarivm/easy-acl-bundle","owner":"programarivm","description":"Easy-to-use access control list (ACL) bundle in Symfony 5.","archived":false,"fork":false,"pushed_at":"2023-08-12T11:44:39.000Z","size":6,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-01T15:27:04.154Z","etag":null,"topics":["access","acl","bundle","control","list","security","symfony"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/programarivm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-01T10:19:07.000Z","updated_at":"2023-11-09T19:00:11.000Z","dependencies_parsed_at":"2022-08-24T04:11:11.785Z","dependency_job_id":null,"html_url":"https://github.com/programarivm/easy-acl-bundle","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programarivm%2Feasy-acl-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programarivm%2Feasy-acl-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programarivm%2Feasy-acl-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/programarivm%2Feasy-acl-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/programarivm","download_url":"https://codeload.github.com/programarivm/easy-acl-bundle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219847001,"owners_count":16556416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["access","acl","bundle","control","list","security","symfony"],"created_at":"2024-09-30T15:27:09.187Z","updated_at":"2024-10-14T18:20:51.464Z","avatar_url":"https://github.com/programarivm.png","language":"PHP","readme":"# EasyAcl Bundle\n\nEasy-to-use access control list (ACL) bundle in Symfony 5.\n\n### Install\n\nVia composer:\n\n```text\n$ composer require programarivm/easy-acl-bundle\n```\n\n### Configuration\n\nConfigure your app's routes in `config/routes.yaml`.\n\n```yaml\n# config/routes.yaml\napi_post_create:\n    path:       /api/posts\n    controller: App\\Controller\\Post\\CreateController::index\n    methods:    POST\n\napi_post_delete:\n    path:       /api/posts/{id}\n    controller: App\\Controller\\Post\\DeleteController::index\n    methods:    DELETE\n\napi_post_edit:\n    path:       /api/posts/{id}\n    controller: App\\Controller\\Post\\EditController::index\n    methods:    PUT\n```\n\nSet up permissions as in the example shown below.\n\n```yaml\n# config/packages/programarivm_easy_acl.yaml\nprogramarivm_easy_acl:\n  target: App\\Entity\\User\n  permission:\n    -\n      role: Superadmin\n      routes:\n        - api_post_create\n        - api_post_delete\n        - api_post_edit\n    -\n      role: Admin\n      routes:\n        - api_post_create\n        - api_post_edit\n    -\n      role: Basic\n      routes:\n        - api_post_create\n```\n\nUpdate your `config/services.yaml` file.\n\n```yaml\n# config/services.yaml\nservices:\n    Programarivm\\EasyAclBundle\\Command\\SetupCommand:\n        arguments:\n            $projectDir: '%kernel.project_dir%'\n        tags: ['console.command']\n\n    Programarivm\\EasyAclBundle\\Repository\\:\n        resource: '../vendor/programarivm/easy-acl-bundle/src/Repository'\n        autowire: true\n        tags: ['doctrine.repository_service']\n\n    Programarivm\\EasyAclBundle\\EventListener\\IdentitySubscriber:\n        tags: ['doctrine.event_subscriber']\n```\n\nDon't forget to update your database schema:\n\n    php bin/console doctrine:schema:update --force\n\nThis will create four empty tables in your database:\n\n- `easy_acl_identity`\n- `easy_acl_permission`\n- `easy_acl_role`\n- `easy_acl_route`\n\nWhich go hand in hand with the entities:\n\n- [`Programarivm\\EasyAclBundle\\Entity\\Identity`](https://github.com/programarivm/easy-acl-bundle/blob/master/src/Entity/Identity.php)\n- [`Programarivm\\EasyAclBundle\\Entity\\Permission`](https://github.com/programarivm/easy-acl-bundle/blob/master/src/Entity/Permission.php)\n- [`Programarivm\\EasyAclBundle\\Entity\\Role`](https://github.com/programarivm/easy-acl-bundle/blob/master/src/Entity/Role.php)\n- [`Programarivm\\EasyAclBundle\\Entity\\Route`](https://github.com/programarivm/easy-acl-bundle/blob/master/src/Entity/Route.php)\n\nAnd the repositories:\n\n- [`Programarivm\\EasyAclBundle\\Repository\\IdentityRepository`](https://github.com/programarivm/easy-acl-bundle/blob/master/src/Repository/IdentityRepository.php)\n- [`Programarivm\\EasyAclBundle\\Repository\\PermissionRepository`](https://github.com/programarivm/easy-acl-bundle/blob/master/src/Repository/PermissionRepository.php)\n- [`Programarivm\\EasyAclBundle\\Repository\\RoleRepository`](https://github.com/programarivm/easy-acl-bundle/blob/master/src/Repository/RoleRepository.php)\n- [`Programarivm\\EasyAclBundle\\Repository\\RouteRepository`](https://github.com/programarivm/easy-acl-bundle/blob/master/src/Repository/RouteRepository.php)\n\n### `easy-acl:setup` command\n\nCommand line:\n\n    php bin/console easy-acl:setup\n    This will reset the ACL. Are you sure to continue? (y) y\n\nMySQL console:\n\n    mysql\u003e select * from easy_acl_identity;\n    Empty set (0.01 sec)\n\n    mysql\u003e select * from easy_acl_permission;\n    +----+------------+-----------------+\n    | id | rolename   | routename       |\n    +----+------------+-----------------+\n    |  1 | Superadmin | api_post_create |\n    |  2 | Superadmin | api_post_delete |\n    |  3 | Superadmin | api_post_edit   |\n    |  4 | Admin      | api_post_create |\n    |  5 | Admin      | api_post_edit   |\n    |  6 | Basic      | api_post_create |\n    +----+------------+-----------------+\n    6 rows in set (0.00 sec)\n\n    mysql\u003e select * from easy_acl_role;\n    +----+------------+\n    | id | name       |\n    +----+------------+\n    |  1 | Superadmin |\n    |  2 | Admin      |\n    |  3 | Basic      |\n    +----+------------+\n    3 rows in set (0.00 sec)\n\n    mysql\u003e select * from easy_acl_route;\n    +----+-----------------+---------+-----------------+\n    | id | name            | methods | path            |\n    +----+-----------------+---------+-----------------+\n    |  1 | api_post_create | POST    | /api/posts      |\n    |  2 | api_post_delete | DELETE  | /api/posts/{id} |\n    |  3 | api_post_edit   | PUT     | /api/posts/{id} |\n    +----+-----------------+---------+-----------------+\n    3 rows in set (0.00 sec)\n\nAs you can see, three `EasyAcl` tables are populated with the data contained in `config/packages/programarivm_easy_acl.yaml`, however it is up to you to define your users' identities.\n\nExample on how to set the `Superadmin` identity to `alice`:\n\n```php\nuse Programarivm\\EasyAclBundle\\Entity\\Identity;\n\n...\n\n$user = self::$em-\u003egetRepository('App:User')-\u003efindOneBy(['username' =\u003e 'alice');\n$role = self::$em-\u003egetRepository('EasyAclBundle:Role')-\u003efindOneBy(['name' =\u003e 'Superadmin']);\n\n$this-\u003eem-\u003epersist(\n    (new Identity())\n        -\u003esetUser($user)\n        -\u003esetRole($role)\n);\n\n...\n\n$this-\u003eem-\u003eflush();\n```\n\n    mysql\u003e select * from easy_acl_identity;\n    +----+---------+---------+\n    | id | role_id | user_id |\n    +----+---------+---------+\n    |  1 |       1 |       1 |\n    +----+---------+---------+\n    1 row in set (0.00 sec)\n\nFinally, the permission repository helps you determine whether or not a particular role can access a given resource:\n\n```php\n$isAllowed = $this-\u003eem\n                -\u003egetRepository('EasyAclBundle:Permission')\n                -\u003eisAllowed('Superadmin', 'api_post_show');\n```\n\nMore specifically, the example below shows how a JWT token can be authorized in an [event subscriber](https://symfony.com/doc/current/event_dispatcher/before_after_filters.html#creating-an-event-subscriber) with the help of the permission repository.\n\n```php\n// src/EventSubscriber/TokenSubscriber.php\n\nnamespace App\\EventSubscriber;\n\nuse App\\Controller\\AccessTokenController;\nuse Doctrine\\ORM\\EntityManagerInterface;\nuse Firebase\\JWT\\JWT;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\nuse Symfony\\Component\\HttpKernel\\Event\\ControllerEvent;\nuse Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException;\nuse Symfony\\Component\\HttpKernel\\KernelEvents;\n\nclass TokenSubscriber implements EventSubscriberInterface\n{\n    public function __construct(EntityManagerInterface $em)\n    {\n        $this-\u003eem = $em;\n    }\n\n    public function onKernelController(ControllerEvent $event)\n    {\n        $controller = $event-\u003egetController();\n\n        // when a controller class defines multiple action methods, the controller\n        // is returned as [$controllerInstance, 'methodName']\n        if (is_array($controller)) {\n            $controller = $controller[0];\n        }\n\n        if ($controller instanceof AccessTokenController) {\n            $jwt = substr($event-\u003egetRequest()-\u003eheaders-\u003eget('Authorization'), 7);\n\n            try {\n                $decoded = JWT::decode($jwt, getenv('JWT_SECRET'), ['HS256']);\n            } catch (\\Exception $e) {\n                throw new AccessDeniedHttpException('Whoops! Access denied.');\n            }\n\n            $user = $this-\u003eem-\u003egetRepository('App:User')\n                        -\u003efindOneBy(['id' =\u003e $decoded-\u003esub]);\n\n            $identity = $this-\u003eem-\u003egetRepository('EasyAclBundle:Identity')\n                            -\u003efindBy(['user' =\u003e $user]);\n\n            $rolename = $identity[0]-\u003egetRole()-\u003egetName();\n            $routename = $event-\u003egetRequest()-\u003eget('_route');\n\n            $isAllowed = $this-\u003eem-\u003egetRepository('EasyAclBundle:Permission')\n                            -\u003eisAllowed($rolename, $routename);\n\n            if (!$isAllowed) {\n                throw new AccessDeniedHttpException('Whoops! Access denied.');\n            }\n        }\n    }\n\n    public static function getSubscribedEvents()\n    {\n        return [\n            KernelEvents::CONTROLLER =\u003e 'onKernelController',\n        ];\n    }\n}\n```\n\n### `EasyAcl` usage\n\nThe bundle provides you with `Programarivm\\EasyAclBundle\\EasyAcl` which can be used to access the bundle information in the YAML config file in a friendly, object-oriented way.\n\nExample:\n\n```php\n// src/DataFixtures/EasyAcl/RoleFixtures.php\n\nnamespace App\\DataFixtures\\EasyAcl;\n\nuse Doctrine\\Bundle\\FixturesBundle\\Fixture;\nuse Doctrine\\Bundle\\FixturesBundle\\FixtureGroupInterface;\nuse Doctrine\\Common\\Persistence\\ObjectManager;\nuse Programarivm\\EasyAclBundle\\EasyAcl;\nuse Programarivm\\EasyAclBundle\\Entity\\Role;\n\nclass RoleFixtures extends Fixture implements FixtureGroupInterface\n{\n    private $easyAcl;\n\n    public function __construct(EasyAcl $easyAcl)\n    {\n        $this-\u003eeasyAcl = $easyAcl;\n    }\n\n    public function load(ObjectManager $manager)\n    {\n        foreach ($this-\u003eeasyAcl-\u003egetPermission() as $key =\u003e $permission) {\n            $role = (new Role())-\u003esetName($permission['role']);\n            $manager-\u003epersist($role);\n            $this-\u003eaddReference(\"role-$key\", $role);\n        }\n\n        $manager-\u003eflush();\n    }\n\n    public static function getGroups(): array\n    {\n        return [\n            'easy-acl',\n        ];\n    }\n}\n```\n\nExample:\n\n```php\n// src/DataFixtures/EasyAcl/IdentityFixtures.php\n\nnamespace App\\DataFixtures\\EasyAcl;\n\nuse App\\DataFixtures\\UserFixtures;\nuse Doctrine\\Bundle\\FixturesBundle\\Fixture;\nuse Doctrine\\Bundle\\FixturesBundle\\FixtureGroupInterface;\nuse Doctrine\\Common\\DataFixtures\\DependentFixtureInterface;\nuse Doctrine\\Common\\Persistence\\ObjectManager;\nuse Programarivm\\EasyAclBundle\\EasyAcl;\nuse Programarivm\\EasyAclBundle\\Entity\\Identity;\n\nclass IdentityFixtures extends Fixture implements FixtureGroupInterface, DependentFixtureInterface\n{\n    private $easyAcl;\n\n    public function __construct(EasyAcl $easyAcl)\n    {\n        $this-\u003eeasyAcl = $easyAcl;\n    }\n\n    public function load(ObjectManager $manager)\n    {\n        for ($i = 0; $i \u003c UserFixtures::N; $i++) {\n            $index = rand(0, count($this-\u003eeasyAcl-\u003egetPermission())-1);\n            $user = $this-\u003egetReference(\"user-$i\");\n            $role = $this-\u003egetReference(\"role-$index\");\n            $manager-\u003epersist(\n                (new Identity())\n                    -\u003esetUser($user)\n                    -\u003esetRole($role)\n            );\n        }\n\n        $manager-\u003eflush();\n    }\n\n    public static function getGroups(): array\n    {\n        return [\n            'easy-acl',\n        ];\n    }\n\n    public function getDependencies(): array\n    {\n        return [\n            RoleFixtures::class,\n            UserFixtures::class,\n        ];\n    }\n}\n```\n\n### Contributions\n\nWould you help make this Symfony bundle better?\n\n- Feel free to send a pull request\n- Drop an email at info@programarivm.com with the subject \"EasyAcl\"\n- Leave me a comment on [Twitter](https://twitter.com/programarivm)\n\nThank you.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogramarivm%2Feasy-acl-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprogramarivm%2Feasy-acl-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprogramarivm%2Feasy-acl-bundle/lists"}