forked from Business/AccountHub
Make better API system, use new AccountHub API
parent
13b60de915
commit
5b7ab65946
@ -0,0 +1,5 @@
|
|||||||
|
# Rewrite for Nextcloud Notes API
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
RewriteEngine on
|
||||||
|
RewriteRule ([a-zA-Z0-9]+) index.php?action=$1 [PT]
|
||||||
|
</IfModule>
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sendJsonResp();
|
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$APIS = [
|
||||||
|
"ping" => [
|
||||||
|
"load" => "ping.php",
|
||||||
|
"vars" => [
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
@ -0,0 +1,123 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build and send a simple JSON response.
|
||||||
|
* @param string $msg A message
|
||||||
|
* @param string $status "OK" or "ERROR"
|
||||||
|
* @param array $data More JSON data
|
||||||
|
*/
|
||||||
|
function sendJsonResp(string $msg = null, string $status = "OK", array $data = null) {
|
||||||
|
$resp = [];
|
||||||
|
if (!is_null($data)) {
|
||||||
|
$resp = $data;
|
||||||
|
}
|
||||||
|
if (!is_null($msg)) {
|
||||||
|
$resp["msg"] = $msg;
|
||||||
|
}
|
||||||
|
$resp["status"] = $status;
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
exit(json_encode($resp));
|
||||||
|
}
|
||||||
|
|
||||||
|
function exitWithJson(array $json) {
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
exit(json_encode($json));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the API key with most of the characters replaced with *s.
|
||||||
|
* @global string $key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function getCensoredKey() {
|
||||||
|
global $key;
|
||||||
|
$resp = $key;
|
||||||
|
if (strlen($key) > 5) {
|
||||||
|
for ($i = 2; $i < strlen($key) - 2; $i++) {
|
||||||
|
$resp[$i] = "*";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the request is allowed
|
||||||
|
* @global type $VARS
|
||||||
|
* @global type $database
|
||||||
|
* @return bool true if the request should continue, false if the request is bad
|
||||||
|
*/
|
||||||
|
function authenticate(): bool {
|
||||||
|
global $VARS, $database;
|
||||||
|
if (empty($VARS['key'])) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
$key = $VARS['key'];
|
||||||
|
if ($database->has('apikeys', ['key' => $key]) !== TRUE) {
|
||||||
|
engageRateLimit();
|
||||||
|
http_response_code(403);
|
||||||
|
Log::insert(LogType::API_BAD_KEY, null, "Key: " . $key);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkVars($vars, $or = false) {
|
||||||
|
global $VARS;
|
||||||
|
$ok = [];
|
||||||
|
foreach ($vars as $key => $val) {
|
||||||
|
if (strpos($key, "OR") === 0) {
|
||||||
|
checkVars($vars[$key], true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only check type of optional variables if they're set, and don't
|
||||||
|
// mark them as bad if they're not set
|
||||||
|
if (strpos($key, " (optional)") !== false) {
|
||||||
|
$key = str_replace(" (optional)", "", $key);
|
||||||
|
if (empty($VARS[$key])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (empty($VARS[$key])) {
|
||||||
|
$ok[$key] = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$checkmethod = "is_$val";
|
||||||
|
if ($checkmethod($VARS[$key]) !== true) {
|
||||||
|
$ok[$key] = false;
|
||||||
|
} else {
|
||||||
|
$ok[$key] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($or) {
|
||||||
|
$success = false;
|
||||||
|
$bad = "";
|
||||||
|
foreach ($ok as $k => $v) {
|
||||||
|
if ($v) {
|
||||||
|
$success = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
$bad = $k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$success) {
|
||||||
|
http_response_code(400);
|
||||||
|
die("400 Bad request: variable $bad is missing or invalid");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($ok as $key => $bool) {
|
||||||
|
if (!$bool) {
|
||||||
|
http_response_code(400);
|
||||||
|
die("400 Bad request: variable $key is missing or invalid");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require __DIR__ . '/../required.php';
|
||||||
|
require __DIR__ . '/functions.php';
|
||||||
|
require __DIR__ . '/apisettings.php';
|
||||||
|
|
||||||
|
$VARS = $_GET;
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != "GET") {
|
||||||
|
$VARS = array_merge($VARS, $_POST);
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestbody = file_get_contents('php://input');
|
||||||
|
$requestjson = json_decode($requestbody, TRUE);
|
||||||
|
if (json_last_error() == JSON_ERROR_NONE) {
|
||||||
|
$requestdata = array_merge($requestdata, $requestjson);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're not using the old api.php file, allow more flexible requests
|
||||||
|
if (strpos($_SERVER['REQUEST_URI'], "/api.php") === FALSE) {
|
||||||
|
$route = explode("/", substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], "api/") + 4));
|
||||||
|
|
||||||
|
if (count($route) > 1) {
|
||||||
|
$VARS["action"] = $route[0];
|
||||||
|
}
|
||||||
|
if (count($route) >= 2 && strpos($route[1], "?") !== 0) {
|
||||||
|
$VARS["key"] = $route[1];
|
||||||
|
|
||||||
|
for ($i = 2; $i < count($route); $i++) {
|
||||||
|
$key = explode("=", $route[$i], 2)[0];
|
||||||
|
$val = explode("=", $route[$i], 2)[1];
|
||||||
|
$VARS[$key] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strpos($route[count($route) - 1], "?") === 0) {
|
||||||
|
$morevars = explode("&", substr($route[count($route) - 1], 1));
|
||||||
|
foreach ($morevars as $var) {
|
||||||
|
$key = explode("=", $var, 2)[0];
|
||||||
|
$val = explode("=", $var, 2)[1];
|
||||||
|
$VARS[$key] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!authenticate()) {
|
||||||
|
http_response_code(403);
|
||||||
|
die("403 Unauthorized");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($VARS['action'])) {
|
||||||
|
http_response_code(404);
|
||||||
|
die("404 No action specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($APIS[$VARS['action']])) {
|
||||||
|
http_response_code(404);
|
||||||
|
die("404 Action not defined");
|
||||||
|
}
|
||||||
|
|
||||||
|
$APIACTION = $APIS[$VARS["action"]];
|
||||||
|
|
||||||
|
if (!file_exists(__DIR__ . "/actions/" . $APIACTION["load"])) {
|
||||||
|
http_response_code(404);
|
||||||
|
die("404 Action not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($APIACTION["vars"])) {
|
||||||
|
checkVars($APIACTION["vars"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once __DIR__ . "/actions/" . $APIACTION["load"];
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class AccountHubApi {
|
||||||
|
|
||||||
|
public static function get(string $action, array $data = null, bool $throwex = false) {
|
||||||
|
$content = [
|
||||||
|
"action" => $action,
|
||||||
|
"key" => PORTAL_KEY
|
||||||
|
];
|
||||||
|
if (!is_null($data)) {
|
||||||
|
$content = array_merge($content, $data);
|
||||||
|
}
|
||||||
|
$options = [
|
||||||
|
'http' => [
|
||||||
|
'method' => 'POST',
|
||||||
|
'content' => json_encode($content),
|
||||||
|
'header' => "Content-Type: application/json\r\n" .
|
||||||
|
"Accept: application/json\r\n",
|
||||||
|
"ignore_errors" => true
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$context = stream_context_create($options);
|
||||||
|
$result = file_get_contents(PORTAL_API, false, $context);
|
||||||
|
$response = json_decode($result, true);
|
||||||
|
if ($result === false || !AccountHubApi::checkHttpRespCode($http_response_header) || json_last_error() != JSON_ERROR_NONE) {
|
||||||
|
if ($throwex) {
|
||||||
|
throw new Exception($result);
|
||||||
|
} else {
|
||||||
|
sendError($result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function checkHttpRespCode(array $headers): bool {
|
||||||
|
foreach ($headers as $header) {
|
||||||
|
if (preg_match("/HTTP\/[0-9]\.[0-9] [0-9]{3}.*/", $header)) {
|
||||||
|
$respcode = explode(" ", $header)[1] * 1;
|
||||||
|
if ($respcode >= 200 && $respcode < 300) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue