| 
									
										
										
										
											2018-12-14 21:16:31 -07:00
										 |  |  | <?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 | 
					
						
							| 
									
										
										
										
											2018-12-27 00:51:54 -07:00
										 |  |  |  * @global array $VARS | 
					
						
							| 
									
										
										
										
											2018-12-14 21:16:31 -07:00
										 |  |  |  * @return bool true if the request should continue, false if the request is bad | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | function authenticate(): bool { | 
					
						
							| 
									
										
										
										
											2019-03-01 23:41:10 -07:00
										 |  |  |     global $VARS, $SETTINGS; | 
					
						
							| 
									
										
										
										
											2018-12-27 00:51:54 -07:00
										 |  |  |     // HTTP basic auth
 | 
					
						
							|  |  |  |     if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { | 
					
						
							| 
									
										
										
										
											2019-02-11 16:19:27 -07:00
										 |  |  |         $username = $_SERVER['PHP_AUTH_USER']; | 
					
						
							|  |  |  |         $password = $_SERVER['PHP_AUTH_PW']; | 
					
						
							|  |  |  |     } else if (!empty($VARS['username']) && !empty($VARS['password'])) { | 
					
						
							| 
									
										
										
										
											2018-12-27 00:51:54 -07:00
										 |  |  |         $username = $VARS['username']; | 
					
						
							|  |  |  |         $password = $VARS['password']; | 
					
						
							| 
									
										
										
										
											2019-02-11 16:19:27 -07:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     $user = User::byUsername($username); | 
					
						
							|  |  |  |     if (!$user->exists()) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ($user->checkPassword($password, true)) { | 
					
						
							| 
									
										
										
										
											2019-03-01 23:41:10 -07:00
										 |  |  |         // Check that the user has permission to access the app
 | 
					
						
							|  |  |  |         $perms = is_array($SETTINGS['api_permissions']) ? $SETTINGS['api_permissions'] : $SETTINGS['permissions']; | 
					
						
							|  |  |  |         foreach ($perms as $perm) { | 
					
						
							|  |  |  |             if (!$user->hasPermission($perm)) { | 
					
						
							|  |  |  |                 return false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-02-11 16:19:27 -07:00
										 |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2018-12-14 21:16:31 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-02-11 16:19:27 -07:00
										 |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2018-12-14 21:16:31 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 00:55:58 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * 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']); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-14 21:16:31 -07:00
										 |  |  | 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; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-12-27 14:44:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (strpos($val, "/") === 0) { | 
					
						
							|  |  |  |             // regex
 | 
					
						
							|  |  |  |             $ok[$key] = preg_match($val, $VARS[$key]) === 1; | 
					
						
							| 
									
										
										
										
											2018-12-14 21:16:31 -07:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2018-12-27 14:44:10 -07:00
										 |  |  |             $checkmethod = "is_$val"; | 
					
						
							|  |  |  |             $ok[$key] = !($checkmethod($VARS[$key]) !== true); | 
					
						
							| 
									
										
										
										
											2018-12-14 21:16:31 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |