Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #107 from jungessolutions/wildcard-permissions
Browse files Browse the repository at this point in the history
v1.8.0
  • Loading branch information
Mateus Junges committed Jul 4, 2019
2 parents 1068ed0 + 9936100 commit aaa054c
Show file tree
Hide file tree
Showing 21 changed files with 319 additions and 36 deletions.
8 changes: 5 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
All notable changes to `mateusjunges/laravel-acl` will be documented in this file.


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

## 1.7.5
- Fix [#93](https://github.com/mateusjunges/laravel-acl/issues/93)
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Contributions are **welcome**!

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

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.

## Pull Requests

Expand Down
86 changes: 81 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
This package allows you to manage user permissions and groups in a database.

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


## Installation

To get started with laravel-acl, use Composer to add the package to your project's dependencies:

``` bash
Expand Down Expand Up @@ -67,12 +70,24 @@ After installing the laravel-acl package, register the service provider in
Junges\ACL\ACLEventsServiceProvider::class,
];
```

### Install using `acl:install` command

You can install this package by running the provided install command:
```bash
php artisan acl:install
```

After run this command, the package installation is done. Proceed to the [usage](#usage) section.

### Step by step installation

All migrations required for this package are already included. If you
need to customize the tables, you can publish [the migrations](https://github.com/mateusjunges/laravel-acl/tree/master/src/database/migrations)
with:

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

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

```bash
php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider" --tag="config"
php artisan vendor:publish --provider="Junges\ACL\ACLServiceProvider" --tag="acl-config"
```

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

## Checking for permissions using wildcards
Sometimes, you want to know if the logged in user has any permission related to users, like
`*.users`. It can easily be done with the `ACLWildcardsTrait`.

Add the `ACLWildcardsTrait` to your `user` model:

```php
use Illuminate\Foundation\Auth\User as Authenticatable;
use Junges\ACL\Traits\UsersTrait;
use Junges\ACL\Traits\ACLWildcardsTrait;

class User extends Authenticatable
{
use UsersTrait;
use ACLWildcardsTrait;

//
}
```
Then, you can check for wildcard permissions using the `hasPermissionWithWildcard` method:
```php
$user->hasPermissionWithWildcards('users.*');
```

You can also use this trait to check for group permissions using wildcards.
The `ACLWildcardsTrait` is used by the Group model by default:

```php
$group->hasPermissionWithWildcards('users.*');
```

## Syncing user permissions
The user permissions can synced with this method:
```php
Expand Down Expand Up @@ -541,14 +587,15 @@ Check for any group:


If you want to use the middleware provided by this package
(`PermissionMiddleware`, `GroupMiddleware` e `PermissionOrGroupMiddleware`),
(`PermissionMiddleware`, `GroupMiddleware`, `HierarchicalPermissions` e `PermissionOrGroupMiddleware`),
you need to add them to the `app/Http/Kernel.php` file,
inside the `routeMiddleware` array:
```php
protected $routeMiddleware = [
'permissions' => \Junges\ACL\Middlewares\PermissionMiddleware::class,
'groups' => \Junges\ACL\Middlewares\GroupMiddleware::class,
'permissionOrGroup' => \Junges\ACL\Middlewares\PermissionOrGroupMiddleware::class,
'hierarchical_permissions' => \Junges\ACL\Middlewares\HierarchicalPermissionsMiddleware::class
];
```
Then you can protect you routes using middleware rules:
Expand All @@ -571,6 +618,12 @@ Route::get('/', function(){
})->middleware('groups:admin');
```

```php
Route::get('/', function(){
echo "Middlewares working!";
})->middleware('hierarchical_permissions:user.auth.admin');
```

Alternatively, you can separate multiple groups or permissions with a `|` (pipe) character:
```php
Route::get('/', function(){
Expand All @@ -590,6 +643,12 @@ Route::get('/', function(){
})->middleware('groups:admin|manager');
```

```php
Route::get('/', function(){
echo "Middlewares working!";
})->middleware('hierarchical_permissions:user.auth.admin|user.manager.user.admin');
```

You can protect controller similarly, by setting desired middleware in the constructor:

```php
Expand All @@ -605,6 +664,13 @@ public function __construct()
}
```

```php
public function __construct()
{
$this->middleware('hierarchical_permissions:user.auth.admin|user.manager.user.admin');
}
```

The `groups` middleware will check if the current logged in user has any of the groups passed to the middleware.

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

The `hierarchical_permissions` middleware will check if the current logged in user has any of the "sub-permissions"
in the passed string. The `user.manager.user.admin` matches with all the following:
```text
user
user.manager
user.manager.user
user.manager.user.admin
```
If the user has any of the above permissions, the access is granted.

In positive case, both middleware guarantee access to the route.

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

# Tests
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
},
"autoload-dev": {
"psr-4": {
"Junges\\ACL\\Test\\": "tests/"
"Junges\\ACL\\Tests\\": "tests/"
}
},
"extra": {
Expand Down
18 changes: 10 additions & 8 deletions src/ACLServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Contracts\Config\Repository;
use Illuminate\Contracts\Events\Dispatcher;
use Junges\ACL\Console\Commands\CreateGroup;
use Junges\ACL\Console\Commands\InstallCommand;
use Junges\ACL\Console\Commands\ShowPermissions;
use Junges\ACL\Console\Commands\UserPermissions;
use Junges\ACL\Console\Commands\CreatePermission;
Expand Down Expand Up @@ -49,21 +50,21 @@ public function loadViews()
$this->loadViewsFrom(__DIR__.'/resources/views', 'acl');
$this->publishes([
__DIR__.'/resources/views' => resource_path('views/vendor/junges/acl'),
], 'views');
], 'acl-views');
}

/**
* Load and publishes the pt-br.php configuration file.
* Load and publishes the configuration file.
*/
public function publishConfig()
{
$this->publishes([
__DIR__.'/../config/acl.php' => config_path('acl.php'),
], 'config');
], 'acl-config');
}

/**
* Load package commands.
* Register the package's commands.
*/
public function loadCommands()
{
Expand All @@ -73,12 +74,13 @@ public function loadCommands()
ShowPermissions::class,
CreateGroup::class,
UserPermissions::class,
InstallCommand::class,
]);
}
}

/**
* Load package migrations.
* Register the package's migrations.
*/
public function loadMigrations()
{
Expand All @@ -90,19 +92,19 @@ public function loadMigrations()
}
$this->publishes([
__DIR__.'/database/migrations' => database_path('migrations/vendor/junges/acl'),
], 'migrations');
], 'acl-migrations');
}

/**
* Load package translations.
* Register the package's migrations.
*/
public function loadTranslations()
{
$translationsPath = __DIR__.'/resources/lang';
$this->loadTranslationsFrom($translationsPath, 'acl');
$this->publishes([
$translationsPath => base_path('resources/lang/vendor/acl'),
], 'translations');
], 'acl-translations');
}

/**
Expand Down
51 changes: 51 additions & 0 deletions src/Console/Commands/InstallCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Junges\ACL\Console\Commands;

use Illuminate\Console\Command;

class InstallCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'acl:install';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Install all of the Laravel ACL resources';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->comment('Publishing Laravel ACL Migrations...');
$this->callSilent('vendor:publish', ['--tag' => 'acl-migrations']);
$this->comment('Using default migrations by default.');

$this->comment('Publishing Laravel ACL configuration...');
$this->callSilent('vendor:publish', ['--tag' => 'acl-config']);

$this->info('Laravel ACL installed successfully');

$this->comment('Remember to use the UsersTrait inside your User model.');
}
}
2 changes: 2 additions & 0 deletions src/Http/Models/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
use Junges\ACL\Events\GroupSaving;
use Junges\ACL\Traits\GroupsTrait;
use Illuminate\Database\Eloquent\Model;
use Junges\ACL\Traits\ACLWildcardsTrait;

class Group extends Model
{
use GroupsTrait;
use ACLWildcardsTrait;

protected $dates = ['deleted_at'];
protected $table;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Illuminate\Support\Facades\Auth;
use Junges\ACL\Exceptions\UnauthorizedException;

class HierarchicalMiddleware
class HierarchicalPermissionsMiddleware
{
/**
* Handle an incoming request.
Expand Down
21 changes: 21 additions & 0 deletions src/Traits/ACLWildcardsTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Junges\ACL\Traits;

trait ACLWildcardsTrait
{
/**
* Check if the user has a permission, but only if this permission is directly associated to the user.
*
* @param $permissionSlug
* @return bool
*/
public function hasPermissionWithWildcards(string $permissionSlug) : bool
{
$permissionSlug = str_replace('*', '%', $permissionSlug);

return (bool) $this->permissions()
->where('slug', 'like', $permissionSlug)
->count();
}
}
6 changes: 3 additions & 3 deletions tests/CommandsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Junges\Tests;

use Junges\ACL\Test\Group;
use Junges\ACL\Test\TestCase;
use Junges\ACL\Test\Permission;
use Junges\ACL\Tests\Group;
use Junges\ACL\Tests\TestCase;
use Junges\ACL\Tests\Permission;
use Illuminate\Support\Facades\Artisan;

class CommandsTest extends TestCase
Expand Down
Loading

0 comments on commit aaa054c

Please sign in to comment.