WIP Preorder 2022-09-14
This commit is contained in:
@@ -153,7 +153,7 @@
|
||||
<label class="col-lg-2 col-form-label" for="corsorigins">CORS Origin Hostnamen</label>
|
||||
<div class="col-lg-10">
|
||||
<textarea class="form-control" name="corsorigins"><?=($campaign->corsorigins) ? implode("\n", $campaign->corsorigins) : ""?></textarea>
|
||||
<small>Website Url oder Hostname; ein Eintrag pro Zeile</small>
|
||||
<small>Hostname der Website, mit oder ohne Protokoll (<em>https://</em>); *. als Wildcard erlaubt (<em>*.domain.com</em>); ein Eintrag pro Zeile</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
class AddressdbApicontroller extends mfBaseApicontroller {
|
||||
private $filter_gemeinde_ids = [];
|
||||
|
||||
protected function init() {
|
||||
$db = $this->db(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
|
||||
@@ -9,6 +10,24 @@ class AddressdbApicontroller extends mfBaseApicontroller {
|
||||
$this->addRoute("/addressdb/findStreet", "findStreet", "POST");
|
||||
$this->addRoute("/addressdb/findZip", "findZip", "POST");
|
||||
$this->addRoute("/addressdb/findCity", "findCity", "POST");
|
||||
|
||||
$this->allowMissingOrigin = false;
|
||||
}
|
||||
|
||||
protected function authenticated() {
|
||||
$campaignApiuser = PreordercampaignApiuserModel::getFirst(["worker_id" => $this->me->id]);
|
||||
$campaign = new Preordercampaign($campaignApiuser->preordercampaign_id);
|
||||
if($campaign) {
|
||||
foreach(PreordercampaignGemeindeModel::search(['preordercampaign_id' => $campaign->id]) as $gemeinde) {
|
||||
$this->filter_gemeinde_ids[] = $gemeinde->id;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(PreordercampaignOriginhostnameModel::search(['preordercampaign_id' => $campaign->id]) as $origin) {
|
||||
$this->addAllowedOrigin($origin->hostname);
|
||||
}
|
||||
|
||||
//var_dump($campaign, $this->allowed_origins);exit;
|
||||
}
|
||||
|
||||
protected function findCity() {
|
||||
|
||||
157
application/Api/v1/PreorderApicontroller.php
Normal file
157
application/Api/v1/PreorderApicontroller.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
class PreorderApicontroller extends mfBaseApicontroller {
|
||||
private $filter_gemeinde_ids = [];
|
||||
private $campaign;
|
||||
|
||||
|
||||
protected function init() {
|
||||
$db = $this->db(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
|
||||
|
||||
$this->addRoute("/preorder", "submitPreorder", "POST");
|
||||
|
||||
$this->allowMissingOrigin = false;
|
||||
}
|
||||
|
||||
protected function authenticated() {
|
||||
$campaignApiuser = PreordercampaignApiuserModel::getFirst(["worker_id" => $this->me->id]);
|
||||
$campaign = new Preordercampaign($campaignApiuser->preordercampaign_id);
|
||||
if($campaign) {
|
||||
$this->campaign = $campaign;
|
||||
foreach(PreordercampaignGemeindeModel::search(['preordercampaign_id' => $campaign->id]) as $gemeinde) {
|
||||
$this->filter_gemeinde_ids[] = $gemeinde->id;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(PreordercampaignOriginhostnameModel::search(['preordercampaign_id' => $campaign->id]) as $origin) {
|
||||
$this->addAllowedOrigin($origin->hostname);
|
||||
}
|
||||
|
||||
//var_dump($campaign, $this->allowed_origins);exit;
|
||||
}
|
||||
|
||||
protected function submitPreorder() {
|
||||
if(!$this->campaign) {
|
||||
$this->log->debug("disallowed request because no campaign for apikey");
|
||||
return mfResponse::Forbidden();
|
||||
}
|
||||
|
||||
$type = $this->post['type'];
|
||||
if($type != "provision" && $type != "order") {
|
||||
return mfResponse::BadRequest(["message" => "Unknown type"]);
|
||||
}
|
||||
|
||||
if(!array_key_exists("address", $this->post)) {
|
||||
return mfResponse::BadRequest(['message' => "address missing"]);
|
||||
}
|
||||
|
||||
if(!array_key_exists("customer", $this->post)) {
|
||||
return mfResponse::BadRequest(['message' => "customer data missing"]);
|
||||
}
|
||||
|
||||
// check address
|
||||
if(!property_exists($this->post['address'],"street") ||
|
||||
!property_exists($this->post['address'],"housenumber") ||
|
||||
!property_exists($this->post['address'],"zip") ||
|
||||
!property_exists($this->post['address'],"city")
|
||||
) {
|
||||
return mfResponse::BadRequest(['message' => "Mandatory address fields missing"]);
|
||||
}
|
||||
|
||||
$address_search = [];
|
||||
foreach(['street' => 'strasse','housenumber' => "hausnummer",'zip' => "plz",'city' => "ortschaft"] as $key => $field_name) {
|
||||
if(property_exists($this->post['address'], $key)) {
|
||||
$address_search[$field_name] = trim($this->post['address']->$key);
|
||||
}
|
||||
}
|
||||
|
||||
$unit_search = [];
|
||||
foreach(['block','stiege','stock','tuer'] as $key) {
|
||||
if(property_exists($this->post['address'], $key) && trim($this->post['address']->key)) {
|
||||
$unit_search[$key] = trim($this->post['address']->$key);
|
||||
}
|
||||
}
|
||||
|
||||
// check customer
|
||||
|
||||
$customer = $this->post['customer'];
|
||||
|
||||
if(!property_exists($customer,"firstname") ||
|
||||
!property_exists($customer,"lastname") ||
|
||||
!property_exists($customer,"street") ||
|
||||
!property_exists($customer,"zip") ||
|
||||
!property_exists($customer,"city")
|
||||
) {
|
||||
return mfResponse::BadRequest(['message' => "Mandatory customer fields missing"]);
|
||||
}
|
||||
|
||||
|
||||
// search address in AddressDB
|
||||
|
||||
foreach($address_search as $field => $value) {
|
||||
$where .= " AND `$field` = '$value'";
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM view_hausnummer WHERE 1=1 $where";
|
||||
$res = $this->db()->query($sql);
|
||||
if(!$this->db()->num_rows($res)) {
|
||||
//var_dump($this->db()->num_rows($res), $this->db()->fetch_object($res));
|
||||
return mfResponse::NotFound(['message' => "Adresse nicht gefunden"]);
|
||||
}
|
||||
|
||||
$address = $this->db()->fetch_object($res);
|
||||
|
||||
|
||||
|
||||
|
||||
// search wohneinheit
|
||||
$unit = false;
|
||||
if(count($unit_search)) {
|
||||
foreach($unit_search as $field => $value) {
|
||||
if($field == "stock" || $field == "stiege") continue; // only check for block and tuer
|
||||
$where .= " AND `$field` = '$value'";
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM view_wohneinheit WHERE 1=1 $where AND hausnummer_id=".$address->hausnummer_id;
|
||||
$res = $this->db()->query($sql);
|
||||
if(!$this->db()->num_rows($res)) {
|
||||
return mfResponse::NotFound(['message' => "Wohneinheit nicht gefunden"]);
|
||||
}
|
||||
|
||||
$unit = $this->db()->fetch_object($res);
|
||||
//var_dump($this->db()->num_rows($res), $this->db()->fetch_object($res));
|
||||
|
||||
}
|
||||
|
||||
$preorder_data = [];
|
||||
$preorder_data['preordercampaign_id'] = $this->campaign->id;
|
||||
$preorder_data['type'] = $type;
|
||||
$preorder_data['adb_hausnummer_id'] = $address->hausnummer_id;
|
||||
|
||||
if($unit) {
|
||||
$preorder_data['adb_wohneinheit_id'] = $unit->wohneinheit_id;
|
||||
}
|
||||
|
||||
if($type == "provision") {
|
||||
$product = $this->campaign->setup_products['provision'][0];
|
||||
if($product) {
|
||||
$preorder_data['setup_product_id'] = $product->id;
|
||||
$preorder_data['price_setup'] = $product->price_setup;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
foreach(['company','uid','firstname','lastname','street','zip','city','phone','email'] as $key) {
|
||||
if(property_exists($customer, $key)) {
|
||||
$preorder_data[$key] = $customer->$key;
|
||||
}
|
||||
}
|
||||
|
||||
var_dump($preorder_data);exit;
|
||||
|
||||
|
||||
var_dump($this->post);exit;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
SetEnvIf Origin "^(https://docs.thetool.xinon.at|https://editor.swagger.io|.*abstellgleis.at)$" AccessControlAllowOrigin=$0
|
||||
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
|
||||
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS"
|
||||
Header add Access-Control-Allow-Headers: "X-Api-Key"
|
||||
#SetEnvIf Origin "^(https://docs.thetool.xinon.at|https://editor.swagger.io|.*abstellgleis.at)$" AccessControlAllowOrigin=$0
|
||||
#Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
|
||||
#Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS"
|
||||
#Header add Access-Control-Allow-Headers: "X-Api-Key"
|
||||
|
||||
RewriteEngine on
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@ Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessCo
|
||||
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS"
|
||||
Header add Access-Control-Allow-Headers: "X-Api-Key"
|
||||
|
||||
Header add Cach-control: "no-store, no-cache, must-revalidate"
|
||||
Header add Cache-control: "no-store, no-cache, must-revalidate"
|
||||
|
||||
Reference in New Issue
Block a user