|
|
|
@ -6,32 +6,134 @@ require "../../sql/database.php";
|
|
|
|
|
require "../utils.php";
|
|
|
|
|
|
|
|
|
|
use App\Connexion;
|
|
|
|
|
use App\Controller\Api\APIAuthController;
|
|
|
|
|
use App\Controller\Api\APITacticController;
|
|
|
|
|
use App\Data\Account;
|
|
|
|
|
use App\Gateway\AccountGateway;
|
|
|
|
|
use App\Gateway\TacticInfoGateway;
|
|
|
|
|
use App\Http\HttpResponse;
|
|
|
|
|
use App\Http\JsonHttpResponse;
|
|
|
|
|
use App\Http\ViewHttpResponse;
|
|
|
|
|
use App\Model\AuthModel;
|
|
|
|
|
use App\Model\TacticModel;
|
|
|
|
|
use App\Session\SessionHandle;
|
|
|
|
|
use App\Validation\ValidationFail;
|
|
|
|
|
|
|
|
|
|
$con = new Connexion(get_database());
|
|
|
|
|
function getTacticController(): APITacticController {
|
|
|
|
|
return new APITacticController(new TacticModel(new TacticInfoGateway(new Connexion(get_database()))));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getAuthController(): APIAuthController {
|
|
|
|
|
return new APIAuthController(new AuthModel(new AccountGateway(new Connexion(get_database()))));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Action {
|
|
|
|
|
/**
|
|
|
|
|
* @var callable(mixed[]): HttpResponse $action action to call
|
|
|
|
|
*/
|
|
|
|
|
private $action;
|
|
|
|
|
|
|
|
|
|
private bool $isAuthRequired;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param callable(mixed[]): HttpResponse $action
|
|
|
|
|
*/
|
|
|
|
|
private function __construct(callable $action, bool $isAuthRequired) {
|
|
|
|
|
$this->action = $action;
|
|
|
|
|
$this->isAuthRequired = $isAuthRequired;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function isAuthRequired(): bool {
|
|
|
|
|
return $this->isAuthRequired;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param mixed[] $params
|
|
|
|
|
* @param ?Account $account
|
|
|
|
|
* @return HttpResponse
|
|
|
|
|
*/
|
|
|
|
|
public function run(array $params, ?Account $account): HttpResponse {
|
|
|
|
|
$params = array_values($params);
|
|
|
|
|
if ($this->isAuthRequired) {
|
|
|
|
|
if ($account == null) {
|
|
|
|
|
throw new Exception("action requires authorization.");
|
|
|
|
|
}
|
|
|
|
|
$params[] = $account;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return call_user_func_array($this->action, $params);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param callable(mixed[]): HttpResponse $action
|
|
|
|
|
* @return Action an action that does not require to have an authorization.
|
|
|
|
|
*/
|
|
|
|
|
public static function noAuth(callable $action): Action {
|
|
|
|
|
return new Action($action, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param callable(mixed[]): HttpResponse $action
|
|
|
|
|
* @return Action an action that does require to have an authorization.
|
|
|
|
|
*/
|
|
|
|
|
public static function auth(callable $action): Action {
|
|
|
|
|
return new Action($action, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param mixed[] $match
|
|
|
|
|
* @return HttpResponse
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
function handleMatch(array $match): HttpResponse {
|
|
|
|
|
if (!$match) {
|
|
|
|
|
return new JsonHttpResponse([ValidationFail::notFound("not found")]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$action = $match['target'];
|
|
|
|
|
if (!$action instanceof Action) {
|
|
|
|
|
throw new Exception("routed action is not an Action object.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$auth = null;
|
|
|
|
|
|
|
|
|
|
if ($action->isAuthRequired()) {
|
|
|
|
|
$auth = tryGetAuthAccount();
|
|
|
|
|
if ($auth == null) {
|
|
|
|
|
return new JsonHttpResponse([ValidationFail::unauthorized("Missing or invalid 'Authorization' header")]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $action->run($match['params'], $auth);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function tryGetAuthAccount(): ?Account {
|
|
|
|
|
$headers = getallheaders();
|
|
|
|
|
|
|
|
|
|
// If no authorization header is set, try fallback to php session.
|
|
|
|
|
if (!isset($headers['Authorization'])) {
|
|
|
|
|
$session = SessionHandle::init();
|
|
|
|
|
return $session->getAccount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$token = $headers['Authorization'];
|
|
|
|
|
$gateway = new AccountGateway(new Connexion(get_database()));
|
|
|
|
|
return $gateway->getAccountFromToken($token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$router = new AltoRouter();
|
|
|
|
|
$router->setBasePath(get_public_path() . "/api");
|
|
|
|
|
|
|
|
|
|
$tacticEndpoint = new APITacticController(new TacticModel(new TacticInfoGateway($con)));
|
|
|
|
|
$router->map("POST", "/tactic/[i:id]/edit/name", fn(int $id) => $tacticEndpoint->updateName($id));
|
|
|
|
|
$router->map("GET", "/tactic/[i:id]", fn(int $id) => $tacticEndpoint->getTacticInfo($id));
|
|
|
|
|
$router->map("POST", "/tactic/new", fn() => $tacticEndpoint->newTactic());
|
|
|
|
|
$router->map("POST", "/tactic/[i:id]/edit/name", Action::auth(fn(int $id, Account $acc) => getTacticController()->updateName($id, $acc)));
|
|
|
|
|
$router->map("GET", "/tactic/[i:id]", Action::auth(fn(int $id, Account $acc) => getTacticController()->getTacticInfo($id, $acc)));
|
|
|
|
|
$router->map("POST", "/tactic/new", Action::auth(fn(Account $acc) => getTacticController()->newTactic($acc)));
|
|
|
|
|
$router->map("POST", "/auth", Action::noAuth(fn() => getAuthController()->authorize()));
|
|
|
|
|
|
|
|
|
|
$match = $router->match();
|
|
|
|
|
|
|
|
|
|
if ($match == null) {
|
|
|
|
|
echo "404 not found";
|
|
|
|
|
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$response = call_user_func_array($match['target'], $match['params']);
|
|
|
|
|
|
|
|
|
|
$response = handleMatch($match);
|
|
|
|
|
http_response_code($response->getCode());
|
|
|
|
|
|
|
|
|
|
if ($response instanceof JsonHttpResponse) {
|
|
|
|
|