Skip to content

Commit

Permalink
Role middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
Raccoon254 committed Apr 1, 2024
1 parent d350d78 commit 1320e12
Show file tree
Hide file tree
Showing 15 changed files with 171 additions and 60 deletions.
Binary file modified .DS_Store
Binary file not shown.
Binary file modified app/.DS_Store
Binary file not shown.
35 changes: 18 additions & 17 deletions app/Http/Controllers/Auth/RegisteredUserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,7 @@ public function store(Request $request): RedirectResponse
*/
public function store_client(Request $request): RedirectResponse
{
dd($request->all());
/*array:7 [▼ // app/Http/Controllers/Auth/RegisteredUserController.php:73
"_token" => "8SSZoXpatAKSZRaDSOAEfdid3SbuC45fHlNeo0ym"
"name" => "Raccoon"
"email" => "[email protected]"
"phone_number" => "88818912"
"address" => "22"
"password" => "222"
"password_confirmation" => "2222"
]
*/
// Validate the request
$request->validate([
"name" => ["required", "string", "max:255"],
"email" => [
Expand All @@ -97,30 +87,41 @@ public function store_client(Request $request): RedirectResponse
"max:10",
"unique:" . User::class,
],
"address" => ["required", "string"],
"password" => ["required", "confirmed", Rules\Password::defaults()],
]);

// Validate the phone number
$phone_number_validated = $this->validateNumber($request->phone_number);
if (!$phone_number_validated) {
return redirect()->back()->with("error", "Invalid phone number");
}

// Create the user
$user = User::create([
"name" => $request->name,
"email" => $request->email,
"role" => "client",
"role" => "client", // Assign the role of client
"phone_number" => $phone_number_validated,
"password" => Hash::make($request->password),
]);

event(new Registered($user));

// Log in the new user
Auth::login($user);
$user->last_login_at = now();

//create a client
// Create the client and associate it with the user
$client = new Client([
"address" => $request->address,
// TODO! add other client-specific fields
// - Location data is useful for location-based services
]);
$user->client()->save($client); // Assuming you have a client relation defined on the User model

return redirect(RouteServiceProvider::HOME);
// Optionally, redirect with a success message
return redirect(RouteServiceProvider::HOME)->with(
"success",
"Client account created successfully."
);
}

private function validateNumber(mixed $phone_number): int|bool
Expand Down
33 changes: 19 additions & 14 deletions app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Kernel extends HttpKernel
* @var array<string, array<int, class-string|string>>
*/
protected $middlewareGroups = [
'web' => [
"web" => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
Expand All @@ -38,9 +38,9 @@ class Kernel extends HttpKernel
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],

'api' => [
"api" => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\ThrottleRequests::class . ":api",
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Expand All @@ -53,16 +53,21 @@ class Kernel extends HttpKernel
* @var array<string, class-string|string>
*/
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
"auth" => \App\Http\Middleware\Authenticate::class,
"auth.basic" =>
\Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
"auth.session" =>
\Illuminate\Session\Middleware\AuthenticateSession::class,
"cache.headers" => \Illuminate\Http\Middleware\SetCacheHeaders::class,
"can" => \Illuminate\Auth\Middleware\Authorize::class,
"guest" => \App\Http\Middleware\RedirectIfAuthenticated::class,
"password.confirm" =>
\Illuminate\Auth\Middleware\RequirePassword::class,
"precognitive" =>
\Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
"signed" => \App\Http\Middleware\ValidateSignature::class,
"throttle" => \Illuminate\Routing\Middleware\ThrottleRequests::class,
"verified" => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
"role" => \App\Http\Middleware\RoleMiddleware::class,
];
}
32 changes: 32 additions & 0 deletions app/Http/Middleware/RoleMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class RoleMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next, ...$roles)
{
if (!Auth::check()) {
return redirect("/login");
}

$user = Auth::user();

if (in_array($user->role, $roles)) {
return $next($request);
}

return redirect("/unauthorized");
}
}
27 changes: 15 additions & 12 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,34 @@ class User extends Authenticatable implements MustVerifyEmail
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'role',
'phone_number',
'password',
'last_login_at',
"name",
"email",
"role",
"phone_number",
"password",
"last_login_at",
];

/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
protected $hidden = ["password", "remember_token"];

/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
"email_verified_at" => "datetime",
"password" => "hashed",
];

//client relationship
public function client()
{
return $this->hasOne(Client::class);
}
}
Binary file added resources/.DS_Store
Binary file not shown.
9 changes: 5 additions & 4 deletions resources/views/auth/verify-email.blade.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<x-guest-layout>
<div class="mb-4 text-sm text-gray-600">
<div class="mb-4 text-sm text-gray-200">
{{ __('Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }}
</div>

Expand All @@ -14,17 +14,18 @@
@csrf

<div>
<x-primary-button>
<button class="btn ring-1 ring-offset-1 ring-gray-400 btn-secondary normal-case w-full mt-4 rounded-full btn-outline transition duration-300 ease-in-out">
{{ __('Resend Verification Email') }}
</x-primary-button>
</button>
</div>
</form>

<form method="POST" action="{{ route('logout') }}">
@csrf

<button type="submit" class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<button type="submit" class="ring-1 ring-inset btn btn-ghost rounded-full text-sm text-gray-400 hover:text-gray-200 normal-case focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
{{ __('Log Out') }}
<i class="fa-solid fa-arrow-right"></i>
</button>
</form>
</div>
Expand Down
2 changes: 1 addition & 1 deletion resources/views/layouts/app.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
@include('layouts.partials.sidebar')
<main class="bg-gray-100 rounded-[10px] w-full m-2">
@include('layouts.navigation')

@include('session.alerts')
{{ $slot }}
</main>
</div>
Expand Down
1 change: 1 addition & 0 deletions resources/views/layouts/guest.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class="min-h-screen pt-20 sm:pt-0 flex flex-col sm:justify-center items-center b
</div>

<div class="w-full sm:max-w-[80%] mt-6 px-6 py-4 overflow-hidden sm:rounded-lg">
@include('session.alerts')
{{ $slot }}
</div>
</div>
Expand Down
22 changes: 22 additions & 0 deletions resources/views/session/alerts.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!--Check if there are any messages within the session-->
@if(session('success'))
<div class="alert rounded mt-3 alert-success">
{{ session('success') }}
</div>
@endif

@if(session('error'))
<div class="alert rounded mt-3 bg-red-500 alert-danger">
{{ session('error') }}
</div>
@endif

@if ($errors->any())
<div class="alert rounded mt-3 bg-red-500 alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
12 changes: 12 additions & 0 deletions resources/views/static/unauthorized.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<x-guest-layout>

<div class="mb-4 text-sm text-gray-300">
{{ __('You are not authorized to access this page.') }}
</div>

<div class="mt-4 flex items-center justify-between">
<button>
<a href="{{ route('dashboard') }}">Go Back</a>
</button>
</div>
</x-guest-layout>
58 changes: 46 additions & 12 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,55 @@
|
*/

Route::get('/', function () {
return view('welcome');
Route::get("/", function () {
return view("welcome");
});

Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
Route::get("/dashboard", function () {
return view("dashboard");
})
->middleware(["auth", "verified"])
->name("dashboard");

Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
Route::group(["middleware" => ["auth", "role:admin"]], function () {
Route::get("/admin/dashboard", function () {
return view("admin.dashboard");
})->name("admin.dashboard");
});

Route::post('/set-theme', [ThemeController::class, 'setTheme'])->name('set-theme');
Route::get('/get-theme', [ThemeController::class, 'getTheme'])->name('get-theme');
Route::group(["middleware" => ["auth", "role:manager"]], function () {
Route::get("/manager/dashboard", function () {
return view("manager.dashboard");
})->name("manager.dashboard");
});

Route::group(["middleware" => ["auth", "role:user"]], function () {
Route::get("/user/dashboard", function () {
return view("user.dashboard");
})->name("user.dashboard");
});

Route::middleware("auth")->group(function () {
Route::get("/profile", [ProfileController::class, "edit"])->name(
"profile.edit"
);
Route::patch("/profile", [ProfileController::class, "update"])->name(
"profile.update"
);
Route::delete("/profile", [ProfileController::class, "destroy"])->name(
"profile.destroy"
);
});

Route::get("/unauthorized", function () {
return view("static/unauthorized");
})->name("unauthorized");

Route::post("/set-theme", [ThemeController::class, "setTheme"])->name(
"set-theme"
);
Route::get("/get-theme", [ThemeController::class, "getTheme"])->name(
"get-theme"
);

require __DIR__.'/auth.php';
require __DIR__ . "/auth.php";
Binary file added storage/.DS_Store
Binary file not shown.
Binary file added tests/.DS_Store
Binary file not shown.

0 comments on commit 1320e12

Please sign in to comment.