Roles & Permissions for Laravel 8 / 7 / 6 / 5

Overview

Defender


Defender is an Access Control List (ACL) Solution for Laravel 5 / 6 / 7 (single auth). (Not compatible with multi-auth)
With security and usability in mind, this project aims to provide you a safe way to control your application access without losing the fun of coding.

Current Build Status

Build Status Code Climate StyleCI

Statistics

Latest Stable Version Latest Unstable Version License Total Downloads Monthly Downloads Daily Downloads

Contribution welcome

Defender is looking for maintainers and contributors.

Installation

1. Dependency

Using composer, execute the following command to automatically update your composer.json, using the corresponding package version:

Version Constraint Package Version
>= 5.0.* && <= 5.3.* 0.6.*
~5.4, ~5.5 0.7.*
>= 5.6.* 0.8.*
~6.0 0.9.*
~7.0 0.10.*
composer require artesaos/defender

or manually update your composer.json file

{
    "require": {
        "artesaos/defender": "~0.10.0"
    }
}

2. Provider

If you are using Laravel >= 5.5 skip this section since our package support auto-discovery.

You need to update your application configuration in order to register the package, so it can be loaded by Laravel. Just update your config/app.php file adding the following code at the end of your 'providers' section:

// file START ommited
    'providers' => [
        // other providers ommited
        \Artesaos\Defender\Providers\DefenderServiceProvider::class,
    ],
// file END ommited

3. User Class

On your User class, add the trait Artesaos\Defender\Traits\HasDefender to enable the creation of permissions and roles:

<?php

namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Artesaos\Defender\Traits\HasDefender;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
    use Authenticatable, CanResetPassword, HasDefender;
...

If you are using laravel 5.2+, there is a small difference:

<?php

namespace App;

use Artesaos\Defender\Traits\HasDefender;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasDefender;
...

4. Publishing configuration file and migrations

To publish the default configuration file and database migrations, execute the following command:

php artisan vendor:publish

Execute the migrations, so that the tables on you database are created:

php artisan migrate

You can also publish only the configuration file or the migrations:

php artisan vendor:publish --tag=config

Or

php artisan vendor:publish --tag=migrations

If you already published defender files, but for some reason you want to override previous published files, add the --force flag.

5. Facade (optional)

In order to use the Defender facade, you need to register it on the config/app.php file, you can do that the following way:

// config.php file
// file START ommited
    'aliases' => [
        // other Facades ommited
        'Defender' => \Artesaos\Defender\Facades\Defender::class,
    ],
// file END ommited

6. Defender Middlewares (optional)

If you have to control the access Defender provides middlewares to protect your routes. If you have to control the access through the Laravel routes, Defender has some built-in middlewares for the trivial tasks. To use them, just put it in your app/Http/Kernel.php file.

protected $routeMiddleware = [
    'auth'            => \App\Http\Middleware\Authenticate::class,
    'auth.basic'      => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest'           => \App\Http\Middleware\RedirectIfAuthenticated::class,

    // Access control using permissions
    'needsPermission' => \Artesaos\Defender\Middlewares\NeedsPermissionMiddleware::class,

    // Simpler access control, uses only the groups
    'needsRole' => \Artesaos\Defender\Middlewares\NeedsRoleMiddleware::class
];

You'll see how to use the middlewares below.

6.1 - Create your own middleware

If the built-in middlewares doesn't fit your needs, you can make your own by using Defender's API to control the access.

Usage

Defender handles only access control. The authentication is still made by Laravel's Auth.

Note: If you are using a different model for your users or has changed the namespace, please update the user_model key on your defender config file

Creating roles and permissions

With commands

You can use these commands to create the roles and permissions for you application.

php artisan defender:make:role admin  # creates the role admin
php artisan defender:make:role admin --user=1 # creates the role admin and attaches this role to the user where id=1
php artisan defender:make:permission users.index "List all the users" # creates the permission
php artisan defender:make:permission users.create "Create user" --user=1 # creates the permission and attaches it to user where id=1
php artisan defender:make:permission users.destroy "Delete user" --role=admin # creates the permission and attaches it to the role admin

With the seeder or artisan tinker

You can also use the Defender's API. You can create a Laravel Seeder or use php artisan tinker.

use App\User;

$roleAdmin = Defender::createRole('admin');

// The first parameter is the permission name
// The second is the "friendly" version of the name. (usually for you to show it in your application).
$permission =  Defender::createPermission('user.create', 'Create Users');

// You can assign permission directly to a user.
$user = User::find(1);
$user->attachPermission($permission);

// or you can add the user to a group and that group has the power to rule create users.
$roleAdmin->attachPermission($permission);

// Now this user is in the Administrators group.
$user->attachRole($roleAdmin);

Using the middleware

To protect your routes, you can use the built-in middlewares.

Defender requires Laravel's Auth, so, use the auth middleware before the Defender's middleware that you intend to use.

Checking Permissions: needsPermissionMiddleware

Route::get('foo', ['middleware' => ['auth', 'needsPermission'], 'shield' => 'user.create', function()
{
    return 'Yes I can!';
}]);

If you're using Laravel 5.1+ it's possible to use Middleware Parameters.

Route::get('foo', ['middleware' => ['auth', 'needsPermission:user.index'], function() {
    return 'Yes I can!';
}]);

With this syntax it's also possible to use the middleware within your controllers.

$this->middleware('needsPermission:user.index');

You can pass an array of permissions to check on.

Route::get('foo', ['middleware' => ['auth', 'needsPermission'], 'shield' => ['user.index', 'user.create'], function()
{
    return 'Yes I can!';
}]);

When using middleware parameters, use a | to separate multiple permissions.

Route::get('foo', ['middleware' => ['auth', 'needsPermission:user.index|user.create'], function() {
    return 'Yes I can!';
}]);

Or within controllers:

$this->middleware('needsPermission:user.index|user.create');

When you pass an array of permissions, the route will be fired only if the user has all the permissions. However, if you want to allow the access to the route when the user has at least one of the permissions, just add 'any' => true.

Route::get('foo', ['middleware' => ['auth', 'needsPermission'], 'shield' => ['user.index', 'user.create'], 'any' => true, function()
{
    return 'Yes I can!';
}]);

Or, with middleware parameters, pass it as the 2nd parameter

Route::get('foo', ['middleware' => ['auth', 'needsPermission:user.index|user.create,true'], function() {
    return 'Yes I can!';
}]);

Or within controllers:

$this->middleware('needsPermission:user.index|user.create,true');

Checking Roles: needsRoleMiddleware

This is similar to the previous middleware, but only the roles are checked, it means that it doesn't check the permissions.

Route::get('foo', ['middleware' => ['auth', 'needsRole'], 'is' => 'admin', function()
{
    return 'Yes I am!';
}]);

If you're using Laravel 5.1 it's possible to use Middleware Parameters.

Route::get('foo', ['middleware' => ['auth', 'needsRole:admin'], function() {
    return 'Yes I am!';
}]);

With this syntax it's also possible to use the middleware within your controllers.

$this->middleware('needsRole:admin');

You can pass an array of permissions to check on.

Route::get('foo', ['middleware' => ['auth', 'needsRole'], 'shield' => ['admin', 'member'], function()
{
    return 'Yes I am!';
}]);

When using middleware parameters, use a | to separate multiple roles.

Route::get('foo', ['middleware' => ['auth', 'needsRole:admin|editor'], function() {
    return 'Yes I am!';
}]);

Or within controllers:

$this->middleware('needsRole:admin|editor');

When you pass an array of permissions, the route will be fired only if the user has all the permissions. However, if you want to allow the access to the route when the user has at least one of the permissions, just add 'any' => true.

Route::get('foo', ['middleware' => ['auth', 'needsRole'], 'is' => ['admin', 'member'], 'any' => true, function()
{
    return 'Yes I am!';
}]);

Or, with middleware parameters, pass it as the 2nd parameter

Route::get('foo', ['middleware' => ['auth', 'needsRole:admin|editor,true'], function() {
    return 'Yes I am!';
}]);

Or within controllers:

$this->middleware('needsRole:admin|editor,true');

Using in Views

Laravel's Blade extension for using Defender.

@shield

@shield('user.index')
    shows your protected stuff
@endshield
@shield('user.index')
    shows your protected stuff
@else
    shows the data for those who doesn't have the user.index permission
@endshield

You can also use wildcard(*)

@shield('user.*')
    shows your protected stuff
@else
    shows the data for those who doesn't have the any permission with 'user' prefix
@endshield

@is

@is('admin')
    Shows data for the logged user and that belongs to the admin role
@endis
@is('admin')
    Shows data for the logged user and that belongs to the admin role
@else
    shows the data for those who doesn't have the admin permission
@endis
@is(['role1', 'role2'])
    Shows data for the logged user and that belongs to the admin role
@else
    shows the data for those who doesn't have the admin permission
@endis

Using javascript helper

The stand provides helper for when you need to interact with the user permissions on the front-end.

echo Defender::javascript()->render();
// or
echo app('defender')->javascript()->render();
// or
echo app('defender.javascript')->render();

This helper injects a javascript code with all permissions and roles of the current user.


Using the Facade

With the Defender's Facade you can access the API and use it at any part of your application.


Defender::hasPermission($permission):

Check if the logged user has the $permission.


Defender::canDo($permission):

Check if the logged user has the $permission. If the role superuser returns true


Defender::roleHasPermission($permission):

Check if the logged user has the $permission checking only the role permissions.


Defender::hasRole($roleName):

Check if the logged user belongs to the role $roleName.


Defender::roleExists($roleName):

Check if the role $roleName exists in the database.


Defender::permissionExists($permissionName):

Check if the permission $permissionName exists in the database.


Defender::findRole($roleName):

Find the role in the database by the name $roleName.


Defender::findRoleById($roleId):

Find the role in the database by the role ID roleId.


Defender::findPermission($permissionName):

Find the permission in the database by the name $permissionName.


Defender::findPermissionById($permissionId):

Find the permission in the database by the ID $permissionId.


Defender::createRole($roleName):

Create a new role in the database.


Defender::createPermission($permissionName):

Create a new permission in the database.

Defender::is($roleName):

Check whether the current user belongs to the role.

Defender::javascript()->render():

Returns a javascript script with a list of all roles and permissions of the current user. The variable name can be modified.


Using the trait

To add the Defender's features, you need to add the trait HasDefender in you User model (usually App\User).

<?php namespace App;

// Declaration of other omitted namespaces
use Artesaos\Defender\Traits\HasDefender;

class User extends Model implements AuthenticatableContract, CanResetPasswordContract {

    use Authenticatable, CanResetPassword, HasDefender;

    // Rest of the class
}

This trait, beyond configuring the relationships, will add the following methods to your object App\User:

public function hasPermission($permission):

This method checks if the logged user has the permission $permission

In Defender, there are 2 kind of permissions: User permissions and Role permissions. By default, the permissions that the user inherits, are permissions of the roles that it belongs to. However, always that a user pemission is set, it will take precedence of role permission.

public function foo(Authenticable $user)
{
    if ($user->hasPermission('user.create'));
}

public function roleHasPermission($permission):

This method works the same way the previous one, the only diference is that the user permissions are not considered, however, only the role's permissions that the user belongs are used to check the access.

public function foo(Authenticable $user)
{
    if ($user->roleHasPermission('user.create');
}

public function attachRole($role):

Attach the user to the role $role. The $role variable might be an object of the type Artesaos\Defender\Role or an array containing the ids of the roles.

public function foo(Authenticable $user)
{
    $role = Defender::findRole('admin'); // Returns an Artesao\Defender\Role
    $user->attachRole($role);

    // or

    $roles = [1, 2, 3]; // Using an array of ids
    $user->attachRole($roles);
}

public function detachRole($role):

Detach the role $role from the user (inverse to attachRole()).

public function foo(Authenticable $user)
{
    $role = Defender::findRole('admin'); // Returns an Artesao\Defender\Role
    $user->detachRole($role);

    // ou

    $roles = [1, 2, 3]; // Using an array of ids
    $user->detachRole($roles);
}

public function syncRoles(array $roles = array()):

This is like the attachRole() method, but only the roles in the array $roles will be on the relationship after the method runs. $roles is an array of ids for the needed roles.

public function foo(Authenticable $user)
{
    $roles = [1, 2, 3]; // Using an array of ids

    $user->syncRoles($roles);
}

public function attachPermission($permission, array $options = array()):

Attach the user to the permission $permission. The $permission variable is an instance of the Artesaos\Defender\Permission class.

public function foo(Authenticable $user)
{
    $permission = Defender::findPermission('user.create');

    $user->attachPermission($permission, [
        'value' => true // true = has the permission, false = doesn't have the permission,
    ]);
}

public function detachPermission($permission):

Remove the permission $permission from the user. The $permission variable might be an instance of the Artesaos\Defender\Permission class or an array of ids with the ids of the permissions to be removed.

public function foo(Authenticable $user)
{
    $permission = Defender::findPermission('user.create');
    $user->detachPermission($permission);

    // or

    $permissions = [1, 3];
    $user->detachPermission($permissions);
}

public function syncPermissions(array $permissions):

This is like the method syncRoles, but only the roles in the array $permissions be on the relationship after the method runs.

public function foo(Authenticable $user)
{
    $permissions = [
        1 => ['value' => false],
        2 => ['value' => true,
        3 => ['value' => true]
    ];

    $user->syncPermissions($permissions);
}

public function revokePermissions():

Remove all the user permissions.

public function foo(Authenticable $user)
{
    $user->revokePermissions();
}

public function revokeExpiredPermissions():

Remove all the temporary expired pemissions from the user. More about temporary permissions below.

public function foo(Authenticable $user)
{
    $user->revokeExpiredPermissions();
}

Temporary permissions

One of Defender's coolest features is to add temporary permissions to a group or an user.

For example

The user John belongs to the role 'admins', however I want to temporaly remove the John's permission to create new users

In this case we need to attach an permission with the value equal to false, explicitly prohibiting the user to perform that action. You must add this permission, with the false value, since by default, the user permissions are inherited of the permissions of their roles. When you assign a user permission, this will always take precedence.

For instance. Below we revoke the permission user.create for the user during 7 days.

public function foo()
{
    $userX = App\User::find(3);
    $permission = Defender::findPermission('user.create');


    $userX->attachPermission($permission, [
        'value' => false, // false means that he will not have the permission,
        'expires' => \Carbon\Carbon::now()->addDays(7) // Set the permission's expiration date
    ]);

}

After 7 days, the user will take the permission again.


Allow that a user can perform some action by a period of time.

To allow that a user have temporary access to perform a given action, just set the expires key. The value key will be true by default.

public function foo()
{
    $user = App\User::find(1);
    $permission = Defender::findPermission('user.create');

    $user->attachPermission($permission, [
        'expires' => \Carbon\Carbon::now()->addDays(7)
    ];
}

It's also possible to extend an existing temporary: Just use the $user->extendPermission($permissionName, array $options) method.

Using custom Role and Permission models

To use your own classes for Role and Permission models, first set the role_model and permission_model keys at defender.php config.

Following are two examples of how Role and Permission models must be implemented for MongoDB using jenssegers/laravel-mongodb driver:

    <?php
    
    // Role model
    
    namespace App;
    
    use Jenssegers\Mongodb\Eloquent\Model;
    use Artesaos\Defender\Traits\Models\Role;
    use Artesaos\Defender\Contracts\Role as RoleInterface;
    
    /**
     * Class Role.
     */
    class Role extends Model implements RoleInterface {
        use Role;
    }
    <?php
    
    // Permission model
    
    namespace App;
    
    use Jenssegers\Mongodb\Eloquent\Model;
    use Artesaos\Defender\Traits\Models\Permission;
    use Artesaos\Defender\Contracts\Permission as PermissionInterface;
    
    /**
     * Class Permission.
     */
    class Permission extends Model implements PermissionInterface
    {
        use Permission;    
    }

You must use the correct traits and each class has to implemet the corresponding interface contract.

Comments
  • Gerar migrações com data atual (stub)

    Gerar migrações com data atual (stub)

    Migrations estão sendo geradas com datas de 2015.

    Em qualquer aplicação criada após a data das migrations do pacote, ocorrerá conflito (por exemplo, as migrations criam chaves estrangeiras utilizando a tabela user - mesmo em pacotes cuja primeira migração ainda não foi efetuada).

    Seria possível utilizar um stub para criação dos arquivos de migração de acordo com a data?

    opened by andreportaro 14
  • Replace can method and blade extensions

    Replace can method and blade extensions

    With the introduction of Laravel offical ACL layer we need a way to remove the conflict with the official can @can and endcan.

    Since this is a breaking change, we'll need a major release.

    help wanted high priority proposal need feedback 
    opened by andreoav 12
  • Upgrade defender to laravel 5.4

    Upgrade defender to laravel 5.4

    This MR intents to upgrade the defender package to laravel 5.4.

    Unfortunately are some breaking changes on 5.4 which obliges us to introduce a new version incompatible with previous framework versions.

    Laravel <= 5.3 should use 0.6.* and 5.4 the new 0.7 that will be introduced as soon as the tests pass

    The tests are not passing at this point so any help with the remaining errors will be appreciated

    opened by mauri870 11
  • [Proposal] Project rename

    [Proposal] Project rename

    Given that already exists a project for Laravel with the same name and similar goal, we new ideas to rename the project.

    • Guardian (keep the same)
    • Unbroken (1)
    • Keeper
    • Safeguard
    • Supervisor
    • Defender (4)
    • Protector
    • ~~Muscle~~
    • ~~Savior~~
    • Bulwark
    • Tutor (1)
    • Patron (1)
    • Vigilant (1)
    • Shield (1)
    • Paladin (1)

    Please, comment with your suggestion.

    proposal need feedback 
    opened by andreoav 11
  • erro após login

    erro após login

    Bom dia,

    Estou tendo um problema que nao estou encontrando o motivo do mesmo.

    quando eu executo o login ele me retorna o seguinte erro:

    Whoops, looks like something went wrong. BadMethodCallException in Builder.php line 2161: Call to undefined method Illuminate\Database\Query\Builder::hasPermission()

    Tem alguma ideia ?

    opened by daniellopes81 8
  • Problema com as rotas

    Problema com as rotas

    Eu criei as seguintes regras: superadmin, admin, user.

    Coloquei 1 usuário com a regra de superadmin no usuário e mesmo assim, ao usar a rota desta forma:

    Route::get('foo', ['middleware' => ['auth', 'needsRole'], 'can' => ['admin', 'patient'], function()
    {
        return 'Yes I am!';
    }]);
    

    Recebo o retorn

    Desta forma:

    Route::get('foo', ['middleware' => ['auth', 'needsRole:superadmin'], function() {
        return 'Yes I am!';
    }]);
    

    Só funciona se eu passar apenas uma regra se eu adicionar um |admin, nem o primeiro nem as outras funcionam.

    bug 
    opened by raphaeljorge 8
  • É possível usar needsRole em Route Groups

    É possível usar needsRole em Route Groups

    Tentei fazer o seguinte, mas não dá erro, apenas uma tela em branco. Não aparece nada nos logs para eu poder ajudar. O que eu estou fazendo errado?

    `Route::group([ 'prefix' => 'admin', 'middleware' => ['auth', 'needsRole'], 'is' => 'admin' ], function() {

    Route::get('/', ['as' => 'admin.painel', 'uses' => 'PainelController@index']);
    

    });`

    opened by larbous 8
  • not compatible with laravel 5.4.8

    not compatible with laravel 5.4.8

      Declaration of Artesaos\Defender\Traits\HasDefender::newPivot() should be compatible with Illuminate\Database\Eloquent\Model::new
      Pivot(Illuminate\Database\Eloquent\Model $parent, array $attributes, $table, $exists, $using = NULL)
    

    need to add $using to satisfy a contract:

    • Artesaos\Defender\Traits\Models\Permission@newPivot
    • Artesaos\Defender\Traits\Models\Role@newPivot
    • Artesaos\Defender\Traits\Permissions\RoleHasPermissions@newPivot
        /**
         * @param Model  $parent
         * @param array  $attributes
         * @param string $table
         * @param bool   $exists
         * @param string|null   $using
         *
         * @return PermissionRolePivot|\Illuminate\Database\Eloquent\Relations\Pivot
         */
        public function newPivot(Model $parent, array $attributes, $table, $exists, $using = null)
        {
        
            ...
    
            return parent::newPivot($parent, $attributes, $table, $exists, $using);
        }
    
    opened by Nightly18 7
  • Parse error: syntax error

    Parse error: syntax error

    PHP: v7.0.10 Laravel: v5.3.6

    source:

    @shield('test')
        ...
    @endshield
    

    error:

    Parse error: syntax error, unexpected ''test'' (T_CONSTANT_ENCAPSED_STRING) (View: /home/jaonoctus/htdocs/laravel/resources/views/home.blade.php)
    

    log:

    in 34a69314a1628d6b7321a2436770cbd95c4e44bf.php line 11
    at CompilerEngine->handleViewException(object(FatalThrowableError), '1') in PhpEngine.php line 46
    at PhpEngine->evaluatePath('/home/jaonoctus/htdocs/laravel/storage/framework/views/34a69314a1628d6b7321a2436770cbd95c4e44bf.php', array('__env' => object(Factory), 'app' => object(Application), 'errors' => object(ViewErrorBag))) in CompilerEngine.php line 59
    at CompilerEngine->get('/home/jaonoctus/htdocs/laravel/resources/views/home.blade.php', array('__env' => object(Factory), 'app' => object(Application), 'errors' => object(ViewErrorBag))) in View.php line 149
    at View->getContents() in View.php line 120
    at View->renderContents() in View.php line 85
    at View->render() in Response.php line 45
    at Response->setContent(object(View)) in Response.php line 201
    at Response->__construct(object(View)) in Router.php line 1042
    at Router->prepareResponse(object(Request), object(View)) in Router.php line 642
    at Router->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in SubstituteBindings.php line 41
    at SubstituteBindings->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Authenticate.php line 43
    at Authenticate->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in VerifyCsrfToken.php line 64
    at VerifyCsrfToken->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in ShareErrorsFromSession.php line 49
    at ShareErrorsFromSession->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in StartSession.php line 64
    at StartSession->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
    at AddQueuedCookiesToResponse->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in EncryptCookies.php line 59
    at EncryptCookies->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 104
    at Pipeline->then(object(Closure)) in Router.php line 644
    at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 618
    at Router->dispatchToRoute(object(Request)) in Router.php line 596
    at Router->dispatch(object(Request)) in Kernel.php line 267
    at Kernel->Illuminate\Foundation\Http\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 46
    at CheckForMaintenanceMode->handle(object(Request), object(Closure)) in Pipeline.php line 137
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 104
    at Pipeline->then(object(Closure)) in Kernel.php line 149
    at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 116
    at Kernel->handle(object(Request)) in index.php line 53
    at require_once('/home/jaonoctus/htdocs/laravel/public/index.php') in server.php line 21
    
    bug high priority 
    opened by jaonoctus 5
  • Interface 'Artesaos\Defender\Contracts\User' not found

    Interface 'Artesaos\Defender\Contracts\User' not found

    Having problem while upgrading to 0.4.1 version. The Documentation says to implement the interface Artesaos\Defender\Contracts\User on Users's class but there's no User.php file located in Contracts dir.

    I have this error on console. Interface 'Artesaos\Defender\Contracts\User' not found

    opened by wemersonjanuario 5
  • Commands!

    Commands!

    [English]

    I've tested the commands, that is very cool!

    I would like to propose some improvements:

    1 - One option to attach permission to a user, even if that permission already exists. 2 - A command to list permissions of the user like defender:permissions user 3 - A command to list roles of the user like defender:roles user 4 - Command to detach permissions for users 5 - Command to remove permissions 5 - Command to remove roles 6 - Command to add/remove temporary permissions

    [Português]

    Testei os comandos, muito show!

    Gostaria de sugerir melhorias:

    1 - Ter opção de poder adicionar um usuário a uma permissão existente, sem precisar criar; 2 - Ter como lista permissões do usuário algo como artisan defender:permissions user 3 - Ter como lista roles do usuário algo como artisan defender:roles user 4 - Poder remover permissões do usuário 5 - Poder apagar permissoes 6 - adicionar/remover permissões temporaria 7 - tudo que falei de permissões também para roles

    feature medium priority 
    opened by emtudo 5
  • how to have multiples permissions on blade @shield directive

    how to have multiples permissions on blade @shield directive

    I was needing to have multiples permissions in @shield but from what i readed its not possible. With wildcard(*) dont work because the name is not standardized.

    Example of usage:

    @shield(['can-do-that', 'that-can-here'])
        // code...
    @endshield
    

    The alternative thats i founded is use vanilla php.

    <?php if (app('defender')->canDo('can-do-that') || app('defender')->canDo('that-can-here')) : ?>
        // code...
    <?php endif; ?>
    

    Thinks a good ideia do implement that?

    opened by MuriloChianfa 0
  • Bump guzzlehttp/psr7 from 2.1.0 to 2.2.1

    Bump guzzlehttp/psr7 from 2.1.0 to 2.2.1

    Bumps guzzlehttp/psr7 from 2.1.0 to 2.2.1.

    Release notes

    Sourced from guzzlehttp/psr7's releases.

    2.2.1

    See change log for changes.

    2.2.0

    See change log for changes.

    2.1.2

    See change log for changes.

    2.1.1

    See change log for changes.

    Changelog

    Sourced from guzzlehttp/psr7's changelog.

    2.2.1 - 2022-03-20

    Fixed

    • Correct header value validation

    2.2.0 - 2022-03-20

    Added

    • A more compressive list of mime types
    • Add JsonSerializable to Uri
    • Missing return types

    Fixed

    • Bug MultipartStream no uri metadata
    • Bug MultipartStream with filename for data:// streams
    • Fixed new line handling in MultipartStream
    • Reduced RAM usage when copying streams
    • Updated parsing in Header::normalize()

    2.1.1 - 2022-03-20

    Fixed

    • Validate header values properly
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Attaching permission to role create the  correct db records but not working in the routes

    Attaching permission to role create the correct db records but not working in the routes

    Firts of all i create roles and permissions:

    $role = Defender::createRole('superadmin');
    $roleSuperadmin = Defender::findRole('superadmin');
    $permission = Defender::createPermission('user.create', 'Create Users');
    $roleSuperadmin->attachPermission($permission);
    //... And so on with all the roles and permissions
    

    Then i set the routes middlewares:

    Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
        Route::group(['prefix' => 'user', 'as' => 'user.'], function () {
            Route::group(['middleware' => ['auth']], function () {
                Route::get('/index', [UserController::class, 'index'])->name('index')->middleware(['auth', 'needsPermission:user.index']);
                Route::get('/create', [UserController::class, 'create'])->name('create')->middleware(['auth', 'needsPermission: user.create']);
                Route::post('/store', [UserController::class, 'store'])->name('store')->middleware(['auth', 'needsPermission: user.store']);
                Route::get('/destroy/{id}', [UserController::class, 'destroy'])->name('destroy')->middleware(['auth', 'needsPermission: user.destroy']);
                Route::get('/edit/{id}', [UserController::class, 'edit'])->name('edit')->middleware(['auth', 'needsPermission: user.edit']);
                Route::post('/update/{id}', [UserController::class, 'update'])->name('update')->middleware(['auth', 'needsPermission: user.update']);
            });
        });
    

    I check the database and all the records about the roles and the permissions seems to be created in the right way. When i go to one of the routes i get:

    Artesaos\Defender\Exceptions\ForbiddenException
    You don't have permission to access this resource 
    
    opened by lucamarchiori 0
Releases(v0.12.0)
  • v0.12.0(Mar 14, 2022)

  • v0.11.0(Mar 14, 2022)

  • v0.10.0(Jul 14, 2020)

  • v0.8.3(Aug 31, 2018)

  • v0.8.2(Jun 11, 2018)

  • v0.8.1(Jun 1, 2018)

  • v0.8.0(May 29, 2018)

  • 0.7(Oct 13, 2017)

    We are tagging this release to mark the official support for Laravel 5.5 and package auto-discovery, as well as maintaining compatibility with the version 5.4 of the framework.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.2(Sep 11, 2016)

  • 0.6(Sep 11, 2016)

  • v0.4.6(Sep 11, 2015)

    This release has a few breaking changes.

    1. can method renamed

    Since Laravel 5.1.11 introduced a ACL feature that uses the same method name, our can method has been replaced with canDo or hasPermission method.

    Our blade helper has been replaced with the @shield and @endshield helpers as well the needsPermissionMiddleware. The syntax for both cases remains the same.

    2. Defender Commands

    This version introduces a new feature called Defender Commands. Just run php artisan to take a look at all available commands.

    3. New forbidden_callback handler.

    This version replaces the forbidden_callback within defender.php configuration. With the new syntax it's possible cache the defender configuration file.

    By default, Denfender comes with a ForbiddenHandler that throws the same exception from previous versions. To add a custom handler, create a class within your application namespace that implements our Artesaos\Defender\Contracts\ForbiddenHandlercontract. This interface has only one method called handle that must be implemented.

    4. Locked version only Laravel 5.1

    Fixtures

    #78

    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Jul 1, 2015)

    Fix

    • Fix #45 Duplicated querys when using @can multiple times in blade template.
    • Improved #41 Blade @is() support for multiple roles

    Modifications

    • Removed support for laravel 5.0
    • New traits structure.

    New features

    • Javascript helper
    • More compatible with packages like MultiAuth
    • superuser role
    Source code(tar.gz)
    Source code(zip)
  • v0.2.16(Jun 26, 2015)

  • v0.2.14(Jun 11, 2015)

  • v0.2.12(May 14, 2015)

  • v0.2.11(May 14, 2015)

Owner
Artesãos
Artesãos
Roles & Permissions for Laravel 8 / 7 / 6 / 5

Defender Defender is an Access Control List (ACL) Solution for Laravel 5 / 6 / 7 (single auth). (Not compatible with multi-auth) With security and usa

Artesãos 437 Dec 22, 2022
Laravel Users (Roles & Permissions, Devices, Password Hashing, Password History).

LARAVEL USERS Roles & Permissions Devices Password Hashing Password History Documentation You can find the detailed documentation here in Laravel User

Pharaonic 8 Dec 14, 2022
Powerful package for handling roles and permissions in Laravel 5

Roles And Permissions For Laravel 5 Powerful package for handling roles and permissions in Laravel 5 (5.1 and also 5.0). Installation Composer Service

Roman Bičan 1.2k Dec 17, 2022
Laravel Roles and Permissions

Introduction to Laravel Roles and Permission App Starter Kit Roles and sanctions are a paramount part of many web applications. In project, we have op

Brian Kiprono Koech 1 Nov 1, 2021
A Powerful package for handling roles and permissions in Laravel with GUI.

Laravel Roles A Powerful package for handling roles and permissions in Laravel. Supports Laravel 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 6.0, 7.0, and 8.0+. Tab

Jeremy Kenedy 827 Jan 1, 2023
This is a lightweight package that allows you assign roles and permissions to any Laravel model, or on a pivot table (many to many relationship).

Simple Laravel roles and permissions Introduction This package allows you to assign roles and permissions to any laravel model, or on a pivot table (m

null 52 Nov 10, 2022
Tech-Admin is Laravel + Bootstrap Admin Panel With User Management And Access Control based on Roles and Permissions.

Tech-Admin | Laravel 8 + Bootstrap 4 Tech-Admin is Admin Panel With Preset of Roles, Permissions, ACL, User Management, Profile Management. Features M

TechTool India 39 Dec 23, 2022
Associate users with roles and permissions

Associate users with permissions and roles Sponsor If you want to quickly add authentication and authorization to Laravel projects, feel free to check

Spatie 10.9k Jan 3, 2023
Eloquent roles and abilities.

Bouncer Bouncer is an elegant, framework-agnostic approach to managing roles and abilities for any app using Eloquent models. Table of Contents Click

Joseph Silber 3.2k Jan 5, 2023
Proyecto para aprender a utilizar privilegios (roles y permisos) con CRUDBooster

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Informática DP 3 May 9, 2022
Role-based Permissions for Laravel 5

ENTRUST (Laravel 5 Package) Entrust is a succinct and flexible way to add Role-based Permissions to Laravel 5. If you are looking for the Laravel 4 ve

Zizaco 6.1k Jan 5, 2023
Light-weight role-based permissions system for Laravel 6+ built in Auth system.

Kodeine/Laravel-ACL Laravel ACL adds role based permissions to built in Auth System of Laravel 8.0+. ACL middleware protects routes and even crud cont

Kodeine 781 Dec 15, 2022
PermissionsMakr is a Laravel package that will help any developer to easily manage the system's users permissions

PermissionsMakr is a Laravel package that will help any developer to easily manage the system's users permissions

Alvarium Digital 3 Nov 30, 2021
Manage authorization with granular role-based permissions in your Laravel Apps.

Governor For Laravel Manage authorization with granular role-based permissions in your Laravel apps. Goal Provide a simple method of managing ACL in a

GeneaLabs, LLC 149 Dec 23, 2022
This package helps you to associate users with permissions and permission groups with laravel framework

Laravel ACL This package allows you to manage user permissions and groups in a database, and is compatible with Laravel v5.8 or higher. Please check t

Mateus Junges 537 Dec 28, 2022
Laravel mongodb permissions

Laravel mongodb permissions

null 4 May 10, 2022
Laravel fortify ve spatie permissions eklentileri üzerine geliştirilmiş kullanıma hazır panel

Herkobi Panel Laravel ile yeni bir projeye başlayacak kişiler için Laravel Fortify üzerine geliştirdiğimiz arayüze (https://github.com/bulentsakarya/l

Herkobi 10 Jun 15, 2023
A Laravel 5 package for OAuth Social Login/Register implementation using Laravel socialite and (optionally) AdminLTE Laravel package

laravel-social A Laravel 5 package for OAuth Social Login/Register implementation using Laravel socialite and (optionally) AdminLTE Laravel package. I

Sergi Tur Badenas 42 Nov 29, 2022
:octocat: Socialite is an OAuth2 Authentication tool. It is inspired by laravel/socialite, you can easily use it without Laravel.

Socialite Socialite is an OAuth2 Authentication tool. It is inspired by laravel/socialite, You can easily use it in any PHP project. 中文文档 This tool no

安正超 1.2k Dec 22, 2022