stevebauman/authorization

Native Laravel Authorization.

v1.3.3 2016-02-26 18:42 UTC

README

Build Status Scrutinizer Code Quality Total Downloads Latest Stable Version License

Attention

This package has been moved to https://github.com/larapacks/authorization.

This GitHub repository will be deleted in 3 months from this commit (though composer availability will still exist and will not be removed).

Description

An easy, native role / permission management system for Laravel.

Authorization automatically adds your database permissions and roles to the Illuminate\Auth\Access\Gate, this means that you can utilize native laravel policies and methods for authorization. This also means that you're not walled into using this package.

Installation

Insert Authorization in your composer.json file:

"stevebauman/authorization": "1.3.*"

Then run composer update.

Insert the service provider in your config/app.php file:

Stevebauman\Authorization\AuthorizationServiceProvider::class,

Once that's complete, publish the migrations using:

php artisan vendor:publish --tag="authorization"

Then run php artisan migrate.

Once you've done the migrations, create the following two models and insert the relevant trait:

The Role model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Stevebauman\Authorization\Traits\RolePermissionsTrait;

class Role extends Model
{
    use RolePermissionsTrait;

    /**
     * The roles table.
     *
     * @var string
     */
    protected $table = 'roles';
}

The permission model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Stevebauman\Authorization\Traits\PermissionRolesTrait;

class Permission extends Model
{
    use PermissionRolesTrait;

    /**
     * The permissions table.
     *
     * @var string
     */
    protected $table = 'permissions';
}

Now insert the Stevebauman\Authorization\Traits\UserRolesTrait onto your App\Models\User model:

namespace App\Models;

use Stevebauman\Authorization\Traits\UserRolesTrait;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;

class User extends Model
{
    use Authenticatable, Authorizable, CanResetPassword, UserRolesTrait;
    
    /**
     * The users table.
     *
     * @var string
     */
    protected $table = 'users';
}

You're all set!

Usage

Create a permission:

$createUsers = new Permission();

$createUsers->name = 'users.create';
$createUsers->label = 'Create Users';

$createUsers->save();

Grant the permission to a role:

$administrator = new Role();

$administrator->name = 'administrator';
$administrator->label = 'Admin';

$administrator->save();

// Granting the role the $createUsers permission.

$administrator->grant($createUsers);

// Or use regular relationship methods

$administrator->permissions()->save($createUsers);

Now assign the role to the user:

$user = User::find(1);

// Using the role model

$user->assignRole($administrator);

// Using the role name

$user->assignRole('administrator');

// Or use regular relationship methods

$user->roles()->save($administrator);

Perform authorization like so:

if (Auth::user()->hasPermission('users.create')) {
    
}

You can also create user specific permissions:

$createUsers = new Permission();

$createUsers->name = 'users.create';
$createUsers->label = 'Create Users';

$createUsers->save();

$user->permissions()->save($createUsers);

// Using the permissions name.
if ($user->hasPermission('users.create')) {
    //
}

// Using the permissions model.
if ($user->hasPermission($createUsers)) {
    //
}

Or using Laravel's native authorization methods such as the Gate facade:

if (Gate::allows('users.edit')) {
    //
}

Or by using Laravel's native AuthorizesRequests trait methods in your controllers:

public function index()
{
    $this->authorize('users.index');
    
    // User can access index.
}

Or by using Laravel's native can method on the user:

if (Auth::user()->can('users.index')) {
    // This user can access the index.
}

Or by using Laravel's native @can directive in your views:

@can('users.index')
    <!-- This user can access the index. -->
@endcan

Checking for multiple permissions:

if (Auth::user()->hasPermissions(['users.create', 'users.edit'])) {
    // This user has both creation and edit rights.
} else {
    // It looks like the user doesn't have one of the specified permissions.
}

Checking if the user has any permissions:

if (Auth::user()->hasAnyPermissions(['users.create', 'users.edit', 'users.destroy'])) {
    // This user either has create, edit or destroy permissions.
} else {
    // It looks like the user doesn't have any of the specified permissions.
}

Checking if the user has a role:

if (Auth::user()->hasRole('administrator')) {
    // This user is an administrator.
} else {
    // It looks like the user isn't an administrator.
}

Checking if the user has specified roles:

if (Auth::user()->hasRoles(['administrator', 'member'])) {
    // This user is an administrator and a member.
} else {
    // It looks like the user isn't an administrator or member.
}

Checking if the user has any specified roles:

if (Auth::user()->hasAnyRoles(['administrator', 'member', 'guest'])) {
    // This user is either an administrator, member or guest.
} else {
    // It looks like the user doesn't have any of these roles.
}

Middleware

Authorization includes two useful middleware classes you can utilize for your routes.

Insert them into your app/Http/Kernel.php:

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'permission' => \Stevebauman\Authorization\Middleware\PermissionMiddleware::class, // The permission middleware
    'role' => \Stevebauman\Authorization\Middleware\RoleMiddleware::class, // The role middleware
];

Once you've done that, you can start using them.

Note: When a user does not meet the requirements using the middleware, an Illuminate\Contracts\Validation\UnauthorizedException is thrown.

To guard a route to only allow specific permissions:

Route::get('users', [
    'uses' => 'UsersController@index',
    'middleware' => 'permission:users.index',
]);

// Multiple permissions:

Route::get('users', [
    'uses' => 'UsersController@index',
    'middleware' => 'permission:users.index,users.create', // Users must have index **and** create rights to access this route.
]);

To guard a route to allow a specific role:

Route::get('users', [
    'uses' => 'UsersController@index',
    'middleware' => 'role:administrator',
]);

// Multiple roles:

Route::get('users', [
    'uses' => 'UsersController@index',
    'middleware' => 'role:administrator,member', // Users must be an administrator **and** a member to access this route.
]);

Model Specific Permissions

To create permissions for a specific model, use the models key for a unique permission name. For example:

$user = User::find(1);

$permission = new Permission();

$permission->name = "users.edit.$user->id";
$permission->label = "Edit User: $user->name";

$permission->save();

Then validate it when editing the specific model:

public function edit($id)
{
    $user = $this->user->findOrFail($id);

    // The current user must have permission to edit this specific user.
    $this->authorize("users.edit.$user->id");
    
    return view('users.edit', compact('user'));
}