API interface and first basic API request:
https://phpservermonitor.com/api/?&mod=server_status&key=123456789 https://phpservermonitor.com/api/?&mod=server_status&key=123456789&action=detail&id=14 Created api folder and booter. User database row enhanced by api_auth field, to store user hashcode. Updated router, to hold information whether this is an api request and if is, load specific controller. Then use standard executeMethod to get proper JsonResponse. First implemented API to get list of servers / one server detailpull/812/head
parent
a5312265f8
commit
b7c1c4a29e
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP Server Monitor
|
||||
* Monitor your servers and websites.
|
||||
*
|
||||
* This file is part of PHP Server Monitor.
|
||||
* PHP Server Monitor is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PHP Server Monitor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package phpservermon
|
||||
* @author Pepijn Over <pep@mailbox.org>
|
||||
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
|
||||
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
|
||||
* @version Release: @package_version@
|
||||
* @link http://www.phpservermonitor.org/
|
||||
**/
|
||||
|
||||
require __DIR__.'/../src/bootstrap.php';
|
||||
|
||||
$router->setIsApi(true);
|
||||
|
||||
psm_no_cache();
|
||||
|
||||
$mod = psm_GET('mod');
|
||||
|
||||
try {
|
||||
$router->run($mod);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
// invalid module, try the default one
|
||||
// it that somehow also doesnt exist, we have a bit of an issue
|
||||
// and we really have no reason catch it
|
||||
$router->run(PSM_MODULE_DEFAULT);
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PHP Server Monitor
|
||||
* Monitor your servers and websites.
|
||||
*
|
||||
* This file is part of PHP Server Monitor.
|
||||
* PHP Server Monitor is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* PHP Server Monitor is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @package phpservermon
|
||||
* @author Pepijn Over <pep@mailbox.org>
|
||||
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
|
||||
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
|
||||
* @version Release: @package_version@
|
||||
* @link http://www.phpservermonitor.org/
|
||||
* */
|
||||
/**
|
||||
* Server module. List all servers, return list as JSON.
|
||||
*/
|
||||
|
||||
namespace psm\Module\Server\Controller;
|
||||
|
||||
use psm\Service\Database;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Twig_Environment;
|
||||
|
||||
/**
|
||||
* Description of ApiStatusController
|
||||
*
|
||||
* @author Matej Kminek <matej.kminek@attendees.eu>, 24. 11. 2019
|
||||
*/
|
||||
class ApiStatusController extends AbstractServerController {
|
||||
|
||||
/**
|
||||
* Current server id
|
||||
* @var int|\PDOStatement $server_id
|
||||
*/
|
||||
protected $server_id;
|
||||
|
||||
function __construct(Database $db, Twig_Environment $twig) {
|
||||
parent::__construct($db, $twig);
|
||||
|
||||
$this->server_id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||
|
||||
$this->setActions(array('detail', 'list'), 'list');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the view template
|
||||
*/
|
||||
protected function executeList() {
|
||||
$server = $this->getServers();
|
||||
|
||||
return new JsonResponse($server, Response::HTTP_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the view template
|
||||
*/
|
||||
protected function executeDetail() {
|
||||
var_dump($this->server_id);
|
||||
if(empty($this->server_id)){
|
||||
return new JsonResponse("Not found", Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$server = $this->getServers($this->server_id);
|
||||
|
||||
if (empty($server)) {
|
||||
return $this->runAction('index');
|
||||
}
|
||||
|
||||
return new JsonResponse($server, Response::HTTP_OK);
|
||||
}
|
||||
|
||||
}
|
|
@ -43,6 +43,7 @@ class ServerModule implements ModuleInterface {
|
|||
'log' => __NAMESPACE__.'\Controller\LogController',
|
||||
'status' => __NAMESPACE__.'\Controller\StatusController',
|
||||
'update' => __NAMESPACE__.'\Controller\UpdateController',
|
||||
'api.status' => __NAMESPACE__.'\Controller\ApiStatusController',
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -50,6 +50,12 @@ class Router {
|
|||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Indication whether this request comes from API
|
||||
* @var boolean
|
||||
*/
|
||||
private $isApi = false;
|
||||
|
||||
public function __construct() {
|
||||
$this->container = $this->buildServiceContainer();
|
||||
|
||||
|
@ -80,13 +86,17 @@ class Router {
|
|||
}
|
||||
$this->buildTwigEnvironment();
|
||||
|
||||
$controller = $this->getController($mod, $controller);
|
||||
$controller = $this->isApi ? $this->getController($mod, $controller, true) : $this->getController($mod, $controller);
|
||||
$action = null;
|
||||
|
||||
try {
|
||||
$this->validateRequest($controller);
|
||||
} catch (\InvalidArgumentException $ex) {
|
||||
switch ($ex->getMessage()) {
|
||||
case 'invalid_api_key':
|
||||
$controller = $this->getController('error');
|
||||
$action = '403';
|
||||
break;
|
||||
case 'login_required':
|
||||
$controller = $this->getController('user', 'login');
|
||||
break;
|
||||
|
@ -114,12 +124,17 @@ class Router {
|
|||
* @return \psm\Module\ControllerInterface
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function getController($module_id, $controller_id = null) {
|
||||
public function getController($module_id, $controller_id = null, $isApi = false) {
|
||||
if ($controller_id === null) {
|
||||
// by default, we use the controller with the same id as the module.
|
||||
$controller_id = $module_id;
|
||||
}
|
||||
|
||||
if ($isApi) {
|
||||
// if this is an api request, serve api.controller
|
||||
$controller_id = "api." . $controller_id;
|
||||
}
|
||||
|
||||
$module = $this->container->get('module.'.$module_id);
|
||||
$controllers = $module->getControllers();
|
||||
if (!isset($controllers[$controller_id]) || !class_exists($controllers[$controller_id])) {
|
||||
|
@ -156,6 +171,10 @@ class Router {
|
|||
protected function validateRequest(\psm\Module\ControllerInterface $controller) {
|
||||
$request = Request::createFromGlobals();
|
||||
|
||||
if($this->isApi){
|
||||
return $this->validateApiRequest($controller, $request);
|
||||
}
|
||||
|
||||
if ($request->getMethod() == 'POST') {
|
||||
// require CSRF token for all POST calls
|
||||
$session = $this->container->get('user')->getSession();
|
||||
|
@ -189,6 +208,23 @@ class Router {
|
|||
}
|
||||
}
|
||||
|
||||
private function validateApiRequest(\psm\Module\ControllerInterface $controller, Request $request) {
|
||||
$result = $controller->getUser()->loginWithApiKey($request->query->get("key"));
|
||||
|
||||
if (!$result) {
|
||||
throw new \InvalidArgumentException('invalid_api_key');
|
||||
}
|
||||
|
||||
// get min required level for this controller and make sure the user matches
|
||||
$min_lvl = $controller->getMinUserLevelRequired();
|
||||
|
||||
if ($min_lvl < PSM_USER_ANONYMOUS) {
|
||||
// if user is not logged in, load login module
|
||||
if ($this->container->get('user')->getUserLevel() > $min_lvl) {
|
||||
throw new \InvalidArgumentException('invalid_user_level');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a new service container
|
||||
|
@ -234,4 +270,14 @@ class Router {
|
|||
|
||||
return $twig;
|
||||
}
|
||||
|
||||
public function getIsApi() {
|
||||
return $this->isApi;
|
||||
}
|
||||
|
||||
public function setIsApi($isApi) {
|
||||
$this->isApi = $isApi;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
|
@ -147,6 +147,23 @@ class User {
|
|||
return $query_user->fetchObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search into database for the user data of api key specified as parameter
|
||||
* @return object|boolean user data as an object if existing user
|
||||
*/
|
||||
public function getUserByApiKey($key) {
|
||||
if(empty($key)){
|
||||
return null;
|
||||
}
|
||||
|
||||
// database query, getting all the info of the selected user
|
||||
$query_user = $this->db_connection->prepare('SELECT * FROM '.PSM_DB_PREFIX.'users WHERE api_hash = :api_hash');
|
||||
$query_user->bindValue(':api_hash', $key, \PDO::PARAM_STR);
|
||||
$query_user->execute();
|
||||
// get result row (as an object)
|
||||
return $query_user->fetchObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs in with SESSION data.
|
||||
*
|
||||
|
@ -169,6 +186,27 @@ class User {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs in via the api key
|
||||
* @return bool success state of cookie login
|
||||
*/
|
||||
public function loginWithApiKey($key) {
|
||||
$apiKey = trim($key);
|
||||
|
||||
if (empty($apiKey)) {
|
||||
return false;
|
||||
}
|
||||
$user = $this->getUserByApiKey($apiKey);
|
||||
|
||||
if (empty($user)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setUserLoggedIn($user->user_id, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs in via the Cookie
|
||||
* @return bool success state of cookie login
|
||||
|
|
|
@ -186,6 +186,7 @@ class Installer {
|
|||
`password_reset_hash` char(40) DEFAULT NULL COMMENT 'user''s password reset code',
|
||||
`password_reset_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of the password reset request',
|
||||
`rememberme_token` varchar(64) DEFAULT NULL COMMENT 'user''s remember-me cookie token',
|
||||
`api_hash` varchar(255) DEFAULT NULL COMMENT 'user''s hash key to validate API requests',
|
||||
`level` tinyint(2) unsigned NOT NULL DEFAULT '20',
|
||||
`name` varchar(255) NOT NULL,
|
||||
`mobile` varchar(15) NOT NULL,
|
||||
|
|
Loading…
Reference in New Issue