From 444ff687fc8e5a2b5c13c1cec8dfa98091a55b5b Mon Sep 17 00:00:00 2001 From: Juan Pablo Vial Date: Wed, 20 Mar 2024 23:07:49 -0300 Subject: [PATCH] Base API, and more solid key and check --- app/resources/routes/01_api.php | 3 +++ .../views/layout/body/scripts.blade.php | 14 +++++++++- app/setup/setups/middlewares.php | 1 + app/setup/setups/services.php | 3 ++- app/src/Controller/API/Base.php | 20 ++++++++++++++ app/src/Middleware/API.php | 26 ++++++++++++++++--- app/src/Middleware/Authentication.php | 3 ++- app/src/Service/Login.php | 8 ++++++ 8 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 app/src/Controller/API/Base.php diff --git a/app/resources/routes/01_api.php b/app/resources/routes/01_api.php index 73fb159..6fd9015 100644 --- a/app/resources/routes/01_api.php +++ b/app/resources/routes/01_api.php @@ -1,4 +1,6 @@ group('/api', function($app) { $folder = implode(DIRECTORY_SEPARATOR, [__DIR__, 'api']); if (file_exists($folder)) { @@ -10,4 +12,5 @@ $app->group('/api', function($app) { include_once $file->getRealPath(); } } + $app->get('[/]', Base::class); })->add($app->getContainer()->get(Incoviba\Middleware\API::class)); diff --git a/app/resources/views/layout/body/scripts.blade.php b/app/resources/views/layout/body/scripts.blade.php index 049a3d0..480a503 100644 --- a/app/resources/views/layout/body/scripts.blade.php +++ b/app/resources/views/layout/body/scripts.blade.php @@ -2,6 +2,13 @@ @stack('page_scripts') diff --git a/app/setup/setups/middlewares.php b/app/setup/setups/middlewares.php index 567b36e..17417f7 100644 --- a/app/setup/setups/middlewares.php +++ b/app/setup/setups/middlewares.php @@ -14,6 +14,7 @@ return [ Incoviba\Middleware\API::class => function(ContainerInterface $container) { return new Incoviba\Middleware\API( $container->get(Psr\Http\Message\ResponseFactoryInterface::class), + $container->get(Incoviba\Service\Login::class), $container->get('API_KEY') ); } diff --git a/app/setup/setups/services.php b/app/setup/setups/services.php index c08cb1c..6873212 100644 --- a/app/setup/setups/services.php +++ b/app/setup/setups/services.php @@ -9,7 +9,8 @@ return [ $container->get('COOKIE_NAME'), $container->get('MAX_LOGIN_HOURS'), $container->has('COOKIE_DOMAIN') ? $container->get('COOKIE_DOMAIN') : '', - $container->has('COOKIE_PATH') ? $container->get('COOKIE_PATH') : '' + $container->has('COOKIE_PATH') ? $container->get('COOKIE_PATH') : '', + $container->has('COOKIE_SEPARATOR') ? $container->get('COOKIE_SEPARATOR') : 'g' ); }, Incoviba\Service\Money::class => function(ContainerInterface $container) { diff --git a/app/src/Controller/API/Base.php b/app/src/Controller/API/Base.php new file mode 100644 index 0000000..1f422ca --- /dev/null +++ b/app/src/Controller/API/Base.php @@ -0,0 +1,20 @@ + '2.0.0', + 'organization' => 'Ingenieria y Construccion Vial Balmaceda Sociedad Anonima' + ]; + return $this->withJson($response, $output); + } +} diff --git a/app/src/Middleware/API.php b/app/src/Middleware/API.php index 61a0d8a..df1d566 100644 --- a/app/src/Middleware/API.php +++ b/app/src/Middleware/API.php @@ -6,10 +6,12 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use Incoviba\Exception\MissingAuthorizationHeader; +use Incoviba\Service; class API { - public function __construct(protected ResponseFactoryInterface $responseFactory, protected string $key) {} + public function __construct(protected ResponseFactoryInterface $responseFactory, protected Service\Login $loginService, + protected string $key) {} public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { @@ -18,7 +20,7 @@ class API } catch (MissingAuthorizationHeader $exception) { return $this->responseFactory->createResponse(401); } - if ($this->validate($key)) { + if ($this->validate($request, $key)) { return $handler->handle($request); } return $this->responseFactory->createResponse(403); @@ -33,8 +35,26 @@ class API } throw new MissingAuthorizationHeader(); } - protected function validate($incoming_key): bool + protected function validate(ServerRequestInterface $request, $incoming_key): bool { + if (str_contains($incoming_key, $this->loginService->getSeparator())) { + list($incoming_key, $selector, $token) = explode($this->loginService->getSeparator(), $incoming_key); + if (!$this->loginService->isIn()) { + return false; + } + } + if (!$this->loginService->isIn() and !$this->validPermitted($request)) { + return false; + } return $incoming_key === md5($this->key); } + protected function validPermitted(ServerRequestInterface $request): bool + { + $uri = $request->getUri(); + $validPaths = [ + '/api', + '/api/' + ]; + return in_array($uri->getPath(), $validPaths); + } } diff --git a/app/src/Middleware/Authentication.php b/app/src/Middleware/Authentication.php index a2530ac..0344212 100644 --- a/app/src/Middleware/Authentication.php +++ b/app/src/Middleware/Authentication.php @@ -51,7 +51,7 @@ class Authentication return true; } $valid_subpaths = [ - '/api' + '/api/' ]; foreach ($valid_subpaths as $path) { if (str_starts_with($current_path, $path)) { @@ -60,6 +60,7 @@ class Authentication } $valid_uris = [ $this->login_url, + "{$this->login_url}/", ]; if (in_array($current_url, $valid_uris, true)) { return true; diff --git a/app/src/Service/Login.php b/app/src/Service/Login.php index 9a55ebb..1fb1730 100644 --- a/app/src/Service/Login.php +++ b/app/src/Service/Login.php @@ -47,6 +47,14 @@ class Login } return $login->user; } + public function getToken(): string + { + return implode($this->cookie_separator, [$this->selector, $this->token]); + } + public function getSeparator(): string + { + return $this->cookie_separator; + } public function validateUser(Model\User $user, string $encryptedPassword): bool { list($passphrase, $encrypted) = $this->splitPassword($encryptedPassword);