2016-07-22 20:00:27 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Vn\Web;
|
|
|
|
|
2016-08-22 10:41:05 +00:00
|
|
|
use Vn\Lib;
|
2017-11-29 10:01:48 +00:00
|
|
|
use Vn\Lib\Locale;
|
|
|
|
use Vn\Lib\UserException;
|
2016-08-22 10:41:05 +00:00
|
|
|
|
2016-07-22 20:00:27 +00:00
|
|
|
/**
|
2016-08-22 10:41:05 +00:00
|
|
|
* Base class for REST application.
|
2017-11-29 10:01:48 +00:00
|
|
|
*/
|
2018-05-23 10:14:20 +00:00
|
|
|
class RestService extends Service {
|
|
|
|
function run() {
|
|
|
|
ini_set('display_errors', _ENABLE_DEBUG);
|
|
|
|
set_error_handler([$this, 'errorHandler'], E_ALL);
|
|
|
|
set_exception_handler([$this, 'exceptionHandler']);
|
2016-07-22 20:00:27 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
$this->init();
|
|
|
|
$this->startSession();
|
|
|
|
$this->loadMethod(__NAMESPACE__.'\RestRequest');
|
2016-08-22 10:41:05 +00:00
|
|
|
}
|
2017-11-29 10:01:48 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Runs a REST method.
|
|
|
|
*/
|
2018-05-23 10:14:20 +00:00
|
|
|
function loadMethod($class) {
|
2017-11-29 10:01:48 +00:00
|
|
|
$db = $this->db;
|
2018-05-23 10:14:20 +00:00
|
|
|
$this->login();
|
2017-11-29 10:01:48 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
$method = $this->app->loadMethod(
|
2017-11-29 10:01:48 +00:00
|
|
|
$_REQUEST['method'], $class, './rest');
|
|
|
|
$method->service = $this;
|
|
|
|
|
2022-05-05 13:56:17 +00:00
|
|
|
$isAuthorized = $db->getValue('SELECT myUser_checkRestPriv(#)',
|
|
|
|
[$_REQUEST['method']]);
|
|
|
|
if (!$isAuthorized)
|
|
|
|
throw new ForbiddenException(s('You don\'t have enough privileges'));
|
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
if ($method::SECURITY == Security::DEFINER) {
|
2017-11-29 10:01:48 +00:00
|
|
|
$methodDb = $db;
|
2018-05-23 11:09:55 +00:00
|
|
|
} else
|
2018-05-23 10:14:20 +00:00
|
|
|
$methodDb = $this->getUserDb($_SESSION['user']);
|
2017-11-29 10:01:48 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
if ($method::PARAMS !== NULL && !$method->checkParams($_REQUEST, $method::PARAMS))
|
|
|
|
throw new UserException (s('Missing parameters'));
|
2017-11-29 10:01:48 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
Locale::addPath('rest/'. dirname($_REQUEST['method']));
|
2017-11-29 10:01:48 +00:00
|
|
|
|
|
|
|
$res = NULL;
|
|
|
|
|
|
|
|
try {
|
2018-05-23 10:14:20 +00:00
|
|
|
$res = $method->run($methodDb);
|
2023-01-16 12:59:11 +00:00
|
|
|
} catch (\Vn\Db\Exception $e) {
|
|
|
|
if ($e->getCode() == 1644) {
|
|
|
|
$eMessage = $e->getMessage();
|
|
|
|
$tMessage = $db->getValue(
|
2023-07-28 11:11:33 +00:00
|
|
|
'SELECT IFNULL(i.`description`, m.`description`) `description`
|
|
|
|
FROM `message` m
|
|
|
|
LEFT JOIN `messageI18n` i
|
|
|
|
ON i.`code` = m.`code` AND i.lang = #
|
|
|
|
WHERE m.`code` = #',
|
|
|
|
[Locale::get(), $eMessage]
|
2023-01-16 12:59:11 +00:00
|
|
|
);
|
|
|
|
if (!$tMessage) $tMessage = $eMessage;
|
|
|
|
throw new Lib\UserException($tMessage, $eMessage);
|
|
|
|
}
|
|
|
|
|
|
|
|
throw $e;
|
2017-11-29 10:01:48 +00:00
|
|
|
}
|
|
|
|
|
2018-03-26 16:35:02 +00:00
|
|
|
if ($method::SECURITY == Security::DEFINER)
|
2020-10-23 10:10:41 +00:00
|
|
|
$methodDb->query('CALL account.myUser_logout');
|
2018-03-26 16:35:02 +00:00
|
|
|
|
2020-10-23 10:10:41 +00:00
|
|
|
$db->query('CALL account.myUser_logout');
|
2017-11-29 10:01:48 +00:00
|
|
|
|
|
|
|
return $res;
|
|
|
|
}
|
2016-08-22 10:41:05 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
function statusFromException($e) {
|
2016-08-22 10:41:05 +00:00
|
|
|
try {
|
|
|
|
throw $e;
|
2018-05-23 11:09:55 +00:00
|
|
|
} catch (SessionExpiredException $e) {
|
|
|
|
$status = 401;
|
|
|
|
} catch (BadLoginException $e) {
|
|
|
|
$status = 401;
|
2022-05-05 13:56:17 +00:00
|
|
|
} catch (ForbiddenException $e) {
|
|
|
|
$status = 403;
|
2018-05-23 11:09:55 +00:00
|
|
|
} catch (Lib\UserException $e) {
|
|
|
|
$status = 400;
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
$status = 500;
|
2016-07-22 20:00:27 +00:00
|
|
|
}
|
2016-08-22 10:41:05 +00:00
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
http_response_code($status);
|
2016-08-22 10:41:05 +00:00
|
|
|
}
|
|
|
|
|
2022-05-20 12:20:34 +00:00
|
|
|
function errorHandler($errno, $message, $file, $line, $context = NULL) {
|
2016-08-22 10:41:05 +00:00
|
|
|
$eFlag =
|
|
|
|
E_USER_NOTICE
|
|
|
|
| E_USER_WARNING
|
|
|
|
| E_USER_DEPRECATED
|
|
|
|
| E_NOTICE
|
|
|
|
| E_WARNING
|
|
|
|
| E_DEPRECATED;
|
|
|
|
|
|
|
|
if (!($errno & $eFlag))
|
2018-05-23 10:14:20 +00:00
|
|
|
http_response_code(500);
|
2016-08-22 10:41:05 +00:00
|
|
|
|
|
|
|
return FALSE;
|
2016-07-22 20:00:27 +00:00
|
|
|
}
|
|
|
|
|
2018-05-23 10:14:20 +00:00
|
|
|
function exceptionHandler($e) {
|
|
|
|
$this->statusFromException($e);
|
2016-08-22 10:41:05 +00:00
|
|
|
throw $e;
|
2016-07-22 20:00:27 +00:00
|
|
|
}
|
|
|
|
}
|