fix(Api): remove index, allow sending Cookies

This commit is contained in:
Jérémy Dufraisse 2023-02-28 01:58:35 +01:00
parent a5f0581535
commit c0695eca2f
4 changed files with 45 additions and 40 deletions

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: EUPL-1.2 // SPDX-License-Identifier: EUPL-1.2
// Authors: see README.md // Authors: see README.md
use Pico;
use SeaCMS\Api\ApiAware; use SeaCMS\Api\ApiAware;
use SeaCMS\Api\BadMethodException; use SeaCMS\Api\BadMethodException;
use SeaCMS\Api\JsonResponse; use SeaCMS\Api\JsonResponse;
@ -19,16 +20,16 @@ class SeacmsApi extends AbstractPicoPlugin implements ApiAware
const API_VERSION = 3; const API_VERSION = 3;
/** /**
* routes trigerred OnPageRendered * api routes
* @var array * @var array
*/ */
protected $routesOnPageRendered ; protected $routes ;
/** /**
* return api routes * return api routes
* @return array * @return array
*/ */
public function registerOnPageRenderedApiRoutes():array public function registerApiRoutes():array
{ {
return [ return [
'POST test' => 'api', 'POST test' => 'api',
@ -66,14 +67,14 @@ class SeacmsApi extends AbstractPicoPlugin implements ApiAware
*/ */
public function onPluginsLoaded(array $plugins) public function onPluginsLoaded(array $plugins)
{ {
$this->routesOnPageRendered = []; $this->routes = [];
foreach($plugins as $plugin){ foreach($plugins as $plugin){
if ($plugin instanceof ApiAware){ if ($plugin instanceof ApiAware){
$routes = $plugin->registerOnPageRenderedApiRoutes(); $routes = $plugin->registerApiRoutes();
if (is_array($routes)){ if (is_array($routes)){
foreach($routes as $route => $methodName){ foreach($routes as $route => $methodName){
if (is_string($methodName) && method_exists($plugin,$methodName)){ if (is_string($methodName) && method_exists($plugin,$methodName)){
$this->routesOnPageRendered[$route] = [$plugin,$methodName]; $this->routes[$route] = [$plugin,$methodName];
} }
} }
} }
@ -91,6 +92,17 @@ class SeacmsApi extends AbstractPicoPlugin implements ApiAware
*/ */
public function onPageRendered(&$output) public function onPageRendered(&$output)
{ {
$this->resolveApi($output);
}
/**
* resolve api
* @param string $$output
* @return bool $outputChanged
*/
protected function resolveApi(string &$output): bool
{
$outputChanged = false;
if (isset($_GET['api'])){ if (isset($_GET['api'])){
$route = $this->getPico()->getUrlParameter( $route = $this->getPico()->getUrlParameter(
'api', 'api',
@ -104,10 +116,13 @@ class SeacmsApi extends AbstractPicoPlugin implements ApiAware
] ]
); );
$route = trim($route); $route = trim($route);
$callable = function() {
$this->getPico()->triggerEvent('sendCookies');
};
if (empty($route)){ if (empty($route)){
$output = (new JsonResponse(404,['code'=>404,'reason'=>'Empty api route']))->send(); $output = (new JsonResponse(404,['code'=>404,'reason'=>'Empty api route'],[],$callable))->send();
} elseif (!preg_match('/^[A-Za-z0-9_\-.\/]+$/',$route)) { } elseif (!preg_match('/^[A-Za-z0-9_\-.\/]+$/',$route)) {
$output = (new JsonResponse(404,['code'=>404,'reason'=>"Route '$route' use forbidden characters !"]))->send(); $output = (new JsonResponse(404,['code'=>404,'reason'=>"Route '$route' use forbidden characters !"],[],$callable))->send();
} else { } else {
ob_start(); ob_start();
$response = null; $response = null;
@ -135,13 +150,15 @@ class SeacmsApi extends AbstractPicoPlugin implements ApiAware
$content['rawOutput'] = $rawOutput; $content['rawOutput'] = $rawOutput;
} }
$content = array_merge(['code'=>$code],$content); $content = array_merge(['code'=>$code],$content);
$response = (new JsonResponse($code,$content)); $response = (new JsonResponse($code,$content,[],$callable));
} elseif (!empty($rawOutput)) { } elseif (!empty($rawOutput)) {
$response->mergeInContent(compact(['rawOutput'])); $response->mergeInContent(compact(['rawOutput']));
} }
$output = $response->send(); $output = $response->send();
} }
$outputChanged = true;
} }
return $outputChanged;
} }
/** /**
@ -178,10 +195,10 @@ class SeacmsApi extends AbstractPicoPlugin implements ApiAware
} }
$searchingRoute = implode('/',$splittedRouteFiltered); $searchingRoute = implode('/',$splittedRouteFiltered);
$data = []; $data = [];
if (array_key_exists("$method $searchingRoute",$this->routesOnPageRendered)){ if (array_key_exists("$method $searchingRoute",$this->routes)){
$data = $this->routesOnPageRendered["$method $searchingRoute"]; $data = $this->routes["$method $searchingRoute"];
} elseif (array_key_exists("$searchingRoute",$this->routesOnPageRendered)){ } elseif (array_key_exists("$searchingRoute",$this->routes)){
$data = $this->routesOnPageRendered["$searchingRoute"]; $data = $this->routes["$searchingRoute"];
} }
if (!empty($data)){ if (!empty($data)){
return [ return [
@ -189,7 +206,7 @@ class SeacmsApi extends AbstractPicoPlugin implements ApiAware
'methodName' => $data[1], 'methodName' => $data[1],
'params' => $params 'params' => $params
]; ];
} elseif (!$badMethod && array_key_exists((($method == 'GET') ? 'POST' : 'GET' )." $searchingRoute",$this->routesOnPageRendered)){ } elseif (!$badMethod && array_key_exists((($method == 'GET') ? 'POST' : 'GET' )." $searchingRoute",$this->routes)){
$badMethod = true; $badMethod = true;
} }
} }

View File

@ -1,24 +0,0 @@
<?php
/**
* SPDX-License-Identifier: EUPL-1.2
* Authors: see /README.md
*/
use SeaCMS\Api\JsonResponse;
$end = 'vendor/picocms/plugins/SeacmsApi/index.php';
if (empty($_SERVER['SCRIPT_NAME']) ||
empty($_SERVER['SCRIPT_FILENAME']) ||
substr($_SERVER['SCRIPT_NAME'],-strlen($end)) != $end){
if (!class_exists(JsonResponse::class,false)){
include_once __DIR__.'/src/JsonResponse.php';
}
echo (new JsonResponse(500,['code'=>500,'reason'=>'bad url to run this file']))->send();
} else {
chdir(dirname($_SERVER['SCRIPT_FILENAME'],5));
$GLOBALS['PicoVendorsDirectoryRelativeLevels'] = 4;
include 'index.php';
}

View File

@ -13,5 +13,5 @@ interface ApiAware
* return api routes * return api routes
* @return array * @return array
*/ */
public function registerOnPageRenderedApiRoutes():array; public function registerApiRoutes():array;
} }

View File

@ -36,6 +36,12 @@ class JsonResponse implements JsonSerializable
503 => 'Service Unavailable', 503 => 'Service Unavailable',
]; ];
/**
* callable to send cookies
* @var callable
*/
protected $callableToSendCookies;
/** /**
* HTTP CODE * HTTP CODE
* @var int * @var int
@ -53,7 +59,7 @@ class JsonResponse implements JsonSerializable
protected $headers; protected $headers;
public function __construct(int $code, array $content, array $headers = []){ public function __construct(int $code, array $content, array $headers = [],$callableToSendCookies = null){
$this->code = array_key_exists($code, self::HTTP_CODES) ? $code : 501; // default $this->code = array_key_exists($code, self::HTTP_CODES) ? $code : 501; // default
$this->content = $content; $this->content = $content;
$this->headers = array_merge([ $this->headers = array_merge([
@ -65,6 +71,7 @@ class JsonResponse implements JsonSerializable
'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, DELETE, PUT, PATCH', 'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, DELETE, PUT, PATCH',
'Access-Control-Max-Age' => '86400' 'Access-Control-Max-Age' => '86400'
], $headers); ], $headers);
$this->callableToSendCookies = is_callable($callableToSendCookies) ? callableToSendCookies : null;
} }
/** /**
@ -134,6 +141,11 @@ class JsonResponse implements JsonSerializable
header($name.': '.$value); header($name.': '.$value);
} }
// cookies
if (!empty($this->callableToSendCookies)){
call_user_func($this->callableToSendCookies);
}
// status // status
$statusText = self::HTTP_CODES[$this->code]; $statusText = self::HTTP_CODES[$this->code];
$protocol = !empty($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'; $protocol = !empty($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';