More Facades, User delete

This commit is contained in:
Kilian Hofmann 2024-07-22 00:56:04 +02:00
parent 4b89a7e9ca
commit 7b897071f5
14 changed files with 177 additions and 63 deletions

View File

@ -3,9 +3,12 @@
namespace Api\Login; namespace Api\Login;
use Exception; use Exception;
use Khofmann\Api\Api;
use Khofmann\Input\Input; use Khofmann\Input\Input;
use Khofmann\Response\Response;
use Khofmann\Models\User\User;
class Login class Login extends Api
{ {
public function post() public function post()
{ {
@ -15,8 +18,7 @@ class Login
if (empty($password)) throw new Exception("Missing Password", 400); if (empty($password)) throw new Exception("Missing Password", 400);
try { try {
$response = \Khofmann\Models\User\User::logIn($email, $password); return Response::json(User::logIn($email, $password));
return json_encode($response);
} catch (Exception $err) { } catch (Exception $err) {
switch ($err->getMessage()) { switch ($err->getMessage()) {
case "Failed": case "Failed":

View File

@ -2,13 +2,16 @@
namespace Api\Logout; namespace Api\Logout;
use Khofmann\Api\Api;
use \Khofmann\Models\User\User; use \Khofmann\Models\User\User;
use Khofmann\Request\Request;
use Khofmann\Response\Response;
class Logout class Logout extends Api
{ {
public function post() public function post()
{ {
$token = request()->getHeader("token"); $token = Request::header("token");
return json_decode(User::getByToken($token)->logOut()); return Response::json(User::getByToken($token)->logOut());
} }
} }

View File

@ -5,13 +5,16 @@ namespace Api\User;
use Exception; use Exception;
use Khofmann\Models\User\User as MUser; use Khofmann\Models\User\User as MUser;
use Khofmann\Input\Input; use Khofmann\Input\Input;
use Khofmann\Response\Response;
use Khofmann\Api\Api;
use Khofmann\Request\Request;
class User class User extends Api
{ {
public function get($id) public function get($id)
{ {
try { try {
return json_encode(MUser::getByID($id)); return Response::json(MUser::getByID($id));
} catch (Exception $err) { } catch (Exception $err) {
switch ($err->getMessage()) { switch ($err->getMessage()) {
case "NotFound": case "NotFound":
@ -22,14 +25,14 @@ class User
} }
} }
public function post($id) public function patch($id)
{ {
$username = Input::post("username"); $username = Input::patch("username");
$password = Input::post("password"); $password = Input::patch("password");
$image = Input::file("image"); $image = Input::file("image");
try { try {
return json_encode(MUser::getByID($id)->update($username, $password, $image)); return Response::json(MUser::getByID($id)->update($username, $password, $image));
} catch (Exception $err) { } catch (Exception $err) {
switch ($err->getMessage()) { switch ($err->getMessage()) {
case "NotFound": case "NotFound":
@ -46,15 +49,15 @@ class User
} }
} }
public function postSelf() public function patchSelf()
{ {
$token = Input::header("token"); $token = Request::header("token");
$username = Input::post("username"); $username = Input::patch("username");
$password = Input::post("password"); $password = Input::patch("password");
$image = Input::file("image"); $image = Input::file("image");
try { try {
return json_encode(MUser::getByToken($token)->update($username, $password, $image)); return Response::json(MUser::getByToken($token)->update($username, $password, $image));
} catch (Exception $err) { } catch (Exception $err) {
switch ($err->getMessage()) { switch ($err->getMessage()) {
case "NotFound": case "NotFound":
@ -70,4 +73,18 @@ class User
} }
} }
} }
public function delete($id)
{
try {
return Response::json(MUser::getByID($id)->delete());
} catch (Exception $err) {
switch ($err->getMessage()) {
case "NotFound":
throw new Exception("User not Found", 404);
default:
throw $err;
}
}
}
} }

View File

@ -126,12 +126,12 @@ paths:
value: { "message": "User not Found" } value: { "message": "User not Found" }
tags: tags:
- User - User
post: patch:
summary: Update user summary: Update user
description: description:
Update user with ID. Fields are updated in order username, password, image. If one fails, subsequent are not updated. <br> Update user with ID. Fields are updated in order username, password, image. If one fails, subsequent are not updated. <br>
Use special ID <code>self</code> to update logged in user. <br> Use special ID <code>self</code> to update logged in user. <br>
Requires logged in user to have admin permissions for any ID other than <code>self</code>. <br> Requires logged in user to have admin permissions for any ID other than <code>self</code>.
security: security:
- BasicAuth: [] - BasicAuth: []
parameters: parameters:
@ -177,17 +177,48 @@ paths:
value: { "message": "Failed to update username" } value: { "message": "Failed to update username" }
tags: tags:
- User - User
delete:
summary: Delete user
description: Delete user with ID. <br>
Requires logged in user to have admin permissions.
security:
- BasicAuth: []
parameters:
- name: id
in: path
description: User ID
required: true
schema:
type: integer
format: int14
responses:
200:
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/BooleanResponse"
examples:
Success:
value: true
404:
description: User not Found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
User not Found:
value: { "message": "User not Found" }
tags:
- User
externalDocs: externalDocs:
url: https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/docs/ url: https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/docs/
security: [] security: []
servers: servers:
- url: https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/ - url: https://khofmann.userpage.fu-berlin.de/phpCourse/exam/api/
description: ""
variables: {}
components: components:
links: {}
callbacks: {}
schemas: schemas:
BooleanResponse: BooleanResponse:
type: boolean type: boolean

File diff suppressed because one or more lines are too long

13
exam/classes/Api/Api.php Normal file
View File

@ -0,0 +1,13 @@
<?php
namespace Khofmann\Api;
use Khofmann\Response\Response;
class Api
{
public function __construct()
{
Response::response()->header("Cache-control: no-cache");
}
}

View File

@ -6,6 +6,7 @@ use Exception;
use Pecee\Http\Middleware\IMiddleware; use Pecee\Http\Middleware\IMiddleware;
use Pecee\Http\Request; use Pecee\Http\Request;
use Khofmann\Models\User\User; use Khofmann\Models\User\User;
use Khofmann\Response\Response;
class AdminAuth implements IMiddleware class AdminAuth implements IMiddleware
{ {
@ -15,17 +16,17 @@ class AdminAuth implements IMiddleware
// No token // No token
if ($token === null) { if ($token === null) {
response()->httpCode(401)->json(["message" => "Not Authorized"]); Response::response()->httpCode(401)->json(["message" => "Not Authorized"]);
} }
try { try {
$user = User::getByToken($token); $user = User::getByToken($token);
if (!$user->getIsAdmin()) { if (!$user->getIsAdmin()) {
response()->httpCode(401)->json(["message" => "Not Authorized"]); Response::response()->httpCode(401)->json(["message" => "Not Authorized"]);
} }
} catch (Exception $err) { } catch (Exception $err) {
// No user with this token exists // No user with this token exists
response()->httpCode(401)->json(["message" => "Not Authorized"]); Response::response()->httpCode(401)->json(["message" => "Not Authorized"]);
} }
} }
} }

View File

@ -6,6 +6,7 @@ use Exception;
use Pecee\Http\Middleware\IMiddleware; use Pecee\Http\Middleware\IMiddleware;
use Pecee\Http\Request; use Pecee\Http\Request;
use Khofmann\Models\User\User; use Khofmann\Models\User\User;
use Khofmann\Response\Response;
class Auth implements IMiddleware class Auth implements IMiddleware
{ {
@ -15,14 +16,14 @@ class Auth implements IMiddleware
// No token // No token
if ($token === null) { if ($token === null) {
response()->httpCode(401)->json(["message" => "Not Authorized"]); Response::response()->httpCode(401)->json(["message" => "Not Authorized"]);
} }
try { try {
User::getByToken($token); User::getByToken($token);
} catch (Exception $err) { } catch (Exception $err) {
// No user with this token exists // No user with this token exists
response()->httpCode(401)->json(["message" => "Not Authorized"]); Response::response()->httpCode(401)->json(["message" => "Not Authorized"]);
} }
} }
} }

View File

@ -2,25 +2,29 @@
namespace Khofmann\Input; namespace Khofmann\Input;
use Khofmann\Request\Request;
class Input class Input
{ {
public static function header($name, $defaultValue = null, $tryParse = true)
{
return request()->getHeader($name, $defaultValue, $tryParse);
}
public static function post($index, $defaultValue = null) public static function post($index, $defaultValue = null)
{ {
return request()->getInputHandler()->post($index, $defaultValue); return Request::request()->getInputHandler()->post($index, $defaultValue);
}
public static function patch($index, $defaultValue = null)
{
return Request::request()->getInputHandler()->post($index, $defaultValue);
} }
public static function get($index, $defaultValue = null) public static function get($index, $defaultValue = null)
{ {
return request()->getInputHandler()->get($index, $defaultValue); return Request::request()->getInputHandler()->get($index, $defaultValue);
} }
public static function file($index, $defaultValue = null) public static function file($index, $defaultValue = null)
{ {
return request()->getInputHandler()->file($index, $defaultValue); return Request::request()->getInputHandler()->file($index, $defaultValue);
} }
} }

View File

@ -18,8 +18,9 @@ class User implements JsonSerializable
private ?string $image; private ?string $image;
private bool $isAdmin; private bool $isAdmin;
private DateTime $memberSince; private DateTime $memberSince;
private int $postCount;
protected function __construct(int $id, string $username, int $status, string $email, string $timestamp, string $image, bool $isAdmin) protected function __construct(int $id, string $username, int $status, string $email, string $timestamp, ?string $image, bool $isAdmin)
{ {
$this->id = $id; $this->id = $id;
$this->username = $username; $this->username = $username;
@ -171,6 +172,14 @@ class User implements JsonSerializable
return true; return true;
} }
public function delete()
{
$db = Database::getInstance();
$stmt = $db->prepare("DELETE FROM egb_benutzer WHERE id = :ID");
$stmt->bindValue(":ID", $this->id);
return $stmt->execute();
}
/* /*
* Getters * Getters
*/ */

View File

@ -0,0 +1,19 @@
<?php
namespace Khofmann\Request;
use Pecee\Http\Request as PRequest;
use Pecee\SimpleRouter\SimpleRouter;
class Request
{
public static function request(): PRequest
{
return SimpleRouter::request();
}
public static function header($name, $defaultValue = null, $tryParse = true)
{
return request()->getHeader($name, $defaultValue, $tryParse);
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Khofmann\Response;
use Pecee\SimpleRouter\SimpleRouter;
use Pecee\Http\Response as PResponse;
class Response
{
public static function response(): PResponse
{
return SimpleRouter::response();
}
public static function json($value, int $options = 0, int $dept = 512)
{
return SimpleRouter::response()->json($value, $options, $dept);
}
}

View File

@ -2,10 +2,11 @@
// Namespaces // Namespaces
use Pecee\SimpleRouter\SimpleRouter; use Pecee\SimpleRouter\SimpleRouter;
use Pecee\Http\Request; use Pecee\Http\Request;
use Khofmann\Response\Response;
// Error handling // Error handling
SimpleRouter::error(function (Request $request, Exception $exception) { SimpleRouter::error(function (Request $request, Exception $exception) {
$code = $exception->getCode(); $code = $exception->getCode();
response()->httpCode(is_int($code) ? $code : 500)->json(["message" => $exception->getMessage()]); Response::response()->httpCode(is_int($code) ? $code : 500)->json(["message" => $exception->getMessage()]);
}); });
// Index // Index
SimpleRouter::all("/", function () { SimpleRouter::all("/", function () {
@ -26,12 +27,14 @@ SimpleRouter::group(["middleware" => \Khofmann\Auth\Auth::class], function () {
// Get any user // Get any user
SimpleRouter::get("/user/{id}", [Api\User\User::class, "get"]); SimpleRouter::get("/user/{id}", [Api\User\User::class, "get"]);
// Update self // Update self
SimpleRouter::post("/user/self", [Api\User\User::class, "postSelf"]); SimpleRouter::patch("/user/self", [Api\User\User::class, "patchSelf"]);
}); });
/* /*
* Admin Auth routes * Admin Auth routes
*/ */
SimpleRouter::group(["middleware" => \Khofmann\Auth\AdminAuth::class], function () { SimpleRouter::group(["middleware" => \Khofmann\Auth\AdminAuth::class], function () {
// Update any user // Update any user
SimpleRouter::post("/user/{id}", [Api\User\User::class, "post"]); SimpleRouter::patch("/user/{id}", [Api\User\User::class, "patch"]);
// Delete any user
SimpleRouter::delete("/user/{id}", [Api\User\User::class, "delete"]);
}); });

View File

@ -2,8 +2,6 @@
use Pecee\SimpleRouter\SimpleRouter as Router; use Pecee\SimpleRouter\SimpleRouter as Router;
use Pecee\Http\Url; use Pecee\Http\Url;
use Pecee\Http\Response;
use Pecee\Http\Request;
/** /**
* Get url for a route by using either name/alias, class or method name. * Get url for a route by using either name/alias, class or method name.
@ -28,22 +26,6 @@ function url(?string $name = null, $parameters = null, ?array $getParams = null)
return Router::getUrl($name, $parameters, $getParams); return Router::getUrl($name, $parameters, $getParams);
} }
/**
* @return \Pecee\Http\Response
*/
function response(): Response
{
return Router::response();
}
/**
* @return \Pecee\Http\Request
*/
function request(): Request
{
return Router::request();
}
/** /**
* @param string $url * @param string $url
* @param int|null $code * @param int|null $code