From 736d3fe25cf483b12d07f640cb3c81c5a12211a3 Mon Sep 17 00:00:00 2001 From: Hasin Hayder Date: Fri, 20 May 2022 22:23:13 +0600 Subject: [PATCH] User Management API with Proper Ability Check --- app/Http/Controllers/UserController.php | 47 ++++++++++++++++++++----- routes/api.php | 20 ++++++----- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 57fee50..fd14841 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -3,11 +3,13 @@ namespace App\Http\Controllers; use App\Models\Option; +use App\Models\Role; use App\Models\User; use Illuminate\Validation\ValidationException; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use App\Models\UserRole; +use Laravel\Sanctum\Exceptions\MissingAbilityException; class UserController extends Controller { /** @@ -38,7 +40,7 @@ class UserController extends Controller { $creds = $request->validate([ 'email' => 'required|email', 'password' => 'required', - 'name' => 'required' + 'name' => 'optional' ]); $user = User::where('email', $creds['email'])->first(); @@ -54,8 +56,8 @@ class UserController extends Controller { $default_user_role_id = Option::where('key', 'default_role_id')->first()->value; UserRole::create([ - 'user_id'=>$user->id, - 'role_id'=>$default_user_role_id + 'user_id' => $user->id, + 'role_id' => $default_user_role_id ]); @@ -86,11 +88,11 @@ class UserController extends Controller { $roles = $user->roles()->get(); $_roles = []; - foreach($roles as $role){ + foreach ($roles as $role) { $_roles[] = $role->slug; } - return $user->createToken('hydra-api-token',$_roles)->plainTextToken; + return $user->createToken('hydra-api-token', $_roles)->plainTextToken; } /** @@ -100,7 +102,7 @@ class UserController extends Controller { * @return \Illuminate\Http\Response */ public function show(User $user) { - // + return $user; } /** @@ -121,7 +123,24 @@ class UserController extends Controller { * @return \Illuminate\Http\Response */ public function update(Request $request, User $user) { - // + $user->name = $request->name ?? $user->name; + $user->email = $request->email ?? $user->email; + $user->password = $request->password ? Hash::make($request->password) : $user->password; + $user->email_verified_at = $request->email_verified_at ?? $user->email_verified_at; + + //check if the logged in user is updating it's own record + + + $loggedInUser = $request->user(); + if ($loggedInUser->id == $user->id) { + $user->update(); + } else if ($loggedInUser->tokenCan('admin') || $loggedInUser->tokenCan('super-admin')) { + $user->update(); + }else{ + throw new MissingAbilityException("Not Authorized"); + } + + return $user; } /** @@ -131,8 +150,18 @@ class UserController extends Controller { * @return \Illuminate\Http\Response */ public function destroy(User $user) { - // - } + //check if the current user is admin, then if there is only one admin - don't delete + $numberOfAdmins = Role::where('slug', 'admin')->first()->users()->count(); + if (1 == $numberOfAdmins) { + return response(['error' => 1, 'message' => 'Create another admin before deleting this only admin user'], 409); + } + $user->delete(); + return response(['error' => 0, 'message' => 'user deleted']); + } + + public function me(Request $request){ + return $request->user(); + } } diff --git a/routes/api.php b/routes/api.php index 30fccc1..57eeeff 100644 --- a/routes/api.php +++ b/routes/api.php @@ -18,16 +18,20 @@ use Illuminate\Support\Facades\Route; | */ -Route::middleware('auth:sanctum')->get('/user', function (Request $request) { - return $request->user(); -}); +// Route::middleware('auth:sanctum')->get('/user', function (Request $request) { +// return $request->user(); +// }); -Route::get('/hydra',[HydraController::class,'hydra']); -Route::get('/hydra/version',[HydraController::class,'version']); +Route::get('hydra',[HydraController::class,'hydra']); +Route::get('hydra/version',[HydraController::class,'version']); -Route::apiResource('users',UserController::class)->except(['edit','create'])->middleware(['auth:sanctum', 'abilities:admin,super-admin']); +Route::apiResource('users',UserController::class)->except(['edit','create','store','update'])->middleware(['auth:sanctum', 'ability:admin,super-admin']); Route::post('users',[UserController::class,'store']); +Route::put('users/{user}',[UserController::class,'update'])->middleware(['auth:sanctum', 'ability:admin,super-admin,user']); +Route::post('users/{user}',[UserController::class,'update'])->middleware(['auth:sanctum', 'ability:admin,super-admin,user']); +Route::patch('users/{user}',[UserController::class,'update'])->middleware(['auth:sanctum', 'ability:admin,super-admin,user']); +Route::get('me',[UserController::class,'me'])->middleware('auth:sanctum'); Route::post('login',[UserController::class,'login']); -Route::apiResource('roles',RoleController::class)->except(['create','edit'])->middleware(['auth:sanctum', 'abilities:admin,super-admin']); -Route::apiResource('users.roles',UserRoleController::class)->except(['create','edit','show','update'])->middleware(['auth:sanctum', 'abilities:admin,super-admin']); +Route::apiResource('roles',RoleController::class)->except(['create','edit'])->middleware(['auth:sanctum', 'ability:admin,super-admin,user']); +Route::apiResource('users.roles',UserRoleController::class)->except(['create','edit','show','update'])->middleware(['auth:sanctum', 'ability:admin,super-admin']);