https://github.com/geekcell/user-policy-bundle
An opinionated bundle, which provides a way to implement user policies for your Symfony app.
https://github.com/geekcell/user-policy-bundle
Last synced: over 1 year ago
JSON representation
An opinionated bundle, which provides a way to implement user policies for your Symfony app.
- Host: GitHub
- URL: https://github.com/geekcell/user-policy-bundle
- Owner: geekcell
- License: mit
- Created: 2023-06-23T15:00:28.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2024-12-02T20:20:47.000Z (over 1 year ago)
- Last Synced: 2025-03-01T18:48:52.647Z (over 1 year ago)
- Language: PHP
- Size: 133 KB
- Stars: 0
- Watchers: 3
- Forks: 1
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Codeowners: CODEOWNERS
Awesome Lists containing this project
README
# Symfony Bundle for User Policies
This Symfony bundle provides an opinionated way to implement user policies for your app. User policies are useful when you need fine-grained/complex rules regarding access to a particular resource. These policies are not static configurations, but written in PHP, i.e. you get full flexibility, but without cluttering your code base.
## Example
Let's say you are working on a video platform where users are only allowed to upload if they either have a premium subscription or a remaining upload quota.
```php
#[AsPolicy(Video::class)]
class VideoPolicy implements Policy
{
public function __construct(
private readonly QuotaService $quotaService,
) {
}
public function upload(User $user): bool
{
return (
$user->hasPremiumSubscription() ||
$this->quotaService->getRemainingUserUploads($user) > 0
);
}
}
```
```php
class VideoController extends AbstractController
{
#[Route('/videos/new_upload')]
public function create(): Response
{
if ($this->getUser()->canUpload(Video::class)) {
// Proceed with upload ...
}
$this->createAccessDeniedException('Operation not allowed.');
}
}
```
Pretty nice, isn't it? The business logic is encapsulated in policy classes and can be _magically queried_ directly from the user object.
## Installation
To use this bundle, require it in Composer
```bash
composer require geekcell/user-policy-bundle
```
When installed, add the following lines in your `config/services.yaml`
```yaml
services:
# Add these lines below to your services.yaml
_instanceof:
GeekCell\UserPolicyBundle\Contracts\Policy:
tags: ['geek_cell.user_policy.policy']
```
These lines are crucial for Symfony to auto-discover the policies defined in your app. Alternatively, policies can be manually configured or even guessed by name, but these methods are not recommended.
Now add the `HasPolicies` trait to you user class.
```php
can('create', 'App\Entity\Book');
$user->canCreate('App\Entity\Book');
$user->cannot('create', 'App\Entity\Book');
$user->cannotCreate('App\Entity\Book');
// These will call BookPolicy::update($user, $book)
$user->can('update', $book);
$user->canUpdate($book);
$user->cannot('update', $book);
$user->canUpdate($book);
// And these will call BookPolicy::delete($user, $book, $foo, $bar, $baz)
$user->can('delete', $book, $foo, $bar, $baz);
$user->canDelete($book, $foo, $bar, $baz);
$user->cannot('delete', $book, $foo, $bar, $baz);
$user->cannnotDelete($book, $foo, $bar, $baz);
```
## Roles Helper
In many cases, policies are likely to have some relationship to one or more rules associated with a user. This bundle provides some convenience methods to make roles easier to query.
```php
$user->setRoles(['MANAGER_ROLE', 'EDITOR_ROLE']);
$user->is('editor'); // true
$user->isEditor(); // true
$user->is('manager'); // true
$user->isManager(); // true
$user->isNot('admin'); // true
$user->isNotAdmin(); // true
```
## Inspiration(s)
- Laravel Authorization (https://laravel.com/docs/authorization)