Skip to content

Commit aaa054c

Browse files
author
Mateus Junges
authored
Merge pull request mateusjunges#107 from jungessolutions/wildcard-permissions
v1.8.0
2 parents 1068ed0 + 9936100 commit aaa054c

21 files changed

+319
-36
lines changed

CHANGELOG.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
All notable changes to `mateusjunges/laravel-acl` will be documented in this file.
44

55

6-
## [UNRELEASED]
7-
- Check wildcard permissions
8-
- Tests for new middleware
6+
## 1.8.0
7+
- Check for permissions using wildcard (fix [#77](https://github.com/jungessolutions/laravel-acl/issues/77))
8+
- Hierarchical permissions middleware
9+
- Added an artisan command to install the package
10+
- Update package docs
911

1012
## 1.7.5
1113
- Fix [#93](https://github.com/mateusjunges/laravel-acl/issues/93)

CONTRIBUTING.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Contributions are **welcome**!
44

55
We accept contributions via Pull Requests on [Github](https://github.com/mateusjunges/laravel-acl).
66

7+
If you don't know how to contribute, check the [jungessolutions/docs](https://github.com/jungessolutions/docs/blob/master/ACL.md) repository of this package.
78

89
## Pull Requests
910

README.md

+81-5
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
This package allows you to manage user permissions and groups in a database.
1313

1414
* [Installation](#installation)
15+
* [Using install command](#install-using-aclinstall-command)
16+
* [Step by step installation](#step-by-step-installation)
1517
* [Usage](#usage)
1618
* [Check for permissions](#checking-for-permissions)
19+
* [Check for permissions using wildcards](#checking-for-permissions-using-wildcards)
1720
* [Syncing user permissions](#syncing-user-permissions)
1821
* [Syncing group permissions](#syncing-group-permissions)
1922
* [Local scopes](#local-scopes)
@@ -37,7 +40,7 @@ This package allows you to manage user permissions and groups in a database.
3740

3841

3942
## Installation
40-
43+
4144
To get started with laravel-acl, use Composer to add the package to your project's dependencies:
4245

4346
``` bash
@@ -67,12 +70,24 @@ After installing the laravel-acl package, register the service provider in
6770
Junges\ACL\ACLEventsServiceProvider::class,
6871
];
6972
```
73+
74+
### Install using `acl:install` command
75+
76+
You can install this package by running the provided install command:
77+
```bash
78+
php artisan acl:install
79+
```
80+
81+
After run this command, the package installation is done. Proceed to the [usage](#usage) section.
82+
83+
### Step by step installation
84+
7085
All migrations required for this package are already included. If you
7186
need to customize the tables, you can publish [the migrations](https://github.com/mateusjunges/laravel-acl/tree/master/src/database/migrations)
7287
with:
7388

7489
```bash
75-
php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider" --tag="migrations"
90+
php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider" --tag="acl-migrations"
7691
```
7792
and set the `config` for `custom_migrations` to `true`, which is false by default.
7893

@@ -89,7 +104,7 @@ publish the config file and update the tables array.
89104
You can publish the config file with:
90105

91106
```bash
92-
php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider" --tag="config"
107+
php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider" --tag="acl-config"
93108
```
94109

95110
When published, the [`config/acl.php`](https://github.com/mateusjunges/laravel-acl/blob/master/config/acl.php) config file contains:
@@ -348,6 +363,37 @@ $group->hasAnyPermission([Permission::find(1), Permission::find(2), Permission::
348363
$group->hasAnyPermission([1, 'permission-slug' Permission::find(3)]);
349364
```
350365

366+
## Checking for permissions using wildcards
367+
Sometimes, you want to know if the logged in user has any permission related to users, like
368+
`*.users`. It can easily be done with the `ACLWildcardsTrait`.
369+
370+
Add the `ACLWildcardsTrait` to your `user` model:
371+
372+
```php
373+
use Illuminate\Foundation\Auth\User as Authenticatable;
374+
use Junges\ACL\Traits\UsersTrait;
375+
use Junges\ACL\Traits\ACLWildcardsTrait;
376+
377+
class User extends Authenticatable
378+
{
379+
use UsersTrait;
380+
use ACLWildcardsTrait;
381+
382+
//
383+
}
384+
```
385+
Then, you can check for wildcard permissions using the `hasPermissionWithWildcard` method:
386+
```php
387+
$user->hasPermissionWithWildcards('users.*');
388+
```
389+
390+
You can also use this trait to check for group permissions using wildcards.
391+
The `ACLWildcardsTrait` is used by the Group model by default:
392+
393+
```php
394+
$group->hasPermissionWithWildcards('users.*');
395+
```
396+
351397
## Syncing user permissions
352398
The user permissions can synced with this method:
353399
```php
@@ -541,14 +587,15 @@ Check for any group:
541587

542588

543589
If you want to use the middleware provided by this package
544-
(`PermissionMiddleware`, `GroupMiddleware` e `PermissionOrGroupMiddleware`),
590+
(`PermissionMiddleware`, `GroupMiddleware`, `HierarchicalPermissions` e `PermissionOrGroupMiddleware`),
545591
you need to add them to the `app/Http/Kernel.php` file,
546592
inside the `routeMiddleware` array:
547593
```php
548594
protected $routeMiddleware = [
549595
'permissions' => \Junges\ACL\Middlewares\PermissionMiddleware::class,
550596
'groups' => \Junges\ACL\Middlewares\GroupMiddleware::class,
551597
'permissionOrGroup' => \Junges\ACL\Middlewares\PermissionOrGroupMiddleware::class,
598+
'hierarchical_permissions' => \Junges\ACL\Middlewares\HierarchicalPermissionsMiddleware::class
552599
];
553600
```
554601
Then you can protect you routes using middleware rules:
@@ -571,6 +618,12 @@ Route::get('/', function(){
571618
})->middleware('groups:admin');
572619
```
573620

621+
```php
622+
Route::get('/', function(){
623+
echo "Middlewares working!";
624+
})->middleware('hierarchical_permissions:user.auth.admin');
625+
```
626+
574627
Alternatively, you can separate multiple groups or permissions with a `|` (pipe) character:
575628
```php
576629
Route::get('/', function(){
@@ -590,6 +643,12 @@ Route::get('/', function(){
590643
})->middleware('groups:admin|manager');
591644
```
592645

646+
```php
647+
Route::get('/', function(){
648+
echo "Middlewares working!";
649+
})->middleware('hierarchical_permissions:user.auth.admin|user.manager.user.admin');
650+
```
651+
593652
You can protect controller similarly, by setting desired middleware in the constructor:
594653

595654
```php
@@ -605,6 +664,13 @@ public function __construct()
605664
}
606665
```
607666

667+
```php
668+
public function __construct()
669+
{
670+
$this->middleware('hierarchical_permissions:user.auth.admin|user.manager.user.admin');
671+
}
672+
```
673+
608674
The `groups` middleware will check if the current logged in user has any of the groups passed to the middleware.
609675

610676
The `permissions` middleware will check if the current logged in user has any of the required groups
@@ -613,6 +679,16 @@ for a route.
613679
The `permissionOrGroup` will check if the current logged in user has any of the required permissions or
614680
groups necessary to access a route.
615681

682+
The `hierarchical_permissions` middleware will check if the current logged in user has any of the "sub-permissions"
683+
in the passed string. The `user.manager.user.admin` matches with all the following:
684+
```text
685+
user
686+
user.manager
687+
user.manager.user
688+
user.manager.user.admin
689+
```
690+
If the user has any of the above permissions, the access is granted.
691+
616692
In positive case, both middleware guarantee access to the route.
617693

618694
# Handling group and permission exceptions
@@ -756,7 +832,7 @@ This package also provides translations for some messages. To use them is easy:
756832
- Change your `config/app.php` file locale for your corresponding locale, like `en` or `pt-br`.
757833
- Publish the translation files with
758834
```bash
759-
php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider" --tag="translations"
835+
php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider" --tag="acl-translations"
760836
```
761837

762838
# Tests

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
},
3838
"autoload-dev": {
3939
"psr-4": {
40-
"Junges\\ACL\\Test\\": "tests/"
40+
"Junges\\ACL\\Tests\\": "tests/"
4141
}
4242
},
4343
"extra": {

src/ACLServiceProvider.php

+10-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Contracts\Config\Repository;
88
use Illuminate\Contracts\Events\Dispatcher;
99
use Junges\ACL\Console\Commands\CreateGroup;
10+
use Junges\ACL\Console\Commands\InstallCommand;
1011
use Junges\ACL\Console\Commands\ShowPermissions;
1112
use Junges\ACL\Console\Commands\UserPermissions;
1213
use Junges\ACL\Console\Commands\CreatePermission;
@@ -49,21 +50,21 @@ public function loadViews()
4950
$this->loadViewsFrom(__DIR__.'/resources/views', 'acl');
5051
$this->publishes([
5152
__DIR__.'/resources/views' => resource_path('views/vendor/junges/acl'),
52-
], 'views');
53+
], 'acl-views');
5354
}
5455

5556
/**
56-
* Load and publishes the pt-br.php configuration file.
57+
* Load and publishes the configuration file.
5758
*/
5859
public function publishConfig()
5960
{
6061
$this->publishes([
6162
__DIR__.'/../config/acl.php' => config_path('acl.php'),
62-
], 'config');
63+
], 'acl-config');
6364
}
6465

6566
/**
66-
* Load package commands.
67+
* Register the package's commands.
6768
*/
6869
public function loadCommands()
6970
{
@@ -73,12 +74,13 @@ public function loadCommands()
7374
ShowPermissions::class,
7475
CreateGroup::class,
7576
UserPermissions::class,
77+
InstallCommand::class,
7678
]);
7779
}
7880
}
7981

8082
/**
81-
* Load package migrations.
83+
* Register the package's migrations.
8284
*/
8385
public function loadMigrations()
8486
{
@@ -90,19 +92,19 @@ public function loadMigrations()
9092
}
9193
$this->publishes([
9294
__DIR__.'/database/migrations' => database_path('migrations/vendor/junges/acl'),
93-
], 'migrations');
95+
], 'acl-migrations');
9496
}
9597

9698
/**
97-
* Load package translations.
99+
* Register the package's migrations.
98100
*/
99101
public function loadTranslations()
100102
{
101103
$translationsPath = __DIR__.'/resources/lang';
102104
$this->loadTranslationsFrom($translationsPath, 'acl');
103105
$this->publishes([
104106
$translationsPath => base_path('resources/lang/vendor/acl'),
105-
], 'translations');
107+
], 'acl-translations');
106108
}
107109

108110
/**
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Junges\ACL\Console\Commands;
4+
5+
use Illuminate\Console\Command;
6+
7+
class InstallCommand extends Command
8+
{
9+
/**
10+
* The name and signature of the console command.
11+
*
12+
* @var string
13+
*/
14+
protected $signature = 'acl:install';
15+
16+
/**
17+
* The console command description.
18+
*
19+
* @var string
20+
*/
21+
protected $description = 'Install all of the Laravel ACL resources';
22+
23+
/**
24+
* Create a new command instance.
25+
*
26+
* @return void
27+
*/
28+
public function __construct()
29+
{
30+
parent::__construct();
31+
}
32+
33+
/**
34+
* Execute the console command.
35+
*
36+
* @return mixed
37+
*/
38+
public function handle()
39+
{
40+
$this->comment('Publishing Laravel ACL Migrations...');
41+
$this->callSilent('vendor:publish', ['--tag' => 'acl-migrations']);
42+
$this->comment('Using default migrations by default.');
43+
44+
$this->comment('Publishing Laravel ACL configuration...');
45+
$this->callSilent('vendor:publish', ['--tag' => 'acl-config']);
46+
47+
$this->info('Laravel ACL installed successfully');
48+
49+
$this->comment('Remember to use the UsersTrait inside your User model.');
50+
}
51+
}

src/Http/Models/Group.php

+2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
use Junges\ACL\Events\GroupSaving;
66
use Junges\ACL\Traits\GroupsTrait;
77
use Illuminate\Database\Eloquent\Model;
8+
use Junges\ACL\Traits\ACLWildcardsTrait;
89

910
class Group extends Model
1011
{
1112
use GroupsTrait;
13+
use ACLWildcardsTrait;
1214

1315
protected $dates = ['deleted_at'];
1416
protected $table;

src/Middlewares/HierarchicalMiddleware.php renamed to src/Middlewares/HierarchicalPermissionsMiddleware.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use Illuminate\Support\Facades\Auth;
77
use Junges\ACL\Exceptions\UnauthorizedException;
88

9-
class HierarchicalMiddleware
9+
class HierarchicalPermissionsMiddleware
1010
{
1111
/**
1212
* Handle an incoming request.

src/Traits/ACLWildcardsTrait.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Junges\ACL\Traits;
4+
5+
trait ACLWildcardsTrait
6+
{
7+
/**
8+
* Check if the user has a permission, but only if this permission is directly associated to the user.
9+
*
10+
* @param $permissionSlug
11+
* @return bool
12+
*/
13+
public function hasPermissionWithWildcards(string $permissionSlug) : bool
14+
{
15+
$permissionSlug = str_replace('*', '%', $permissionSlug);
16+
17+
return (bool) $this->permissions()
18+
->where('slug', 'like', $permissionSlug)
19+
->count();
20+
}
21+
}

tests/CommandsTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace Junges\Tests;
44

5-
use Junges\ACL\Test\Group;
6-
use Junges\ACL\Test\TestCase;
7-
use Junges\ACL\Test\Permission;
5+
use Junges\ACL\Tests\Group;
6+
use Junges\ACL\Tests\TestCase;
7+
use Junges\ACL\Tests\Permission;
88
use Illuminate\Support\Facades\Artisan;
99

1010
class CommandsTest extends TestCase

0 commit comments

Comments
 (0)