WIP Preorder 2022-09-14

This commit is contained in:
Frank Schubert
2022-09-14 16:52:00 +02:00
parent 8a67401d2c
commit 2cbdbf3813
6 changed files with 264 additions and 14 deletions

View File

@@ -21,6 +21,8 @@ class mfBaseApicontroller {
protected $get = [];
protected $post = [];
protected $format = "default";
protected $allowed_origins = [];
protected $allowMissingOrigin = true;
private $http_method;
private $routes = [];
@@ -39,10 +41,22 @@ class mfBaseApicontroller {
if($this->requireAuth) {
$this->authenticateUser();
if(method_exists($this,"authenticated")) {
$this->authenticated();
}
}
// Apicontroller should add allowed hostnames with $this->addAllowedOrigin()
$this->createCorsHeaders();
// CORS preflight OPTIONS
if($this->http_method == "OPTIONS") {
// dont execute route, OPTIONS only requires CORS headers
$this->return(mfResponse::Ok());
}
// route to action
$this->route = $params['apicall'].(($params['apiparams']) ? $params['apiparams'] : "");
$this->route = $params['apicall'].((array_key_exists("apiparams", $params)) ? $params['apiparams'] : "");
$responseData = $this->runRoute($this->route);
if(!$responseData) {
@@ -104,13 +118,6 @@ class mfBaseApicontroller {
$this->return(mfResponse::ImATeaPot());
}
// CORS preflight OPTIONS
// CORS headers must be correctly set in .htaccess or vhost config
if($this->http_method == "OPTIONS") {
// XXX TODO: api endpoint should decide if Origin should be allowed access
$this->return(mfResponse::Ok());
}
// POST Request
$post = [];
if($this->http_method == "POST") {
@@ -210,6 +217,67 @@ class mfBaseApicontroller {
}
private function createCorsHeaders() {
header("Access-Control-Allow-Methods: GET,POST,OPTIONS");
header("Access-Control-Allow-Headers: X-Api-Key");
//var_dump($this->headers);exit;
if(!is_array($this->allowed_origins) || !count($this->allowed_origins)) {
return true;
}
if(!array_key_exists("origin", $this->headers)) {
if(!$this->allowMissingOrigin) {
$this->return(mfResponse::Forbidden());
}
return true;
}
$request_origin = ["proto" => false, "hostname" => ""];
$m = [];
if(preg_match('#^(https?)://(.+)(:\d+)?$#i', $this->headers['origin'], $m)) {
$request_origin['proto'] = $m[1];
$request_origin['hostname'] = $m[2];
}
//var_dump($request_origin);exit;
foreach($this->allowed_origins as $origin) {
//echo $origin." -> ".$_SERVER["HTTP_HOST"];
$proto = false;
$hostname = $origin;
$m = [];
if(preg_match('#^(https?)://(.+)$#i', $origin, $m)) {
$proto = $m[1];
$hostname = $m[2];
}
if(substr($hostname, 0, 2) == "*.") {
$hostname = str_replace("*.", ".*\\.", $hostname);
}
//var_dump($hostname);exit;
//if($hostname == $request_origin['hostname']) {
if(preg_match('/^'.$hostname.'$/', $request_origin['hostname'])) {
if($proto) {
if($proto == $request_origin['proto']) {
header("Access-Control-Allow-Origin: $proto://".$request_origin['hostname']);
return true;
}
} else {
header("Access-Control-Allow-Origin: ".$request_origin['proto']."://".$request_origin['hostname']);
return true;
}
}
}
if(!$this->allowMissingOrigin) {
$this->return(mfResponse::Forbidden());
exit;
}
return true;
}
protected function runRoute($params) {
if(!is_array($this->routes) || !count($this->routes)) {
return false;
@@ -303,6 +371,12 @@ class mfBaseApicontroller {
"action" => $action,
"method" => $method
];
return true;
}
protected function addAllowedOrigin($origin) {
$this->allowed_origins[] = trim($origin);
return true;
}
public static function loadApiClass($name) {