You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.2 KiB
100 lines
3.2 KiB
<?php
|
|
|
|
require "../../config.php";
|
|
require "../../vendor/autoload.php";
|
|
require "../../sql/database.php";
|
|
require "../utils.php";
|
|
|
|
use IQBall\Api\ApiAction;
|
|
use IQBall\Core\Connection;
|
|
use IQBall\Api\APIAuthController;
|
|
use IQBall\Api\APITacticController;
|
|
use IQBall\Core\Data\Account;
|
|
use IQBall\Core\Gateway\AccountGateway;
|
|
use IQBall\Core\Gateway\TacticInfoGateway;
|
|
use IQBall\Core\Http\HttpResponse;
|
|
use IQBall\Core\Http\JsonHttpResponse;
|
|
use IQBall\Core\Http\ViewHttpResponse;
|
|
use IQBall\Core\Model\AuthModel;
|
|
use IQBall\Core\Model\TacticModel;
|
|
use IQBall\Core\Session\PhpSessionHandle;
|
|
use IQBall\Core\Validation\ValidationFail;
|
|
|
|
function getTacticController(): APITacticController {
|
|
return new APITacticController(new TacticModel(new TacticInfoGateway(new Connection(get_database()))));
|
|
}
|
|
|
|
function getAuthController(): APIAuthController {
|
|
return new APIAuthController(new AuthModel(new AccountGateway(new Connection(get_database()))));
|
|
}
|
|
|
|
function getRoutes(): AltoRouter {
|
|
$router = new AltoRouter();
|
|
$router->setBasePath(get_public_path() . "/api");
|
|
|
|
$router->map("POST", "/tactic/[i:id]/edit/name", ApiAction::auth(fn(int $id, Account $acc) => getTacticController()->updateName($id, $acc)));
|
|
$router->map("GET", "/tactic/[i:id]", ApiAction::auth(fn(int $id, Account $acc) => getTacticController()->getTacticInfo($id, $acc)));
|
|
$router->map("POST", "/tactic/new", ApiAction::auth(fn(Account $acc) => getTacticController()->newTactic($acc)));
|
|
$router->map("POST", "/auth", ApiAction::noAuth(fn() => getAuthController()->authorize()));
|
|
|
|
return $router;
|
|
}
|
|
|
|
/**
|
|
* @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 ApiAction) {
|
|
throw new Exception("routed action is not an AppAction object.");
|
|
}
|
|
|
|
$auth = null;
|
|
|
|
if ($action->isAuthRequired()) {
|
|
$auth = tryGetAuthorization();
|
|
if ($auth == null) {
|
|
return new JsonHttpResponse([ValidationFail::unauthorized("Missing or invalid 'Authorization' header.")]);
|
|
}
|
|
}
|
|
|
|
return $action->run($match['params'], $auth);
|
|
}
|
|
|
|
function tryGetAuthorization(): ?Account {
|
|
$headers = getallheaders();
|
|
|
|
// If no authorization header is set, try fallback to php session.
|
|
if (!isset($headers['Authorization'])) {
|
|
$session = PhpSessionHandle::init();
|
|
return $session->getAccount();
|
|
}
|
|
|
|
$token = $headers['Authorization'];
|
|
$gateway = new AccountGateway(new Connection(get_database()));
|
|
return $gateway->getAccountFromToken($token);
|
|
}
|
|
|
|
function render(HttpResponse $response): void {
|
|
http_response_code($response->getCode());
|
|
|
|
foreach ($response->getHeaders() as $header => $value) {
|
|
header("$header: $value");
|
|
}
|
|
|
|
if ($response instanceof JsonHttpResponse) {
|
|
header('Content-type: application/json');
|
|
echo $response->getJson();
|
|
} elseif ($response instanceof ViewHttpResponse) {
|
|
throw new Exception("API returned a view http response.");
|
|
}
|
|
}
|
|
|
|
render(handleMatch(getRoutes()->match()));
|