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/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php index 6a1395d6..0a1d98b6 100644 --- a/app/Http/Controllers/Admin/ServerController.php +++ b/app/Http/Controllers/Admin/ServerController.php @@ -114,7 +114,7 @@ class ServerController extends Controller */ public function dataTable(Request $request) { - $query = Server::with(['user', 'product', 'egg']); + $query = Server::with(['user', 'product']); if ($request->has('product')) $query->where('product_id', '=', $request->input('product')); if ($request->has('user')) $query->where('user_id', '=', $request->input('user')); $query->select('servers.*'); diff --git a/app/Http/Controllers/Api/ServerController.php b/app/Http/Controllers/Api/ServerController.php new file mode 100644 index 00000000..fcfa1b14 --- /dev/null +++ b/app/Http/Controllers/Api/ServerController.php @@ -0,0 +1,83 @@ +paginate($request->query('per_page') ?? 50); + } + + + /** + * Display the specified resource. + * + * @param Server $server + * @return Server + */ + public function show(Server $server) + { + return $server->load('product'); + } + + + /** + * Remove the specified resource from storage. + * + * @param Server $server + * @return Server + */ + public function destroy(Server $server) + { + $server->delete(); + return $server; + } + + + /** + * suspend server + * @param Server $server + * @return Server|JsonResponse + */ + public function suspend(Server $server) + { + try { + $server->suspend(); + } catch (Exception $exception) { + return response()->json(['message' => $exception->getMessage()], 500); + } + + return $server->load('product'); + } + + + /** + * unsuspend server + * @param Server $server + * @return Server|JsonResponse + */ + public function unSuspend(Server $server) + { + try { + $server->unSuspend(); + } catch (Exception $exception) { + return response()->json(['message' => $exception->getMessage()], 500); + } + + return $server->load('product'); + } +} diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 8eb05a0a..7c905328 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -1,79 +1,80 @@ 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. + * + * @param Request $request + * @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/app/Models/Server.php b/app/Models/Server.php index ea83d856..d6f5e178 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -30,7 +30,7 @@ class Server extends Model /** * @var string[] */ - protected static $ignoreChangedAttributes = ['pterodactyl_id' , 'identifier' , 'updated_at']; + protected static $ignoreChangedAttributes = ['pterodactyl_id', 'identifier', 'updated_at']; /** * @var string[] @@ -59,16 +59,17 @@ class Server extends Model /** * */ - public static function boot() { + public static function boot() + { parent::boot(); - static::creating(function(Server $server) { + static::creating(function (Server $server) { $client = new Client(); $server->{$server->getKeyName()} = $client->generateId($size = 21); }); - static::deleting(function(Server $server) { + static::deleting(function (Server $server) { Pterodactyl::client()->delete("/application/servers/{$server->pterodactyl_id}"); }); } @@ -76,7 +77,8 @@ class Server extends Model /** * @return bool */ - public function isSuspended(){ + public function isSuspended() + { return !is_null($this->suspended); } @@ -84,7 +86,8 @@ class Server extends Model /** * @return PromiseInterface|Response */ - public function getPterodactylServer(){ + public function getPterodactylServer() + { return Pterodactyl::client()->get("/application/servers/{$this->pterodactyl_id}"); } @@ -92,7 +95,8 @@ class Server extends Model * * @throws Exception */ - public function suspend(){ + public function suspend() + { $response = Pterodactyl::suspendServer($this); if ($response->successful()) { @@ -120,40 +124,20 @@ class Server extends Model return $this; } - /** * @return HasOne */ - public function product(){ - return $this->hasOne(Product::class , 'id' , 'product_id'); - } - - /** - * @return HasOne - */ - public function nest(){ - return $this->hasOne(Nest::class , 'id' , 'nest_id'); - } - - /** - * @return HasOne - */ - public function egg(){ - return $this->hasOne(Egg::class , 'id' , 'egg_id'); - } - - /** - * @return HasOne - */ - public function location(){ - return $this->hasOne(Location::class , 'id' , 'location_id'); + public function product() + { + return $this->hasOne(Product::class, 'id', 'product_id'); } /** * @return BelongsTo */ - public function user(){ - return $this->belongsTo(User::class , 'user_id' , 'id'); + public function user() + { + return $this->belongsTo(User::class, 'user_id', 'id'); } } 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 @@ + +