Skip to content

Instantly share code, notes, and snippets.

@gundamew
Created January 19, 2021 10:39
Show Gist options
  • Save gundamew/4cd1f63d81ddf9304dd588256ec0329f to your computer and use it in GitHub Desktop.
Save gundamew/4cd1f63d81ddf9304dd588256ec0329f to your computer and use it in GitHub Desktop.
A Laravel native RBAC example. Try to do it myself.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRolePermissionsTable extends Migration
{
public function up()
{
Schema::create('role_permissions', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('role_id');
$table->string('action');
$table->timestamps();
});
}
}
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateRolesTable extends Migration
{
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('display_name');
$table->timestamps();
});
}
}
<?php
namespace App\Permissions;
class OrderPermissions
{
const VIEW = 'view_order';
const VIEW_ANY = 'view_any_orders';
const CREATE = 'create_order';
const UPDATE = 'update_order';
const DELETE = 'delete_order';
public static function forAdmin()
{
return [
static::VIEW,
static::VIEW_ANY,
static::CREATE,
static::UPDATE,
static::DELETE,
];
}
public static function forUser()
{
return [
static::VIEW,
static::CREATE,
];
}
}
<?php
namespace App\Policies;
use App\User;
use App\Order;
use App\Permissions\OrderPermissions;
use Illuminate\Auth\Access\HandlesAuthorization;
class OrderPolicy
{
use HandlesAuthorization;
public function viewAny(User $user)
{
return $user->roles()->whereHas('permissions', function ($query) {
return $query->where('action', OrderPermissions::VIEW_ANY);
})->get()->isNotEmpty();
}
public function view(User $user, Order $order)
{
return $user->roles()->whereHas('permissions', function ($query) {
return $query->whereIn('action', [
OrderPermissions::VIEW,
OrderPermissions::VIEW_ANY,
]);
})->get()->isNotEmpty();
}
public function create(User $user)
{
return $user->roles()->whereHas('permissions', function ($query) {
return $query->where('action', OrderPermissions::CREATE);
})->get()->isNotEmpty();
}
public function update(User $user, Order $order)
{
return $user->roles()->whereHas('permissions', function ($query) {
return $query->where('action', OrderPermissions::UPDATE);
})->get()->isNotEmpty();
}
public function delete(User $user, Order $order)
{
return $user->roles()->whereHas('permissions', function ($query) {
return $query->where('action', OrderPermissions::DELETE);
})->get()->isNotEmpty();
}
}
<?php
namespace App;
use App\User;
use App\RolePermission;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
const ADMIN = 'administrator';
const USER = 'user';
public function users()
{
return $this->belongsToMany(User::class, 'user_roles', 'role_id', 'user_id');
}
public function permissions()
{
return $this->hasMany(RolePermission::class, 'role_id', 'id');
}
}
<?php
namespace App;
use App\Role;
use Illuminate\Database\Eloquent\Model;
class RolePermission extends Model
{
public function role()
{
return $this->belongsTo(Role::class, 'role_id', 'id');
}
}
<?php
use App\Role;
use Illuminate\Database\Seeder;
use App\Permissions\UserPermissions;
class RolePermissionsTableSeeder extends Seeder
{
public function run()
{
$role = Role::where('name', Role::ADMIN)->firstOrFail();
$role->permissions()->createMany(
collect(UserPermissions::forAdmin())->transform(function ($action) {
return ['action' => $action];
})->values()->toArray()
);
$role = Role::where('name', Role::USER)->firstOrFail();
$role->permissions()->createMany(
collect(UserPermissions::forUser())->transform(function ($action) {
return ['action' => $action];
})->values()->toArray()
);
}
}
<?php
namespace App;
use App\Role;
class User
{
public function roles()
{
return $this->belongsToMany(Role::class, 'user_roles', 'user_id', 'role_id');
}
public function hasRole($role)
{
return $this->roles()->where('name', $role)->get()->isNotEmpty();
}
public function isAdmin()
{
return $this->hasRole(Role::ADMIN);
}
public function isUser()
{
return $this->hasRole(Role::USER);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment