mirror of
https://github.com/Karaka-Management/oms-OnlineResourceWatcher.git
synced 2026-01-30 16:28:43 +00:00
281 lines
11 KiB
PHP
281 lines
11 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Applications\Api;
|
|
|
|
use Models\CoreSettings;
|
|
use Models\SettingsEnum;
|
|
use Models\AccountMapper;
|
|
use Models\LocalizationMapper;
|
|
use Models\NullAccount;
|
|
use Models\PermissionCategory;
|
|
use phpOMS\Account\Account;
|
|
use phpOMS\Account\AccountManager;
|
|
use phpOMS\Account\PermissionType;
|
|
use phpOMS\Application\ApplicationAbstract;
|
|
use phpOMS\Application\ApplicationStatus;
|
|
use phpOMS\Auth\Auth;
|
|
use phpOMS\DataStorage\Cache\CachePool;
|
|
use phpOMS\DataStorage\Cookie\CookieJar;
|
|
use phpOMS\DataStorage\Database\DatabasePool;
|
|
use phpOMS\DataStorage\Database\Mapper\DataMapperFactory;
|
|
use phpOMS\DataStorage\Session\HttpSession;
|
|
use phpOMS\Dispatcher\Dispatcher;
|
|
use phpOMS\Event\EventManager;
|
|
use phpOMS\Localization\L11nManager;
|
|
use phpOMS\Message\Http\HttpRequest;
|
|
use phpOMS\Message\Http\HttpResponse;
|
|
use phpOMS\Message\Http\RequestStatusCode;
|
|
use phpOMS\Model\Html\Head;
|
|
use phpOMS\Module\ModuleManager;
|
|
use phpOMS\Router\RouteVerb;
|
|
use phpOMS\Router\WebRouter;
|
|
use phpOMS\System\File\PathException;
|
|
use phpOMS\System\MimeType;
|
|
use phpOMS\Uri\UriFactory;
|
|
use phpOMS\Views\View;
|
|
use WebApplication;
|
|
|
|
final class Application
|
|
{
|
|
|
|
private WebApplication $app;
|
|
|
|
private array $config;
|
|
|
|
public function __construct(WebApplication $app, array $config)
|
|
{
|
|
$this->app = $app;
|
|
$this->app->appName = 'Api';
|
|
$this->config = $config;
|
|
UriFactory::setQuery('/app', \strtolower($this->app->appName));
|
|
}
|
|
|
|
public function run(HttpRequest $request, HttpResponse $response): void
|
|
{
|
|
$response->header->set('Content-Type', 'text/plain; charset=utf-8');
|
|
$pageView = new View($this->app->l11nManager, $request, $response);
|
|
|
|
$this->app->l11nManager = new L11nManager($this->app->appName);
|
|
$this->app->dbPool = new DatabasePool();
|
|
$this->app->router = new WebRouter();
|
|
$this->app->router->importFromFile(__DIR__ . '/Routes.php');
|
|
|
|
$this->app->sessionManager = new HttpSession(0);
|
|
$this->app->cookieJar = new CookieJar();
|
|
$this->app->moduleManager = new ModuleManager($this->app, __DIR__ . '/../../Modules/');
|
|
$this->app->dispatcher = new Dispatcher($this->app);
|
|
|
|
$this->app->dbPool->create('core', $this->config['db']['core']['masters']['admin']);
|
|
$this->app->dbPool->create('insert', $this->config['db']['core']['masters']['insert']);
|
|
$this->app->dbPool->create('select', $this->config['db']['core']['masters']['select']);
|
|
$this->app->dbPool->create('update', $this->config['db']['core']['masters']['update']);
|
|
$this->app->dbPool->create('delete', $this->config['db']['core']['masters']['delete']);
|
|
$this->app->dbPool->create('schema', $this->config['db']['core']['masters']['schema']);
|
|
|
|
/* Checking csrf token, if a csrf token is required at all has to be decided in the route or controller */
|
|
if ($request->getData('CSRF') !== null
|
|
&& !\hash_equals($this->app->sessionManager->get('CSRF'), $request->getData('CSRF'))
|
|
) {
|
|
$response->header->status = RequestStatusCode::R_403;
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var \phpOMS\DataStorage\Database\Connection\ConnectionAbstract $con */
|
|
$con = $this->app->dbPool->get();
|
|
DataMapperFactory::db($con);
|
|
|
|
$this->app->cachePool = new CachePool();
|
|
$this->app->appSettings = new CoreSettings();
|
|
$this->app->eventManager = new EventManager($this->app->dispatcher);
|
|
$this->app->eventManager->importFromFile(__DIR__ . '/Hooks.php');
|
|
|
|
$this->app->accountManager = new AccountManager($this->app->sessionManager);
|
|
$this->app->l11nServer = LocalizationMapper::get()->where('id', 1)->execute();
|
|
|
|
$this->app->orgId = $this->getApplicationOrganization($request, $this->config['app']);
|
|
$pageView->setData('orgId', $this->app->orgId);
|
|
|
|
$aid = Auth::authenticate($this->app->sessionManager);
|
|
$request->header->account = $aid;
|
|
$response->header->account = $aid;
|
|
|
|
$account = $this->loadAccount($request);
|
|
|
|
if (!($account instanceof NullAccount)) {
|
|
$response->header->l11n = $account->l11n;
|
|
} elseif ($this->app->sessionManager->get('language') !== null) {
|
|
$response->header->l11n
|
|
->loadFromLanguage(
|
|
$this->app->sessionManager->get('language'),
|
|
$this->app->sessionManager->get('country') ?? '*'
|
|
);
|
|
} elseif ($this->app->cookieJar->get('language') !== null) {
|
|
$response->header->l11n
|
|
->loadFromLanguage(
|
|
$this->app->cookieJar->get('language'),
|
|
$this->app->cookieJar->get('country') ?? '*'
|
|
);
|
|
}
|
|
|
|
UriFactory::setQuery('/lang', $response->getLanguage());
|
|
$response->header->set('content-language', $response->getLanguage(), true);
|
|
|
|
// Cache general settings
|
|
$this->app->appSettings->get(null, [
|
|
SettingsEnum::LOGGING_STATUS, SettingsEnum::CLI_ACTIVE,
|
|
]);
|
|
|
|
$appStatus = (int) ($this->app->appSettings->get(null, SettingsEnum::LOGIN_STATUS)->content ?? 0);
|
|
if ($appStatus === ApplicationStatus::READ_ONLY || $appStatus === ApplicationStatus::DISABLED) {
|
|
if (!$account->hasPermission(PermissionType::CREATE | PermissionType::MODIFY, module: 'Admin', type: PermissionCategory::APP)) {
|
|
if ($request->getRouteVerb() !== RouteVerb::GET) {
|
|
// Application is in read only mode or completely disabled
|
|
// If read only mode is active only GET requests are allowed
|
|
// A user who is part of the admin group is excluded from this rule
|
|
$response->header->status = RequestStatusCode::R_405;
|
|
|
|
return;
|
|
}
|
|
|
|
$this->app->dbPool->remove('admin');
|
|
$this->app->dbPool->remove('insert');
|
|
$this->app->dbPool->remove('update');
|
|
$this->app->dbPool->remove('delete');
|
|
$this->app->dbPool->remove('schema');
|
|
}
|
|
}
|
|
|
|
if (!empty($uris = $request->uri->getQuery('r'))) {
|
|
$this->handleBatchRequest($uris, $request, $response);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->app->moduleManager->initRequestModules($request);
|
|
|
|
// add tpl loading
|
|
$this->app->router->add(
|
|
'/api/tpl/.*',
|
|
function () use ($account, $request, $response): void {
|
|
$appName = \ucfirst($request->getData('app') ?? 'Backend');
|
|
$app = new class() extends ApplicationAbstract
|
|
{
|
|
};
|
|
|
|
$app->appName = $appName;
|
|
$app->dbPool = $this->app->dbPool;
|
|
$app->orgId = $this->app->orgId;
|
|
$app->accountManager = $this->app->accountManager;
|
|
$app->appSettings = $this->app->appSettings;
|
|
$app->l11nManager = new L11nManager($app->appName);
|
|
$app->moduleManager = new ModuleManager($app, __DIR__ . '/../../Modules/');
|
|
$app->dispatcher = new Dispatcher($app);
|
|
$app->eventManager = new EventManager($app->dispatcher);
|
|
$app->router = new WebRouter();
|
|
|
|
$app->eventManager->importFromFile(__DIR__ . '/../' . $appName . '/Hooks.php');
|
|
$app->router->importFromFile(__DIR__ . '/../' . $appName . '/Routes.php');
|
|
|
|
$route = \str_replace('/api/tpl', '/' . $appName, $request->uri->getRoute());
|
|
|
|
$view = new View();
|
|
$view->setTemplate('/Web/Api/index');
|
|
|
|
$response->set('Content', $view);
|
|
$response->get('Content')->setData('head', new Head());
|
|
|
|
$app->l11nManager->loadLanguage(
|
|
$response->getLanguage(),
|
|
'0',
|
|
include __DIR__ . '/../' . $appName . '/lang/' . $response->getLanguage() . '.lang.php'
|
|
);
|
|
|
|
$routed = $app->router->route(
|
|
$route,
|
|
$request->getData('CSRF'),
|
|
$request->getRouteVerb(),
|
|
$appName,
|
|
$this->app->orgId,
|
|
$account,
|
|
$request->getData()
|
|
);
|
|
|
|
$response->get('Content')->setData('dispatch', $app->dispatcher->dispatch($routed, $request, $response));
|
|
},
|
|
RouteVerb::GET
|
|
);
|
|
|
|
$routed = $this->app->router->route(
|
|
$request->uri->getRoute(),
|
|
$request->getData('CSRF'),
|
|
$request->getRouteVerb(),
|
|
$this->app->appName,
|
|
$this->app->orgId,
|
|
$account,
|
|
$request->getData()
|
|
);
|
|
|
|
$dispatched = $this->app->dispatcher->dispatch($routed, $request, $response);
|
|
|
|
if (empty($dispatched)) {
|
|
$response->header->set('Content-Type', MimeType::M_JSON . '; charset=utf-8', true);
|
|
$response->header->status = RequestStatusCode::R_404;
|
|
$response->set($request->uri->__toString(), [
|
|
'status' => \phpOMS\Message\NotificationLevel::ERROR,
|
|
'title' => '',
|
|
'message' => '',
|
|
'response' => [],
|
|
]);
|
|
}
|
|
|
|
$pageView->addData('dispatch', $dispatched);
|
|
}
|
|
|
|
private function loadAccount(HttpRequest $request): Account
|
|
{
|
|
$account = AccountMapper::getWithPermissions($request->header->account);
|
|
$this->app->accountManager->add($account);
|
|
|
|
return $account;
|
|
}
|
|
|
|
private function handleBatchRequest(string $uris, HttpRequest $request, HttpResponse $response): void
|
|
{
|
|
$request_r = clone $request;
|
|
$uris = \json_decode($uris, true);
|
|
|
|
foreach ($uris as $uri) {
|
|
$modules = $this->app->moduleManager->getRoutedModules($request_r);
|
|
$this->app->moduleManager->initModule($modules);
|
|
|
|
$this->app->dispatcher->dispatch(
|
|
$this->app->router->route(
|
|
$request->uri->getRoute(),
|
|
$request->getData('CSRF') ?? null
|
|
),
|
|
$request,
|
|
$response
|
|
);
|
|
}
|
|
}
|
|
|
|
private function getApplicationOrganization(HttpRequest $request, array $config): int
|
|
{
|
|
return (int) ($request->getData('u') ?? ($config['domains'][$request->uri->host]['org'] ?? $config['default']['org']));
|
|
}
|
|
|
|
private function loadLanguageFromPath(string $language, string $path): void
|
|
{
|
|
/* Load theme language */
|
|
if (($absPath = \realpath($path)) === false) {
|
|
throw new PathException($path);
|
|
}
|
|
|
|
/** @noinspection PhpIncludeInspection */
|
|
$themeLanguage = include $absPath;
|
|
$this->app->l11nManager->loadLanguage($language, '0', $themeLanguage);
|
|
}
|
|
}
|