From ecc3c66589b409c27c52265e5029bae6307ca8a9 Mon Sep 17 00:00:00 2001 From: Arno Date: Sun, 6 Jun 2021 20:22:40 +0200 Subject: [PATCH 1/4] WIP added api keys and user api endpoint --- .../Admin/ApplicationApiController.php | 141 ++++++++++++++++ app/Http/Controllers/Api/UserController.php | 156 +++++++++--------- .../Controllers/Auth/RegisterController.php | 2 +- app/Http/Kernel.php | 4 +- app/Http/Middleware/ApiAuthToken.php | 25 +++ app/Models/ApplicationApi.php | 35 ++++ database/factories/ApplicationApiFactory.php | 28 ++++ ...6_144120_create_application_apis_table.php | 33 ++++ resources/views/admin/api/create.blade.php | 63 +++++++ resources/views/admin/api/edit.blade.php | 64 +++++++ resources/views/admin/api/index.blade.php | 87 ++++++++++ resources/views/layouts/main.blade.php | 8 + routes/api.php | 8 +- routes/web.php | 6 + 14 files changed, 577 insertions(+), 83 deletions(-) create mode 100644 app/Http/Controllers/Admin/ApplicationApiController.php create mode 100644 app/Http/Middleware/ApiAuthToken.php create mode 100644 app/Models/ApplicationApi.php create mode 100644 database/factories/ApplicationApiFactory.php create mode 100644 database/migrations/2021_06_06_144120_create_application_apis_table.php create mode 100644 resources/views/admin/api/create.blade.php create mode 100644 resources/views/admin/api/edit.blade.php create mode 100644 resources/views/admin/api/index.blade.php diff --git a/app/Http/Controllers/Admin/ApplicationApiController.php b/app/Http/Controllers/Admin/ApplicationApiController.php new file mode 100644 index 00000000..e091605a --- /dev/null +++ b/app/Http/Controllers/Admin/ApplicationApiController.php @@ -0,0 +1,141 @@ +validate([ + 'memo' => 'nullable|string|max:60' + ]); + + ApplicationApi::create([ + 'memo' => $request->input('memo') + ]); + + return redirect()->route('admin.api.index')->with('success', 'api key created!'); + } + + /** + * Display the specified resource. + * + * @param ApplicationApi $applicationApi + * @return Response + */ + public function show(ApplicationApi $applicationApi) + { + // + } + + /** + * Show the form for editing the specified resource. + * + * @param ApplicationApi $applicationApi + * @return Application|Factory|View|Response + */ + public function edit(ApplicationApi $applicationApi) + { + return view('admin.api.edit' , [ + 'applicationApi' => $applicationApi + ]); + } + + /** + * Update the specified resource in storage. + * + * @param Request $request + * @param ApplicationApi $applicationApi + * @return RedirectResponse + */ + public function update(Request $request, ApplicationApi $applicationApi) + { + $request->validate([ + 'memo' => 'nullable|string|max:60' + ]); + + $applicationApi->update($request->all()); + + return redirect()->route('admin.api.index')->with('success', 'api key updated!'); + } + + /** + * Remove the specified resource from storage. + * + * @param ApplicationApi $applicationApi + * @return RedirectResponse + */ + public function destroy(ApplicationApi $applicationApi) + { + $applicationApi->delete(); + return redirect()->back()->with('success', 'api key has been removed!'); + } + + /** + * @param Request $request + * @return JsonResponse|mixed + * @throws Exception + */ + public function dataTable(Request $request) + { + $query = ApplicationApi::query(); + + return datatables($query) + ->addColumn('actions', function (ApplicationApi $apiKey) { + return ' + +
+ ' . csrf_field() . ' + ' . method_field("DELETE") . ' + +
+ '; + }) + ->editColumn('token' , function (ApplicationApi $apiKey) { + return "{$apiKey->token}"; + }) + ->editColumn('last_used' , function (ApplicationApi $apiKey) { + return $apiKey->last_used ? $apiKey->last_used->diffForHumans() : ''; + }) + ->rawColumns(['actions' , 'token']) + ->make(); + } +} diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 8eb05a0a..242a4f43 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -1,79 +1,79 @@ query('per_page') ?? 50); -// } -// -// -// /** -// * Display the specified resource. -// * -// * @param int $id -// * @return User -// */ -// public function show(int $id) -// { -// $discordUser = DiscordUser::find($id); -// return $discordUser ? $discordUser->user : User::findOrFail($id); -// } -// -// -// /** -// * Update the specified resource in storage. -// * -// * @param Request $request -// * @param int $id -// * @return User -// */ -// public function update(Request $request, int $id) -// { -// $discordUser = DiscordUser::find($id); -// $user = $discordUser ? $discordUser->user : User::findOrFail($id); -// -// $request->validate([ -// "name" => "sometimes|string|min:4|max:30", -// "email" => "sometimes|string|email", -// "credits" => "sometimes|numeric|min:0|max:1000000", -// "server_limit" => "sometimes|numeric|min:0|max:1000000", -// "role" => ['sometimes', Rule::in(['admin', 'mod', 'client', 'member'])], -// ]); -// -// $user->update($request->all()); -// -// return $user; -// } -// -// /** -// * Remove the specified resource from storage. -// * -// * @param int $id -// * @return Application|ResponseFactory|Response|void -// */ -// public function destroy(int $id) -// { -// $discordUser = DiscordUser::find($id); -// $user = $discordUser ? $discordUser->user : User::findOrFail($id); -// -// $user->delete(); -// return response($user, 200); -// } -//} + +namespace App\Http\Controllers\Api; + +use App\Http\Controllers\Controller; +use App\Models\DiscordUser; +use App\Models\User; +use Illuminate\Contracts\Foundation\Application; +use Illuminate\Contracts\Routing\ResponseFactory; +use Illuminate\Http\Request; +use Illuminate\Http\Response; +use Illuminate\Validation\Rule; + +class UserController extends Controller +{ + /** + * Display a listing of the resource. + * + * @return Response + */ + public function index(Request $request) + { + return User::paginate($request->query('per_page') ?? 50); + } + + + /** + * Display the specified resource. + * + * @param int $id + * @return User + */ + public function show(int $id) + { + $discordUser = DiscordUser::find($id); + return $discordUser ? $discordUser->user : User::findOrFail($id); + } + + + /** + * Update the specified resource in storage. + * + * @param Request $request + * @param int $id + * @return User + */ + public function update(Request $request, int $id) + { + $discordUser = DiscordUser::find($id); + $user = $discordUser ? $discordUser->user : User::findOrFail($id); + + $request->validate([ + "name" => "sometimes|string|min:4|max:30", + "email" => "sometimes|string|email", + "credits" => "sometimes|numeric|min:0|max:1000000", + "server_limit" => "sometimes|numeric|min:0|max:1000000", + "role" => ['sometimes', Rule::in(['admin', 'mod', 'client', 'member'])], + ]); + + $user->update($request->all()); + + return $user; + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * @return Application|ResponseFactory|Response|void + */ + public function destroy(int $id) + { + $discordUser = DiscordUser::find($id); + $user = $discordUser ? $discordUser->user : User::findOrFail($id); + + $user->delete(); + return response($user, 200); + } +} diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 346b0e3e..5d99fdb7 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -58,7 +58,7 @@ class RegisterController extends Controller //check if registered cookie exists as extra defense if (isset($_COOKIE['4b3403665fea6'])) { - $data['registered'] = true; + $data['registered'] = env('APP_ENV') == 'local' ? false : true; } return Validator::make($data, [ diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 9954cecb..5e7b9418 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -2,6 +2,7 @@ namespace App\Http; +use App\Http\Middleware\ApiAuthToken; use App\Http\Middleware\isAdmin; use App\Http\Middleware\LastSeen; use Illuminate\Foundation\Http\Kernel as HttpKernel; @@ -65,6 +66,7 @@ class Kernel extends HttpKernel 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, - 'admin' => isAdmin::class + 'admin' => isAdmin::class, + 'api.token' => ApiAuthToken::class ]; } diff --git a/app/Http/Middleware/ApiAuthToken.php b/app/Http/Middleware/ApiAuthToken.php new file mode 100644 index 00000000..2e556538 --- /dev/null +++ b/app/Http/Middleware/ApiAuthToken.php @@ -0,0 +1,25 @@ +bearerToken()); + if (is_null($token)) return response()->json(['message' => 'Invalid Authorization token'], 401); + $token->updateLastUsed(); + return $next($request); + } +} diff --git a/app/Models/ApplicationApi.php b/app/Models/ApplicationApi.php new file mode 100644 index 00000000..799cb110 --- /dev/null +++ b/app/Models/ApplicationApi.php @@ -0,0 +1,35 @@ +{$applicationApi->getKeyName()} = $client->generateId(48); + }); + } + + public function updateLastUsed(){ + $this->update(['last_used' => now()]); + } +} diff --git a/database/factories/ApplicationApiFactory.php b/database/factories/ApplicationApiFactory.php new file mode 100644 index 00000000..e53ba4e5 --- /dev/null +++ b/database/factories/ApplicationApiFactory.php @@ -0,0 +1,28 @@ +string('token')->unique()->primary(); + $table->string('memo')->nullable(); + $table->timestamp('last_used')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('application_apis'); + } +} diff --git a/resources/views/admin/api/create.blade.php b/resources/views/admin/api/create.blade.php new file mode 100644 index 00000000..300d0754 --- /dev/null +++ b/resources/views/admin/api/create.blade.php @@ -0,0 +1,63 @@ +@extends('layouts.main') + +@section('content') + +
+
+
+
+

Application API

+
+ +
+
+
+ + + +
+
+ +
+
+
+
+
+ @csrf + +
+ + + @error('memo') +
+ {{$message}} +
+ @enderror +
+ +
+ +
+
+
+
+
+
+ +
+
+ + + + +@endsection diff --git a/resources/views/admin/api/edit.blade.php b/resources/views/admin/api/edit.blade.php new file mode 100644 index 00000000..62f82d02 --- /dev/null +++ b/resources/views/admin/api/edit.blade.php @@ -0,0 +1,64 @@ +@extends('layouts.main') + +@section('content') + +
+
+
+
+

Application API

+
+ +
+
+
+ + + +
+
+ +
+
+
+
+
+ @csrf + @method('PATCH') + +
+ + + @error('memo') +
+ {{$message}} +
+ @enderror +
+ +
+ +
+
+
+
+
+
+ +
+
+ + + + +@endsection diff --git a/resources/views/admin/api/index.blade.php b/resources/views/admin/api/index.blade.php new file mode 100644 index 00000000..6c56fcf8 --- /dev/null +++ b/resources/views/admin/api/index.blade.php @@ -0,0 +1,87 @@ +@extends('layouts.main') + +@section('content') + +
+
+
+
+

Application API

+
+ +
+
+
+ + + +
+
+ +
+ +
+
+
Application API
+ Create new +
+
+ +
+ + + + + + + + + + + + +
TokenMemoLast used
+ +
+
+ + +
+ +
+ + + + + + +@endsection diff --git a/resources/views/layouts/main.blade.php b/resources/views/layouts/main.blade.php index 6d1d649f..bb82083c 100644 --- a/resources/views/layouts/main.blade.php +++ b/resources/views/layouts/main.blade.php @@ -218,6 +218,14 @@ + +