From fa4823dd632cad6a5736c1d900a064647bb72c20 Mon Sep 17 00:00:00 2001 From: ryo Date: Tue, 11 Mar 2025 16:15:29 +0000 Subject: Added admin user that can change usres team Fixed: player login based on user and password Added: show errors to the user --- app/Http/Controllers/PlayerController.php | 77 +++++++++++++++++++--- app/Models/Player.php | 18 ++++- config/auth.php | 13 ++-- .../2025_03_06_091820_create_players_table.php | 40 ----------- .../2025_03_08_132951_create_players_table.php | 43 ++++++++++++ database/seeders/DatabaseSeeder.php | 13 ++-- public/css/app.css | 3 + resources/views/admin.blade.php | 46 +++++++++++++ resources/views/dashboard.blade.php | 34 ++++++++-- resources/views/login.blade.php | 18 +++++ resources/views/register.blade.php | 19 +++++- routes/web.php | 21 +++--- 12 files changed, 262 insertions(+), 83 deletions(-) delete mode 100644 database/migrations/2025_03_06_091820_create_players_table.php create mode 100644 database/migrations/2025_03_08_132951_create_players_table.php create mode 100644 public/css/app.css create mode 100644 resources/views/admin.blade.php diff --git a/app/Http/Controllers/PlayerController.php b/app/Http/Controllers/PlayerController.php index d39b177..d80c04e 100644 --- a/app/Http/Controllers/PlayerController.php +++ b/app/Http/Controllers/PlayerController.php @@ -4,38 +4,97 @@ namespace App\Http\Controllers; use App\Models\Player; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Hash; use Symfony\Component\HttpFoundation\RedirectResponse; class PlayerController extends Controller { public function register(Request $request): RedirectResponse { - Player::create([ + $request->validate([ + 'name' => ['required', 'string', 'min:3', 'max:20'], + 'password' => ['required', 'string', 'min:4'], + ]); + $player = Player::create([ 'name' => $request->name, - 'team' => $request->team, - 'score' => 12, + 'password' => Hash::make($request->password), + 'team' => 'none', + 'score' => 0, ]); - return redirect('/'); + Auth::login($player); + + return redirect('dashboard'); } - public function login(Request $request) + public function login(Request $request): RedirectResponse { - if (! Player::where('name', $request->name)->exists()) { - return redirect('/'); + $credentials = $request->validate([ + 'name' => 'required', + 'password' => 'required', + ]); + + if (Auth::attempt($credentials)) { + $player = Auth::user(); + if (isset($player->is_admin)) { + return redirect('/admin'); + } + + return redirect('/dashboard'); } + return back()->withErrors([ + 'name' => 'The provided credentials do not match our records.', + ]); + } + + public function profile() + { + $player = Auth::user(); + + return view('/dashboard', compact('player')); + } + + public function admin() + { + $admin = Auth::user(); + $players = Player::all(); + + return view('/admin', compact('admin'), compact('players')); + } + + public function admin_team(Request $request): RedirectResponse + { + $request->validate([ + 'name' => ['required'], + 'team' => ['required'], + ]); $player = Player::where('name', $request->name)->first(); + $player->team = $request->team; + $player->save(); - return view('dashboard', compact('player')); + return back(); } public function score(Request $request): RedirectResponse { - $player = Player::find($request->id); + $request->validate([ + 'score' => ['required', 'integer', 'gt:0'], + ]); + $player = Auth::user(); $player->score = $request->score; $player->save(); return back(); } + + public function logout(Request $request): RedirectResponse + { + Auth::logout(); + $request->session()->invalidate(); + $request->session()->regenerateToken(); + + return redirect('/'); + } } diff --git a/app/Models/Player.php b/app/Models/Player.php index 12b95c5..3c2440c 100644 --- a/app/Models/Player.php +++ b/app/Models/Player.php @@ -2,13 +2,27 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Model; +use Illuminate\Foundation\Auth\User as Authenticatable; -class Player extends Model +class Player extends Authenticatable { protected $fillable = [ 'name', + 'password', 'team', 'score', ]; + + protected $hidden = [ + 'password', + 'remember_token', + 'is_amdin', + ]; + + protected function casts(): array + { + return [ + 'password' => 'hashed', + ]; + } } diff --git a/config/auth.php b/config/auth.php index 0ba5d5d..7375045 100644 --- a/config/auth.php +++ b/config/auth.php @@ -38,13 +38,13 @@ return [ 'guards' => [ 'web' => [ 'driver' => 'session', - 'provider' => 'users', + 'provider' => 'players', ], ], /* |-------------------------------------------------------------------------- - | User Providers + | Player Providers |-------------------------------------------------------------------------- | | All authentication guards have a user provider, which defines how the @@ -60,15 +60,10 @@ return [ */ 'providers' => [ - 'users' => [ + 'players' => [ 'driver' => 'eloquent', - 'model' => env('AUTH_MODEL', App\Models\User::class), + 'model' => env('AUTH_MODEL', App\Models\Player::class), ], - - // 'users' => [ - // 'driver' => 'database', - // 'table' => 'users', - // ], ], /* diff --git a/database/migrations/2025_03_06_091820_create_players_table.php b/database/migrations/2025_03_06_091820_create_players_table.php deleted file mode 100644 index d078edf..0000000 --- a/database/migrations/2025_03_06_091820_create_players_table.php +++ /dev/null @@ -1,40 +0,0 @@ -id(); - $table->timestamps(); - $table->string('name'); - $table->string('team'); - $table->integer('score'); - }); - - Schema::create('sessions', function (Blueprint $table) { - $table->string('id')->primary(); - $table->foreignId('user_id')->nullable()->index(); - $table->string('ip_address', 45)->nullable(); - $table->text('user_agent')->nullable(); - $table->longText('payload'); - $table->integer('last_activity')->index(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('players'); - Schema::dropIfExists('sessions'); - } -}; diff --git a/database/migrations/2025_03_08_132951_create_players_table.php b/database/migrations/2025_03_08_132951_create_players_table.php new file mode 100644 index 0000000..13d4e24 --- /dev/null +++ b/database/migrations/2025_03_08_132951_create_players_table.php @@ -0,0 +1,43 @@ +id(); + $table->timestamps(); + $table->rememberToken(); + $table->string('name')->unique(); + $table->string('password'); + $table->string('team'); + $table->integer('score'); + $table->boolean('is_admin')->nullable(); + }); + + Schema::create('sessions', function (Blueprint $table) { + $table->string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->longText('payload'); + $table->integer('last_activity')->index(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('players'); + Schema::dropIfExists('sessions'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index d01a0ef..1342d58 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -2,9 +2,9 @@ namespace Database\Seeders; -use App\Models\User; -// use Illuminate\Database\Console\Seeds\WithoutModelEvents; +use App\Models\Player; use Illuminate\Database\Seeder; +use Illuminate\Support\Facades\Hash; class DatabaseSeeder extends Seeder { @@ -15,9 +15,12 @@ class DatabaseSeeder extends Seeder { // User::factory(10)->create(); - User::factory()->create([ - 'name' => 'Test User', - 'email' => 'test@example.com', + Player::create([ + 'name' => 'admin', + 'password' => Hash::make('12345'), + 'team' => 'none', + 'score' => 100, + 'is_admin' => true, ]); } } diff --git a/public/css/app.css b/public/css/app.css new file mode 100644 index 0000000..c2ca89b --- /dev/null +++ b/public/css/app.css @@ -0,0 +1,3 @@ +.error { + color: red; +} diff --git a/resources/views/admin.blade.php b/resources/views/admin.blade.php new file mode 100644 index 0000000..4140b13 --- /dev/null +++ b/resources/views/admin.blade.php @@ -0,0 +1,46 @@ + + + + Admin + + + +@if(Auth::check()) +
Welcome admin!!
+@endif +

User List

+@if($players->isEmpty()) +

No player found.

+@else + +@endif +
+ @csrf + +
+ + +
+ +
+ + +
+ + @if($errors->any()) +
{{ $errors->first() }}
+ @endif + + +
+
+ @csrf + + +
+ + diff --git a/resources/views/dashboard.blade.php b/resources/views/dashboard.blade.php index 7001be3..6961cdb 100644 --- a/resources/views/dashboard.blade.php +++ b/resources/views/dashboard.blade.php @@ -1,17 +1,37 @@ - + + + + Dashboard + + + +@if(Auth::check()) +
You are logged in successfully
+@endif + -
+ @csrf -
+ @if($errors->any()) +
{{ $errors->first() }}
+ @endif +
+
+ @csrf + + +
+ + diff --git a/resources/views/login.blade.php b/resources/views/login.blade.php index d5a528d..9f30bf7 100644 --- a/resources/views/login.blade.php +++ b/resources/views/login.blade.php @@ -1,3 +1,10 @@ + + + + Login + + +
@csrf @@ -6,5 +13,16 @@ +
+ + +
+ + @if($errors->any()) +
{{ $errors->first() }}
+ @endif +
+ + diff --git a/resources/views/register.blade.php b/resources/views/register.blade.php index f526a43..b23dac0 100644 --- a/resources/views/register.blade.php +++ b/resources/views/register.blade.php @@ -1,15 +1,28 @@ + + + + Register + + +
@csrf
- +
- - + +
+ @if($errors->any()) +
{{ $errors->first() }}
+ @endif +
+ + diff --git a/routes/web.php b/routes/web.php index fc05718..6101fab 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,13 +3,18 @@ use App\Http\Controllers\PlayerController; use Illuminate\Support\Facades\Route; -Route::get('/', function () { - return view('welcome'); -}); +Route::view('/', 'welcome'); +Route::view('register', 'register'); +Route::view('login', 'login')->name('login'); + +Route::post('register', [PlayerController::class, 'register']); +Route::post('login', [PlayerController::class, 'login']); -Route::view('/register', 'register'); -Route::view('/login', 'login'); +Route::middleware('auth')->group(function () { + Route::get('dashboard', [PlayerController::class, 'profile']); + Route::get('admin', [PlayerController::class, 'admin']); -Route::post('/register', [PlayerController::class, 'register']); -Route::post('/login', [PlayerController::class, 'login']); -Route::post('/login/score', [PlayerController::class, 'score']); + Route::post('dashboard', [PlayerController::class, 'score']); + Route::post('admin', [PlayerController::class, 'admin_team']); + Route::post('logout', [PlayerController::class, 'logout']); +}); -- cgit v1.2.3