From ec69adab4483fe021e0fd3a4abd4b105870ad2d1 Mon Sep 17 00:00:00 2001 From: Override-6 Date: Fri, 8 Dec 2023 17:51:25 +0100 Subject: [PATCH] add basic api routes to get info on server, users and tactics --- public/api/index.php | 3 ++- sql/database.php | 17 +++++++++++++++++ sql/setup-tables.sql | 2 +- src/Api/API.php | 1 + src/Api/Controller/APIAccountsController.php | 6 ++++++ src/Api/Controller/APIAuthController.php | 2 +- src/Api/Controller/APIServerController.php | 2 ++ src/Api/Controller/APITacticController.php | 20 +++++++++++++------- src/App/App.php | 2 +- src/Core/Control.php | 2 ++ src/Core/Data/User.php | 2 +- src/Core/Gateway/AccountGateway.php | 3 ++- src/Core/Gateway/MemberGateway.php | 1 + src/Core/Model/AuthModel.php | 16 +++++++++++----- 14 files changed, 61 insertions(+), 18 deletions(-) diff --git a/public/api/index.php b/public/api/index.php index 226e8f1..e57872c 100644 --- a/public/api/index.php +++ b/public/api/index.php @@ -33,6 +33,7 @@ function getAccountController(): APIAccountsController { $con = new Connection(get_database()); $gw = new AccountGateway($con); return new APIAccountsController(new AuthModel($gw), $gw); + } function getServerController(): APIServerController { @@ -48,7 +49,6 @@ function getRoutes(): AltoRouter { $router->map("POST", "/auth", Action::noAuth(fn() => getAuthController()->authorize())); $router->map("POST", "/tactic/[i:id]/edit/name", Action::auth(fn(int $id, Account $acc) => getTacticController()->updateName($id, $acc))); $router->map("POST", "/tactic/[i:id]/save", Action::auth(fn(int $id, Account $acc) => getTacticController()->saveContent($id, $acc))); - $router->map("GET", "/admin/list-users", Action::noAuth(fn() => getAccountController()->listUsers($_GET))); $router->map("GET", "/admin/user/[i:id]", Action::noAuth(fn(int $id) => getAccountController()->getUser($id))); $router->map("GET", "/admin/user/[i:id]/space", Action::noAuth(fn(int $id) => getTacticController()->getUserTactics($id))); @@ -57,6 +57,7 @@ function getRoutes(): AltoRouter { $router->map("POST", "/admin/user/[i:id]/update", Action::noAuth(fn(int $id) => getAccountController()->updateUser($id))); $router->map("GET", "/admin/server-info", Action::noAuth(fn() => getServerController()->getServerInfo())); + return $router; } diff --git a/sql/database.php b/sql/database.php index 69b53e7..849d613 100644 --- a/sql/database.php +++ b/sql/database.php @@ -1,5 +1,9 @@ insertAccount($name, $email, AuthModel::generateToken(), password_hash("123456", PASSWORD_DEFAULT)); + $accounts->setIsAdmin($id, true); + } +} \ No newline at end of file diff --git a/sql/setup-tables.sql b/sql/setup-tables.sql index 77f2b3d..b904370 100644 --- a/sql/setup-tables.sql +++ b/sql/setup-tables.sql @@ -17,7 +17,7 @@ CREATE TABLE Account username varchar NOT NULL, token varchar UNIQUE NOT NULL, hash varchar NOT NULL, - profile_picture varchar NOT NULL + profile_picture varchar NOT NULL, ); CREATE TABLE Tactic diff --git a/src/Api/API.php b/src/Api/API.php index cc61c8d..6fd7b71 100644 --- a/src/Api/API.php +++ b/src/Api/API.php @@ -55,6 +55,7 @@ class API { } if ($action->getAuthType() == Action::AUTH_ADMIN && !$account->getUser()->isAdmin()) { + return new JsonHttpResponse([ValidationFail::unauthorized()], HttpCodes::UNAUTHORIZED); } } diff --git a/src/Api/Controller/APIAccountsController.php b/src/Api/Controller/APIAccountsController.php index 32fd956..7b70f7d 100644 --- a/src/Api/Controller/APIAccountsController.php +++ b/src/Api/Controller/APIAccountsController.php @@ -2,6 +2,7 @@ namespace IQBall\Api\Controller; + use IQBall\Api\APIControl; use IQBall\App\Control; use IQBall\Core\Data\Account; @@ -25,6 +26,7 @@ class APIAccountsController { public function __construct(AuthModel $model, AccountGateway $accounts) { $this->accounts = $accounts; $this->authModel = $model; + } @@ -47,6 +49,7 @@ class APIAccountsController { }); } + /** * @param int $userId * @return HttpResponse given user information. @@ -106,3 +109,6 @@ class APIAccountsController { }); } } + +} + diff --git a/src/Api/Controller/APIAuthController.php b/src/Api/Controller/APIAuthController.php index c715803..c8393d3 100644 --- a/src/Api/Controller/APIAuthController.php +++ b/src/Api/Controller/APIAuthController.php @@ -39,6 +39,6 @@ class APIAuthController { } return new JsonHttpResponse(["authorization" => $account->getToken()]); - }); + }, true); } } diff --git a/src/Api/Controller/APIServerController.php b/src/Api/Controller/APIServerController.php index 1c82d3e..e61e6b9 100644 --- a/src/Api/Controller/APIServerController.php +++ b/src/Api/Controller/APIServerController.php @@ -6,6 +6,7 @@ use IQBall\Core\Http\HttpResponse; use IQBall\Core\Http\JsonHttpResponse; class APIServerController { + private string $basePath; private \PDO $pdo; @@ -43,3 +44,4 @@ class APIServerController { } } + diff --git a/src/Api/Controller/APITacticController.php b/src/Api/Controller/APITacticController.php index 9f71212..fed5abf 100644 --- a/src/Api/Controller/APITacticController.php +++ b/src/Api/Controller/APITacticController.php @@ -15,13 +15,15 @@ use IQBall\Core\Validation\DefaultValidators; /** * API endpoint related to tactics */ -class APITacticController { +class APITacticController +{ private TacticModel $model; /** * @param TacticModel $model */ - public function __construct(TacticModel $model) { + public function __construct(TacticModel $model) + { $this->model = $model; } @@ -31,7 +33,8 @@ class APITacticController { * @param Account $account * @return HttpResponse */ - public function updateName(int $tactic_id, Account $account): HttpResponse { + public function updateName(int $tactic_id, Account $account): HttpResponse + { return APIControl::runChecked([ "name" => [DefaultValidators::lenBetween(1, 50), DefaultValidators::nameWithSpaces()], ], function (HttpRequest $request) use ($tactic_id, $account) { @@ -44,14 +47,15 @@ class APITacticController { } return HttpResponse::fromCode(HttpCodes::OK); - }); + }, true); } /** * @param int $id * @return HttpResponse */ - public function saveContent(int $id, Account $account): HttpResponse { + public function saveContent(int $id, Account $account): HttpResponse + { return APIControl::runChecked([ "content" => [], ], function (HttpRequest $req) use ($id) { @@ -60,7 +64,7 @@ class APITacticController { return new JsonHttpResponse([$fail], HttpCodes::BAD_REQUEST); } return HttpResponse::fromCode(HttpCodes::OK); - }); + }, true); } @@ -68,7 +72,8 @@ class APITacticController { * @param int $userId * @return HttpResponse given user information. */ - public function getUserTactics(int $userId): HttpResponse { + public function getUserTactics(int $userId): HttpResponse + { $tactics = $this->model->listAllOf($userId); $response = array_map(fn(TacticInfo $t) => [ @@ -76,6 +81,7 @@ class APITacticController { 'name' => $t->getName(), 'court' => $t->getCourtType(), 'creation_date' => $t->getCreationDate(), + ], $tactics); return new JsonHttpResponse($response); diff --git a/src/App/App.php b/src/App/App.php index 5f208bc..5140aa0 100644 --- a/src/App/App.php +++ b/src/App/App.php @@ -12,7 +12,6 @@ use Twig\Environment; use Twig\Error\LoaderError; use Twig\Error\RuntimeError; use Twig\Error\SyntaxError; -use Twig\Loader\FilesystemLoader; class App { /** @@ -90,6 +89,7 @@ class App { if ($action->getAuthType() == Action::AUTH_ADMIN && !$account->getUser()->isAdmin()) { return new JsonHttpResponse([ValidationFail::unauthorized()], HttpCodes::UNAUTHORIZED); } + } return $action->run($params, $session); diff --git a/src/Core/Control.php b/src/Core/Control.php index 106052d..7456202 100644 --- a/src/Core/Control.php +++ b/src/Core/Control.php @@ -15,6 +15,7 @@ class Control { * @param array $schema an array of `fieldName => DefaultValidators` which represents the request object schema * @param callable(HttpRequest): HttpResponse $run the callback to run if the request is valid according to the given schema. * The callback must accept an HttpRequest, and return an HttpResponse object. +<<<<<<< HEAD:src/Core/Control.php * @param ControlSchemaErrorResponseFactory $errorFactory an error factory to use if the request does not validate the required schema * @return HttpResponse */ @@ -35,6 +36,7 @@ class Control { * @param array $schema an array of `fieldName => DefaultValidators` which represents the request object schema * @param callable(HttpRequest): HttpResponse $run the callback to run if the request is valid according to the given schema. * The callback must accept an HttpRequest, and return an HttpResponse object. +<<<<<<< HEAD:src/Core/Control.php * @param ControlSchemaErrorResponseFactory $errorFactory an error factory to use if the request does not validate the required schema * @return HttpResponse */ diff --git a/src/Core/Data/User.php b/src/Core/Data/User.php index 02a44c0..8471929 100644 --- a/src/Core/Data/User.php +++ b/src/Core/Data/User.php @@ -24,7 +24,7 @@ class User implements \JsonSerializable { private string $profilePicture; /** - * @var bool isAdmin + * @var bool true if the user is an administrator */ private bool $isAdmin; diff --git a/src/Core/Gateway/AccountGateway.php b/src/Core/Gateway/AccountGateway.php index 6752b01..1a0c689 100644 --- a/src/Core/Gateway/AccountGateway.php +++ b/src/Core/Gateway/AccountGateway.php @@ -47,7 +47,6 @@ class AccountGateway { return !empty($result); } - /** * promote or demote a user to server administrator * @param int $id @@ -60,6 +59,7 @@ class AccountGateway { } else { $stmnt = $this->con->prepare("DELETE FROM Admins WHERE id = :id"); } + $stmnt->bindValue(':id', $id); $stmnt->execute(); @@ -155,6 +155,7 @@ class AccountGateway { ] ); return array_map(fn(array $acc) => new Account($acc["token"], new User($acc["email"], $acc["username"], $acc["id"], $acc["profile_picture"], $this->isAdmin($acc["id"]))), $res); + } /** diff --git a/src/Core/Gateway/MemberGateway.php b/src/Core/Gateway/MemberGateway.php index 98d2d41..f79ff60 100644 --- a/src/Core/Gateway/MemberGateway.php +++ b/src/Core/Gateway/MemberGateway.php @@ -47,6 +47,7 @@ class MemberGateway { ] ); return array_map(fn($row) => new Member(new User($row['email'], $row['username'], $row['id'], $row['profile_picture'], $row['is_admin']), $teamId, $row['role']), $rows); + } /** diff --git a/src/Core/Model/AuthModel.php b/src/Core/Model/AuthModel.php index e1fc1bb..034e210 100644 --- a/src/Core/Model/AuthModel.php +++ b/src/Core/Model/AuthModel.php @@ -28,11 +28,16 @@ class AuthModel { * @param string $email * @return Account|null the registered account or null if the account already exists for the given email address */ - public function register( - string $username, - string $password, - string $email - ): ?Account { + + public function register(string $username, + string $password, + string $confirmPassword, + string $email, + array &$failures): ?Account { + + if ($password != $confirmPassword) { + $failures[] = new FieldValidationFail("confirmpassword", "Le mot de passe et la confirmation ne sont pas les mêmes."); + } if ($this->gateway->exists($email)) { return null; } @@ -53,6 +58,7 @@ class AuthModel { } catch (Exception $e) { throw new \RuntimeException($e); } + } /**