Giter Site home page Giter Site logo

defender's Introduction

Defender


Defender is an Access Control List (ACL) Solution for Laravel 5 / 6 / 7 / 8 / 9 (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.*
^8.0 0.11.*
^9.0 0.12.*
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.

defender's People

Contributors

andreoav avatar andreportaro avatar angelorubin avatar cenoura avatar danilobenevides avatar fhferreira avatar fraterblack avatar fulviocanducci avatar joaorobertopb avatar limaa avatar lowerends avatar luizreginaldo avatar lukzgois avatar mauri870 avatar nunomazer avatar rafaelcneves avatar rodrigo-brito avatar sostheblack avatar tperrelli avatar vinicius73 avatar vluzrmos avatar willianmano avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

defender's Issues

Laravel 5.1

Há alguma especificação diferente para a versão 5.1 do Laravel?

ErrorException with tymon/jwt-auth

ErrorException in Container.php line 1065:
Illegal offset type in isset or empty

in Container.php line 1065
at HandleExceptions->handleError('2', 'Illegal offset type in isset or empty', '/var/www/ommininew/vendor/laravel/framework/src/Illuminate/Container/Container.php', '1065', array('abstract' => object(Closure))) in Container.php line 1065
at Container->getAlias(object(Closure)) in Application.php line 668
at Application->make(object(Closure)) in AbstractDefenderMiddleware.php line 55
at AbstractDefenderMiddleware->forbiddenResponse() in NeedsPermissionMiddleware.php line 47
at NeedsPermissionMiddleware->handle(object(Request), object(Closure), 'scliente.alertas')
at call_user_func_array(array(object(NeedsPermissionMiddleware), 'handle'), array(object(Request), object(Closure), 'scliente.alertas')) in /var/www/ommininew/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php line 124
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in Authenticate.php line 47
at Authenticate->handle(object(Request), object(Closure))
at call_user_func_array(array(object(Authenticate), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in GetUserFromToken.php line 37
at GetUserFromToken->handle(object(Request), object(Closure))
at call_user_func_array(array(object(GetUserFromToken), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Router.php line 710
at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 675
at Router->dispatchToRoute(object(Request)) in Router.php line 635
at Router->dispatch(object(Request)) in Kernel.php line 236
at Kernel->Illuminate\Foundation\Http{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 139
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in VerifyCsrfToken.php line 50
at VerifyCsrfToken->handle(object(Request), object(Closure))
at call_user_func_array(array(object(VerifyCsrfToken), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in ShareErrorsFromSession.php line 49
at ShareErrorsFromSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(ShareErrorsFromSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in StartSession.php line 62
at StartSession->handle(object(Request), object(Closure))
at call_user_func_array(array(object(StartSession), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
at AddQueuedCookiesToResponse->handle(object(Request), object(Closure))
at call_user_func_array(array(object(AddQueuedCookiesToResponse), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in EncryptCookies.php line 59
at EncryptCookies->handle(object(Request), object(Closure))
at call_user_func_array(array(object(EncryptCookies), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline{closure}(object(Request)) in CheckForMaintenanceMode.php line 44
at CheckForMaintenanceMode->handle(object(Request), object(Closure))
at call_user_func_array(array(object(CheckForMaintenanceMode), 'handle'), array(object(Request), object(Closure))) in Pipeline.php line 124
at Pipeline->Illuminate\Pipeline{closure}(object(Request))
at call_user_func(object(Closure), object(Request)) in Pipeline.php line 103
at Pipeline->then(object(Closure)) in Kernel.php line 122
at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 87
at Kernel->handle(object(Request)) in index.php line 55

Validação hasRole recebendo objeto ao invés de string

Bom dia galera. Eu tava implementando uns códigos aqui, tomando como base a arquitetura do defender, e me deparei com um detalhe…
no arquivo HasRole.php, nas funções hasRole e attachRole…

Enquanto o hasRole faz uma comparação da “string” role no banco, a função attachRole recebe um objeto Role como parâmetro.
O detalhe é que o attachRole utiliza a função hasRole. Porém, ao passar o parâmetro no hasRole, é passado o objeto, ao invés da string. Como resultado, vai sempre entrar no if, gerando duplicidade das roles.

Isso foi arquitetado propositalmente, ou seria um possível bug? Fiz um composer update, e na minha versão local. essa questão se encontra em:

arquivo HasRole.php
linha 51

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 ?

Find user roles

I'm attempting to find the roles that a user has.
I seem to have a little trouble doing this how would you go about this?

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.

Temporary permissions.

Add to support to give a user a temporary permission that expires after a certain time.

afterResolving not firing anymore

Hello,

i have a problem with the @shield commands in my blade files... found that this line:

$this->app->afterResolving('blade.compiler', function (BladeCompiler $bladeCompiler) {
DefenderServiceProvider.php line: 118

is not firing... and the @shield lines get printed.

i have installed the latest 5.1.* update

É 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']);

});`

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.

Support ownership.

Example situation:
A user can register customers, but it can only edit and update their own customers.

I deal with this situation very often.

Filter users by role

Hi.

Have you planned to add a method to filter users by role ?

e.g. : User::role('admin')->get() or User::role('guest')->get()

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?

blade extensions printing plain text

on laravel 5.2, tried the examples, just printing text on on the page and not hiding anything.. oh and the template_helpers option in the config is set to true, am i missing anything?.. oh and not using multi-auth

Model App\User defined on DefenderServiceProvider

Boa tarde pessoal,
Percebi que na linha 98 do arquivo src\Defender\Providers\DefenderServiceProvider.php é definido o model de usuário levando em consideração o Model default do laravel, que fica em "App\User"... Minha pergunta é a seguinte, se por ventura o nome da minha aplicação for modificado ou até mesmo o namespace do Model de usuário for alterado, como devo proceder neste caso?

attachPermission and detachPermission

Using 'attachPermission' defender inserts a new register at table permission_role with field 'value' 0.
When 'detachPermission' is used, defender deletes the row for permission passed.

attachPermission should insert(if not exist) the register and set field 'value' = 1.
and for detachPermission should not delete the register, only set field 'value' to 0.

This way the field value will be used to determinate if have or not the permission.

Change publishing path for database migrations

Migrations should be pushed right to migrations folder, even if user has its own path for it.
To fix this, change ServiceProvider to:

    /**
     * Publish migration file.
     */
    private function publishMigrations()
    {
        $this->publishes([__DIR__.'/../../resources/migrations/' => database_path('database/migrations')], 'migrations');
    }

(I'm busy to pull a request sorry :) )

[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: Defender Resource

Protect route or group, better for route::resource, based on its name and matching with user permissions.

Role and Permission should be created based on config file

The registerRepositoryInterfaces() function in DefenderServiceProvider class is creating the Role and Permission singletons based on default package classes. This does not allows the repository pattern to provide expected behavior.

I'm using MongoDB and need to extend my models from a different class than default Eloquent\Model. Below are the key parts of this logic:

protected function registerRepositoryInterfaces()
{
    $this->app->singleton('defender.role', function ($app) {
        return new EloquentRoleRepository($app, new Role());
    });

    ...

    $this->app->singleton('defender.permission', function ($app) {
        return new EloquentPermissionRepository($app, new Permission());
    });

    ...

    $this->app->singleton('defender.user', function ($app) {
        $userModel = $app['config']->get('defender.user_model');

        return new EloquentUserRepository($app, $app->make($userModel));
    });

    ...
}

The $userModel creation follows the correct behavior, so should be the Role and Permission, but changing the logic throws the error:

 Type error: Argument 2 passed to Artesaos\Defender\Repositories\Eloquent\EloquentRoleRepository::__construct() must be an instance of Artesaos\Defender\Role

So, I believe one strategy would be to refactor the Role and Permission classes into traits to be used by necessary classes of the app or by default flat classes of the package. This, of course, needs to be better studied. Or a simpler aproach by changing the signature of the __construct functions of EloquentRoleRepository and EloquentPermissionRepository classes.

laravel 5.1

[RuntimeException]
Error Output: PHP Fatal error: Class 'Artesaos\Defender\Providers\Defender
ServiceProvider' not found in E:\EasyPHP-DevServer-14.1VC11\data\localweb\g
amenivora\vendor\laravel\framework\src\Illuminate\Foundation\ProviderReposi
tory.php on line 146

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

Owners?

Is it possible to use this to check if the current user is the owner of a resource? I am wanting to basically give the owner of a post the ability to edit it, while the moderators and admins implicitly have that ability through the plugin middleware.

I.e. an admin, a moderator, and the owner of a post have the ability to edit it.

Add support to Laravel 5.2 Multi Auth

With the release of Laravel 5.2 and its new Auth configuration, we must find a way to support both Laravel 5.1 LTS and Laravel 5.2 configuration files.

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

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

Middleware em controllers

Como usar o middleware "needsPermission" no controller para proteger métodos ao invés de usar nas routes? preciso especificar quais permissões necessárias determinados métodos precisam no controller, para os casos de rotas RESTful

Config cache not possible due to closure in config

I noticed that it is not possible to use php artisan config:cache when using Defender. The reason for this is the following lines in the config file, where a closure is used:

/*
* Forbidden callback
*/
'forbidden_callback' => function () {
    throw new \Artesaos\Defender\Exceptions\ForbiddenException();
},

It seems to be bad practice to use closures in a config file. Is there a way to avoid using a closure here? I found a similar issue here: https://github.com/lucadegasperi/oauth2-server-laravel/issues/323.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.