From d36b34069211711ff393f8c8ba996c46c0f6e51c Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Thu, 27 Dec 2018 00:51:54 -0700 Subject: [PATCH 1/4] Make API work with user/pass combo --- api/functions.php | 25 ++++++++++++++++--------- api/index.php | 14 ++++++++------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/api/functions.php b/api/functions.php index 78e84c1..7cd1706 100644 --- a/api/functions.php +++ b/api/functions.php @@ -48,20 +48,27 @@ function getCensoredKey() { /** * Check if the request is allowed - * @global type $VARS - * @global type $database + * @global array $VARS * @return bool true if the request should continue, false if the request is bad */ function authenticate(): bool { - global $VARS, $database; - if (empty($VARS['key'])) { + global $VARS; + // HTTP basic auth + if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { + $user = User::byUsername($_SERVER['PHP_AUTH_USER']); + if (!$user->checkPassword($_SERVER['PHP_AUTH_PW'])) { + return false; + } + return true; + } + // Form auth + if (empty($VARS['username']) || empty($VARS['password'])) { 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); + $username = $VARS['username']; + $password = $VARS['password']; + $user = User::byUsername($username); + if ($user->exists() !== true || Login::auth($username, $password) !== Login::LOGIN_OK) { return false; } } diff --git a/api/index.php b/api/index.php index 59d0c2a..8875860 100644 --- a/api/index.php +++ b/api/index.php @@ -25,13 +25,14 @@ if (json_last_error() == JSON_ERROR_NONE) { if (strpos($_SERVER['REQUEST_URI'], "/api.php") === FALSE) { $route = explode("/", substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], "api/") + 4)); - if (count($route) > 1) { + 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++) { + for ($i = 1; $i < count($route); $i++) { + if (empty($route[$i]) || strpos($route[$i], "=") === false) { + continue; + } $key = explode("=", $route[$i], 2)[0]; $val = explode("=", $route[$i], 2)[1]; $VARS[$key] = $val; @@ -49,8 +50,9 @@ if (strpos($_SERVER['REQUEST_URI'], "/api.php") === FALSE) { } if (!authenticate()) { - http_response_code(403); - die("403 Unauthorized"); + header('WWW-Authenticate: Basic realm="' . $SETTINGS['site_title'] . '"'); + header('HTTP/1.1 401 Unauthorized'); + die("401 Unauthorized: you need to supply valid credentials."); } if (empty($VARS['action'])) { From f1c36fdeb1802d536f1c5fcf8889f70604adab61 Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Thu, 27 Dec 2018 00:55:58 -0700 Subject: [PATCH 2/4] Add getRequestUser() function --- api/functions.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/api/functions.php b/api/functions.php index 7cd1706..530f011 100644 --- a/api/functions.php +++ b/api/functions.php @@ -75,6 +75,18 @@ function authenticate(): bool { return true; } +/** + * Get the User whose credentials were used to make the request. + */ +function getRequestUser(): User { + global $VARS; + if (!empty($_SERVER['PHP_AUTH_USER'])) { + return User::byUsername($_SERVER['PHP_AUTH_USER']); + } else { + return User::byUsername($VARS['username']); + } +} + function checkVars($vars, $or = false) { global $VARS; $ok = []; From 6ceeeaa087da3206d59ab201e12368b26d430496 Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Thu, 27 Dec 2018 14:44:10 -0700 Subject: [PATCH 3/4] Add support for regex matching on API vars --- api/functions.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/api/functions.php b/api/functions.php index 530f011..b0e6d09 100644 --- a/api/functions.php +++ b/api/functions.php @@ -109,11 +109,13 @@ function checkVars($vars, $or = false) { continue; } } - $checkmethod = "is_$val"; - if ($checkmethod($VARS[$key]) !== true) { - $ok[$key] = false; + + if (strpos($val, "/") === 0) { + // regex + $ok[$key] = preg_match($val, $VARS[$key]) === 1; } else { - $ok[$key] = true; + $checkmethod = "is_$val"; + $ok[$key] = !($checkmethod($VARS[$key]) !== true); } } if ($or) { From 69c634ea9945b0de816c1d46dfdb86d9bedb68e1 Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Mon, 31 Dec 2018 14:14:00 -0700 Subject: [PATCH 4/4] Add checkbox to form builder --- lib/FormBuilder.lib.php | 47 ++++++++++++++++++++++++++++------------- pages/form.php | 1 + 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/FormBuilder.lib.php b/lib/FormBuilder.lib.php index fddbff2..a07919b 100644 --- a/lib/FormBuilder.lib.php +++ b/lib/FormBuilder.lib.php @@ -173,33 +173,50 @@ HTMLTOP; $required = $item["required"] ? "required" : ""; $id = empty($item["id"]) ? "" : "id=\"$item[id]\""; $pattern = empty($item["pattern"]) ? "" : "pattern=\"$item[pattern]\""; - + if (empty($item['type'])) { + $item['type'] = "text"; + } $itemhtml = ""; + $itemlabel = ""; + if ($item['type'] != "checkbox") { + $itemlabel = ""; + } $itemhtml .= <<
- + $itemlabel
ITEMTOP; - if (empty($item['type']) || $item['type'] != "select") { - $itemhtml .= << -INPUT; - } else { - $itemhtml .= <<"; + $itemhtml .= "\n "; + break; + case "checkbox": + $itemhtml .= << + + +
+CHECKBOX; + break; + default: + $itemhtml .= << +INPUT; + break; } if (!empty($item["error"])) { diff --git a/pages/form.php b/pages/form.php index 7cd7fdd..3a9cc52 100644 --- a/pages/form.php +++ b/pages/form.php @@ -18,6 +18,7 @@ $form->addHiddenInput("page", "form"); $form->addInput("name", "John", "text", true, null, null, "Your name", "fas fa-user", 6, 5, 20, "John(ny)?|Steve", "Invalid name, please enter John, Johnny, or Steve."); $form->addInput("location", "", "select", true, null, ["1" => "Here", "2" => "There"], "Location", "fas fa-map-marker"); +$form->addInput("box", "1", "checkbox", true, null, null, "I agree to the terms of service"); $form->addButton("Submit", "fas fa-save", null, "submit", "savebtn");