{"id":22656867,"url":"https://github.com/libreworks/caridea-acl","last_synced_at":"2025-03-29T08:11:19.898Z","repository":{"id":35702292,"uuid":"39979725","full_name":"libreworks/caridea-acl","owner":"libreworks","description":":fried_shrimp: Caridea is a miniscule PHP application library. This is a shrimpy authorization library.","archived":false,"fork":false,"pushed_at":"2018-01-07T18:49:24.000Z","size":64,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-03T21:47:37.773Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/libreworks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-07-31T01:11:52.000Z","updated_at":"2025-01-29T19:31:40.000Z","dependencies_parsed_at":"2022-08-17T21:55:55.827Z","dependency_job_id":null,"html_url":"https://github.com/libreworks/caridea-acl","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/libreworks%2Fcaridea-acl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libreworks%2Fcaridea-acl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libreworks%2Fcaridea-acl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/libreworks%2Fcaridea-acl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/libreworks","download_url":"https://codeload.github.com/libreworks/caridea-acl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246156419,"owners_count":20732397,"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":[],"created_at":"2024-12-09T10:16:45.382Z","updated_at":"2025-03-29T08:11:19.881Z","avatar_url":"https://github.com/libreworks.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# caridea-acl\nCaridea is a miniscule PHP application library. This shrimpy fellow is what you'd use when you just want some helping hands and not a full-blown framework.\n\n![](http://libreworks.com/caridea-100.png)\n\nThis is its access control component. You can create lists of permissions from any source you wish.\n\n[![Packagist](https://img.shields.io/packagist/v/caridea/acl.svg)](https://packagist.org/packages/caridea/acl)\n[![Build Status](https://travis-ci.org/libreworks/caridea-acl.svg)](https://travis-ci.org/libreworks/caridea-acl)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/libreworks/caridea-acl/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/libreworks/caridea-acl/?branch=master)\n[![Code Coverage](https://scrutinizer-ci.com/g/libreworks/caridea-acl/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/libreworks/caridea-acl/?branch=master)\n\n## Installation\n\nYou can install this library using Composer:\n\n```console\n$ composer require caridea/acl\n```\n\n* The master branch (version 3.x) of this project requires PHP 7.1 and has no dependencies.\n* Version 2.x of this project requires PHP 7.0 and has no dependencies.\n* Version 1.x of this project requires PHP 5.5 and has no dependencies.\n\n## Compliance\n\nReleases of this library will conform to [Semantic Versioning](http://semver.org).\n\nOur code is intended to comply with [PSR-1](http://www.php-fig.org/psr/psr-1/), [PSR-2](http://www.php-fig.org/psr/psr-2/), and [PSR-4](http://www.php-fig.org/psr/psr-4/). If you find any issues related to standards compliance, please send a pull request!\n\n## Documentation\n\n* Head over to [Read the Docs](http://caridea-acl.readthedocs.io/en/latest/)\n\n## Definitions\n\nOur permission API deals with three concepts: Subjects, Verbs, and Targets.\n\nA *target* is something that can be protected. It has a type and an identifier. It could be a record from your database, a controller method in your application, or a URL.\n\nA *subject* is a user or role that can be allowed or denied access. `caridea-acl` ships with two kinds of `Subject`s: *principal* and *role*. For instance, the currently authenticated user has a principal `Subject` with the username, and several role `Subject`s with the role names (e.g. `admin`, `user`, `us-citizen`).\n\nA *verb* is the action the `Subject` can take on the `Target` (e.g. *read*, *create*, *submit*).\n\n`Target` and `Subject` are classes, not interfaces. Since we intend ACLs to be immutable and potentially serializable, we'd rather you not add interfaces onto your own domain classes.\n\n## Examples\n\nYou must create your own ACL loaders. We include absolutely no logic to store and retrieve ACLs.\n\nWhy? Well, in our experience, the larger an application gets, the less efficient it is to serialize and store ACLs for any record that might have permissions. We've found that most of the time an application's business rules are determined by record attributes, such as who's created what record, who's the manager of a department, and so on.\n\nBy writing your own `Loader`s, you control in very fine detail how your permission model is provided.\n\n```php\nclass MyLoader implements \\Caridea\\Acl\\Loader\n{\n    public function supports(Target $target)\n    {\n        return $target-\u003egetType() == 'foobar';\n    }\n\n    public function load(Target $target, array $subjects, Service $service)\n    {\n        // some custom method to load my database record\n        try {\n            $record = MyRecord::loadFromDatabase($target-\u003egetId());\n        } catch (\\Exception $e) {\n            throw new \\Caridea\\Acl\\Exception\\Unloadable(\"Could not load record\", 0, $e);\n        }\n        // load the parent record's ACL\n        $parent = $service-\u003eget(new Target('foobar', $record['parent']), $subjects);\n        // create the rules and return the final constructed ACL\n        $rules = [];\n        foreach ($subjects as $subject) {\n            if ($subject-\u003egetType() == 'role' \u0026\u0026\n                $subject-\u003egetId() == 'admin') {\n                // allow \"admin\" role for all permissions\n                $rules[] = Rule::allow($subject);\n            } elseif ($subject-\u003egetType() == 'role' \u0026\u0026\n                $subject-\u003egetId() == 'user') {\n                // allow \"user\" role the read permission\n                $rules[] = Rule::allow($subject, ['read']);\n            } elseif ($subject-\u003egetType() == 'principal' \u0026\u0026\n                $subject-\u003egetId() == $record['owner']) {\n                // allow the record owner CRUD permissions\n                $rules[] = Rule::allow($subject, ['create', 'read', 'update', 'delete']);\n            }\n        }\n        return new RuleAcl($target, $subjects, $rules, $parent);\n    }\n}\n```\n\nThen put it all together.\n\n```php\n// A list of all of your custom loaders\n$loaders = [new MyLoader()];\n// Use the Cache Strategy to cache lookups\n$strategy = new \\Caridea\\Acl\\CacheStrategy(\n    new \\Caridea\\Acl\\DelegateStrategy($loaders);\n);\n$service = new \\Caridea\\Acl\\Service($strategy);\n\n$subjects = MyClass::getSubjects(); // determine which subjects the user has\n$target = new Target('foobar', 123);\n\n$allowed = $service-\u003ecan($subjects, 'delete', $target);\n\ntry {\n    $service-\u003eassert($subjects, 'delete', $target);\n} catch (\\Caridea\\Acl\\Exception\\Forbidden $e) {\n    // not allowed!\n}\n```\n\nYou might consider wiring up all your loaders and the `Service` class using dependency injection, for instance with `caridea/container`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibreworks%2Fcaridea-acl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibreworks%2Fcaridea-acl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibreworks%2Fcaridea-acl/lists"}