Skip to content

Commit c4f6e59

Browse files
committed
Added Role and Permission implementation along with policies, middleware, requests, controllers, models, migrations, and tests.
1 parent 177ea7c commit c4f6e59

17 files changed

Lines changed: 670 additions & 0 deletions
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Http\Requests\StorePermissionRequest;
6+
use App\Http\Requests\UpdatePermissionRequest;
7+
use App\Models\Permission;
8+
9+
class PermissionController extends Controller
10+
{
11+
/**
12+
* Display a listing of the resource.
13+
*/
14+
public function index()
15+
{
16+
//
17+
}
18+
19+
/**
20+
* Show the form for creating a new resource.
21+
*/
22+
public function create()
23+
{
24+
//
25+
}
26+
27+
/**
28+
* Store a newly created resource in storage.
29+
*/
30+
public function store(StorePermissionRequest $request)
31+
{
32+
//
33+
}
34+
35+
/**
36+
* Display the specified resource.
37+
*/
38+
public function show(Permission $permission)
39+
{
40+
//
41+
}
42+
43+
/**
44+
* Show the form for editing the specified resource.
45+
*/
46+
public function edit(Permission $permission)
47+
{
48+
//
49+
}
50+
51+
/**
52+
* Update the specified resource in storage.
53+
*/
54+
public function update(UpdatePermissionRequest $request, Permission $permission)
55+
{
56+
//
57+
}
58+
59+
/**
60+
* Remove the specified resource from storage.
61+
*/
62+
public function destroy(Permission $permission)
63+
{
64+
//
65+
}
66+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Http\Requests\StoreRoleRequest;
6+
use App\Http\Requests\UpdateRoleRequest;
7+
use App\Models\Role;
8+
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
9+
use Inertia\Inertia;
10+
11+
class RoleController extends Controller
12+
{
13+
use AuthorizesRequests;
14+
/**
15+
* Display a listing of the resource.
16+
*/
17+
public function index()
18+
{
19+
//
20+
}
21+
22+
/**
23+
*
24+
*/
25+
public function getRoles()
26+
{
27+
$this->authorize('view-any', Role::class);
28+
return Role::all();
29+
}
30+
/**
31+
* Show the form for creating a new resource.
32+
*/
33+
public function create()
34+
{
35+
return inertia::render('');
36+
}
37+
38+
/**
39+
* Store a newly created resource in storage.
40+
* @param StoreRoleRequest $request
41+
* @return \Illuminate\Http\JsonResponse
42+
*/
43+
public function store(StoreRoleRequest $request)
44+
{
45+
46+
$this->authorize('create', Role::class);
47+
48+
$request->validated();
49+
50+
Role::create([
51+
'name' => $request->name,
52+
'description' => $request->description
53+
]);
54+
55+
return response()->json(['message' => 'Role Added'], 200);
56+
57+
}
58+
59+
/**
60+
* @ AI
61+
* @param $id
62+
* @return mixed
63+
*/
64+
public function getRole($id)
65+
{
66+
$role = Role::findorfail($id);
67+
$this->authorize('view-any', $role);
68+
return $role;
69+
}
70+
/**
71+
* Display the specified resource.
72+
*/
73+
public function show(Role $role)
74+
{
75+
//
76+
}
77+
78+
/**
79+
* Show the form for editing the specified resource.
80+
*/
81+
public function edit(Role $role)
82+
{
83+
//
84+
}
85+
86+
/**
87+
* Update the specified resource in storage.
88+
*/
89+
public function update(UpdateRoleRequest $request, Role $role)
90+
{
91+
//
92+
}
93+
94+
/**
95+
* Remove the specified resource from storage.
96+
*/
97+
public function destroy(Role $role)
98+
{
99+
//
100+
}
101+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace App\Http\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Symfony\Component\HttpFoundation\Response;
8+
9+
class PermissionMiddleware
10+
{
11+
/**
12+
* Handles an incoming request by checking user permissions.
13+
*
14+
* @param Request $request The incoming request instance.
15+
* @param Closure $next The next middleware to be executed.
16+
* @param string $permission The required permission to access the resource.
17+
*
18+
* @return Response
19+
*
20+
* @throws \Symfony\Component\HttpKernel\Exception\HttpException Throws an HTTP 403 exception if the user lacks the required permission.
21+
*/
22+
public function handle(Request $request, Closure $next, string $permission): Response
23+
{
24+
// Abort if unauthenticated or the user does NOT have the required permission
25+
if (! $request->user() || ! $request->user()->hasPermission($permission)) {
26+
abort(403, 'Access denied — Missing permission: ' . $permission);
27+
}
28+
29+
return $next($request);
30+
}
31+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace App\Http\Middleware;
4+
5+
use Closure;
6+
use Illuminate\Http\Request;
7+
use Symfony\Component\HttpFoundation\Response;
8+
9+
class RoleMiddleware
10+
{
11+
/**
12+
* Handle an incoming request and validate user role access.
13+
*
14+
* Checks if the authenticated user has the required role. If the user is
15+
* either not authenticated or does not have the specified role, an HTTP
16+
* 403 error is triggered with an appropriate unauthorized message.
17+
*
18+
* @param Request $request The current HTTP request instance.
19+
* @param Closure $next A callback to pass the request to the next middleware.
20+
* @param string $role The required role for the requested action.
21+
* @return Response The HTTP response after processing the request.
22+
* @throws \Symfony\Component\HttpKernel\Exception\HttpException If the user is unauthorized.
23+
*/
24+
public function handle(Request $request, Closure $next, string $role): Response
25+
{
26+
// Abort if unauthenticated or the user does NOT have the required role
27+
if (! $request->user() || ! $request->user()->hasRole($role)) {
28+
abort(403, 'Unauthorized — Role required: ' . $role);
29+
}
30+
return $next($request);
31+
}
32+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace App\Http\Requests;
4+
5+
use Illuminate\Foundation\Http\FormRequest;
6+
7+
class StorePermissionRequest extends FormRequest
8+
{
9+
/**
10+
* Determine if the user is authorized to make this request.
11+
*/
12+
public function authorize(): bool
13+
{
14+
return false;
15+
}
16+
17+
/**
18+
* Get the validation rules that apply to the request.
19+
*
20+
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
21+
*/
22+
public function rules(): array
23+
{
24+
return [
25+
//
26+
];
27+
}
28+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace App\Http\Requests;
4+
5+
use Illuminate\Foundation\Http\FormRequest;
6+
7+
class StoreRoleRequest extends FormRequest
8+
{
9+
/**
10+
* Determine if the user is authorized to make this request.
11+
*/
12+
public function authorize(): bool
13+
{
14+
return true;
15+
}
16+
17+
/**
18+
* Get the validation rules that apply to the request.
19+
*
20+
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
21+
*/
22+
public function rules(): array
23+
{
24+
return [
25+
'name' => 'required',
26+
'description' => 'required|min:5'
27+
];
28+
}
29+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace App\Http\Requests;
4+
5+
use Illuminate\Foundation\Http\FormRequest;
6+
7+
class UpdatePermissionRequest extends FormRequest
8+
{
9+
/**
10+
* Determine if the user is authorized to make this request.
11+
*/
12+
public function authorize(): bool
13+
{
14+
return false;
15+
}
16+
17+
/**
18+
* Get the validation rules that apply to the request.
19+
*
20+
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
21+
*/
22+
public function rules(): array
23+
{
24+
return [
25+
//
26+
];
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace App\Http\Requests;
4+
5+
use Illuminate\Foundation\Http\FormRequest;
6+
7+
class UpdateRoleRequest extends FormRequest
8+
{
9+
/**
10+
* Determine if the user is authorized to make this request.
11+
*/
12+
public function authorize(): bool
13+
{
14+
return false;
15+
}
16+
17+
/**
18+
* Get the validation rules that apply to the request.
19+
*
20+
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
21+
*/
22+
public function rules(): array
23+
{
24+
return [
25+
//
26+
];
27+
}
28+
}

app/Models/Permission.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
7+
use Illuminate\Database\Eloquent\SoftDeletes;
8+
9+
class Permission extends Model
10+
{
11+
use SoftDeletes;
12+
//
13+
14+
protected $fillable = ['name', 'description'];
15+
16+
public function roles(): BelongsToMany
17+
{
18+
return $this->belongsToMany(Role::class);
19+
}
20+
}

0 commit comments

Comments
 (0)