Last active
December 22, 2020 08:10
-
-
Save aelfannir/f53c25fc7fb58ebe9faeeedd3036fae2 to your computer and use it in GitHub Desktop.
User Role managment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App; | |
use Illuminate\Foundation\Auth\User as Authenticatable; | |
/** | |
* Class User | |
* @package App | |
*/ | |
class User extends Authenticatable | |
{ | |
//... | |
public const ROLE_VISITOR = "ROLE_VISITOR"; | |
public const ROLE_PROVIDER = "ROLE_PROVIDER"; | |
public const ROLE_CLIENT = "ROLE_CLIENT"; | |
public const ROLE_SUPER_ADMIN = "ROLE_SUPER_ADMIN"; | |
protected static $roleHierarchy = [ | |
self::ROLE_SUPER_ADMIN => ['*'], | |
self::ROLE_PROVIDER => [self::ROLE_VISITOR], | |
self::ROLE_CLIENT => [self::ROLE_VISITOR], | |
self::ROLE_VISITOR => [] | |
]; | |
/** | |
* The attributes that should be cast to native types. | |
* | |
* @var array | |
*/ | |
protected $casts = [ | |
'roles'=>'array' | |
]; | |
/*** | |
* @param $role | |
* @return mixed | |
*/ | |
public function hasRole($role) | |
{ | |
return in_array($role, $this->getRoles()); | |
} | |
/** | |
* @return array | |
*/ | |
public function getRoles() | |
{ | |
$roles = $this->getAttribute('roles'); | |
if (is_null($roles)) { | |
$roles = []; | |
} | |
return $roles; | |
} | |
/** | |
* @param string $role | |
* @return array | |
*/ | |
public static function getAllowedRoles(string $role) | |
{ | |
if (isset(self::$roleHierarchy[$role])) { | |
return self::$roleHierarchy[$role]; | |
} | |
return []; | |
} | |
public function check(User $user, string $role) | |
{ | |
//todo use current model | |
// Admin has everything | |
if ($user->hasRole(self::ROLE_SUPER_ADMIN)) { | |
return true; | |
} | |
else if($user->hasRole(self::ROLE_CLIENT)) { | |
$managementRoles = $this->getAllowedRoles(self::ROLE_CLIENT); | |
if (in_array($role, $managementRoles)) { | |
return true; | |
} | |
} | |
return $user->hasRole($role); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Database\Migrations\Migration; | |
use Illuminate\Database\Query\Expression; | |
use Illuminate\Database\Schema\Blueprint; | |
use Illuminate\Support\Facades\Schema; | |
class CreateUsersTable extends Migration | |
{ | |
/** | |
* Run the migrations. | |
* | |
* @return void | |
*/ | |
public function up() | |
{ | |
Schema::create('users', function (Blueprint $table) { | |
//... | |
$table->json('roles')->nullable()->default(new Expression('(JSON_ARRAY("ROLE_VISITOR"))')); | |
}); | |
} | |
/** | |
* Reverse the migrations. | |
* | |
* @return void | |
*/ | |
public function down() | |
{ | |
Schema::dropIfExists('users'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Http\Middleware; | |
use Closure; | |
use App\User; | |
use App\RoleChecker; | |
use Illuminate\Auth\Access\AuthorizationException; | |
use Illuminate\Http\Response; | |
use Illuminate\Support\Facades\Auth; | |
/** | |
* Class CheckUserRole | |
* @package App\Http\Middleware | |
*/ | |
class CheckUserRole | |
{ | |
/** | |
* @var RoleChecker | |
*/ | |
protected $roleChecker; | |
/** | |
* CheckUserRole constructor. | |
* @param RoleChecker $roleChecker | |
*/ | |
public function __construct(RoleChecker $roleChecker) | |
{ | |
$this->roleChecker = $roleChecker; | |
} | |
/** | |
* Handle an incoming request. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @param \Closure $next | |
* @param mixed ...$roles | |
* @return mixed | |
*/ | |
public function handle($request, Closure $next, ...$roles) | |
{ | |
if(!in_array(User::ROLE_VISITOR,$roles) && !Auth::check()) { | |
return response($roles,Response::HTTP_UNAUTHORIZED); | |
} | |
if ( ! $this->roleChecker->check(Auth::guard()->user(), $roles)) { | |
return response(null,Response::HTTP_FORBIDDEN); | |
} | |
return $next($request); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Providers; | |
use App\Http\Middleware\CheckUserRole; | |
use App\RoleChecker; | |
use Illuminate\Foundation\Application; | |
use Illuminate\Support\ServiceProvider; | |
/** | |
* Class AppServiceProvider | |
* @package App\Providers | |
*/ | |
class AppServiceProvider extends ServiceProvider | |
{ | |
/** | |
* Register any application services. | |
* | |
* @return void | |
*/ | |
public function register() | |
{ | |
//... | |
$this->app->singleton(CheckUserRole::class, function(Application $app) { | |
return new CheckUserRole( | |
$app->make(RoleChecker::class) | |
); | |
}); | |
} | |
//... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http; | |
use Illuminate\Foundation\Http\Kernel as HttpKernel; | |
class Kernel extends HttpKernel | |
{ | |
//... | |
/** | |
* The application's route middleware. | |
* | |
* These middleware may be assigned to groups or used individually. | |
* | |
* @var array | |
*/ | |
protected $routeMiddleware = [ | |
//... | |
'check_user_role' => \App\Http\Middleware\CheckUserRole::class, | |
]; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
//... | |
public function __construct() | |
{ | |
$this->middleware('auth:api', ['except' => ['index']]); | |
$this->middleware('check_user_role:' .implode(',',[User::ROLE_CLIENT]))->only(['show','store']); | |
} | |
public function index() | |
{ | |
//... | |
} | |
public function show() | |
{ | |
//... | |
} | |
public function store() | |
{ | |
//... | |
} | |
public function update() | |
{ | |
//... | |
} | |
public function destroy() | |
{ | |
//... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment