piggly / php-capabilities-manager
A simple object to manage capabilities by checking allowed operations.
Requires
- php: ^7.2 || ^8.0
Requires (Dev)
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2024-11-09 07:40:51 UTC
README
The Capability Manager is a library which allows better controlling and checking for Capabilities and allowed operations to each Capability.
How?
It's a common practice to systems have some scopes
, roles
or even permissions
and capabilities
to Users or Clients. And often, they also attached to operations. This library assumes the following operations exists:
You can, of course, customize them by using\Piggly\CapabilitiesManager\Enum\CapabilityOperations
class. Adding new operations with add()
method, removing with remove()
method and using set()
method to a completely new array
of operations.
After, these operations can be attached to capabilities. For example, see below some capabilities samples:
You can, if want or your system need, just ignore operations behavior and use only capabilities keys. This library can support it.
If an user may be allowed to only read posts, his capabilities will be posts:read
. We can achieve this in a smart and simple way:
use Piggly\CapabilitiesManager\Capability; use Piggly\CapabilitiesManager\Capabilities; $caps = new Capabilities(); $caps->add((new Capability())->setKey('posts')->add('read'));
What if the same user can also read/edit comments?
use Piggly\CapabilitiesManager\Capability; use Piggly\CapabilitiesManager\Capabilities; $caps = new Capabilities(); $caps ->add((new Capability())->setKey('posts')->add('read')) ->add((new Capability())->setKey('comments')->add('read', 'write'));
Keep in mind
Capability
object does not care about care about operations order, which meansadd('read', 'write')
is same asadd('write', 'read')
.
Somehow, the same user can do any operations at page
capability. So:
use Piggly\CapabilitiesManager\Capability; use Piggly\CapabilitiesManager\Capabilities; $caps = new Capabilities(); $caps ->add((new Capability())->setKey('posts')->add('read')) ->add((new Capability())->setKey('comments')->add('read', 'write')) ->add((new Capability())->setKey('pages')->allowAny();
Capabitities Syntax
But, there also a simple and compact way to add/create capabilities. By using the capability syntax, which is: <capability_key>:<operation>,...,<operation>
. See below:
use Piggly\CapabilitiesManager\Capability; use Piggly\CapabilitiesManager\Capabilities; $caps = new Capabilities(); $caps ->add(new Capability('posts:read')) ->add(new Capability('comments:read,write')) ->add(new Capability('pages'));
Or even more compact by separating capabilities syntax with a space char:
use Piggly\CapabilitiesManager\Capability; use Piggly\CapabilitiesManager\Capabilities; $caps = new Capabilities('posts:read comments:read,write pages');
If you don't attach operations at syntax, such as page
above, capability syntax will allow the any
operation to that capability. If you want to change this behaviour, you will need to send some default operations.
use Piggly\CapabilitiesManager\Capability; use Piggly\CapabilitiesManager\Capabilities; $caps = new Capabilities('posts:read comments:read,write pages', ['read']);
Now pages
will only have read
operation.
A
Capability
object will throw anInvalidArgumentException
if something wrong with capability syntax. For example, if you createcomments:read,write,unknown
, an exception will be thrown becauseunknown
is not a valid operation.
And how it can help me?
After creating capabilities, you can a lot of things to them, such as:
- Check if one
Capabilities
object has the exactly same capabilities and operations of another by usingisMatching()
method; - Check if one
Capabilities
object fits another by usingisFitting()
method; - Check if a capability and operation is allowed at
Capabilities
object withisAllowed()
method; - Check if any of required operations for a capabitity is allowed at
Capabilities
object withisAnyAllowed()
method; - Check if all of required operations for a capability is allowed at
Capabilities
object withisAllAllowed()
method; - You can manage capabilities with
add()
,merge()
,remove()
,removeMany()
andget()
methods atCapabilities
object; - You can
serialize
theCapabilities
object, convert tojson
, convert toarray
or even tostring
.
Real-world minimal example
use Piggly\CapabilitiesManager\Capability; use Piggly\CapabilitiesManager\Capabilities; // Getting sent capabitities $caps = filter_input ( INPUT_POST, 'capabilities', FILTER_SANITIZE_STRING ); // Create capabilities try { $caps = new Capabilities($caps); } catch ( Exception $e ) { return 'You capability syntax is invalid.'; } // You can save this capabilities to user of many ways: $user->setCapabilities($caps->toJson())->save(); // json format $user->setCapabilities((string)$caps)->save(); // string format $user->setCapabilities(serialize($caps))->save(); // serialized format // ... soon, you can read accordingly $caps = (new Capabilities())->fromJson($user->getCapabilities()); // json format $caps = new Capabilities($user->getCapabilities()); // string format $caps = unserialize($user->getCapabilities()); // unserialized format // To better control user data, you have to do the User object manages Capabilities object: // Class below is a simple sample class User { // ... public function setCapabilities ( Capabilities $caps ) { $this->caps = $caps; } public function getCapabilities () : Capabilities { return $caps; } public function save () { // ... $this->caps = (string) $caps; DB::save($this); } public function load () { $data = DB::load($this); // ... $this->caps = new Capabilities($data['caps']); } } // ... then, user may try to access a middleware requiring some capability and operation $required_capability = 'posts'; $required_operation = 'read'; if ( !$caps->isAllowed($required_capability, $required_operation) ) { /** User cannot access it **/ }
Capabilities
class is flexible and can achive many goals by managing users/clients capabitities at any kind of system.
Changelog
See the CHANGELOG file for information about all code changes.
Testing the code
This library uses the PHPUnit. We carry out tests of all the main classes of this application.
vendor/bin/phpunit
Contributions
See the CONTRIBUTING file for information before submitting your contribution.
Credits
Support the project
Piggly Studio is an agency located in Rio de Janeiro, Brazil. If you like this library and want to support this job, be free to donate any value to BTC wallet 3DNssbspq7dURaVQH6yBoYwW3PhsNs8dnK
❤.
License
MIT License (MIT). See LICENSE.