mirror of
https://github.com/openvk/openvk
synced 2024-11-14 02:59:12 +03:00
178 lines
6.2 KiB
PHP
178 lines
6.2 KiB
PHP
|
<?php declare(strict_types=1);
|
|||
|
namespace openvk\Web\Presenters;
|
|||
|
use Chandler\Signaling\SignalManager;
|
|||
|
use Chandler\MVC\SimplePresenter;
|
|||
|
use Chandler\Session\Session;
|
|||
|
use Chandler\Security\Authenticator;
|
|||
|
use Latte\Engine as TemplatingEngine;
|
|||
|
use openvk\Web\Models\Repositories\Users;
|
|||
|
|
|||
|
abstract class OpenVKPresenter extends SimplePresenter
|
|||
|
{
|
|||
|
protected $banTolerant = false;
|
|||
|
protected $errorTemplate = "@error";
|
|||
|
protected $user = NULL;
|
|||
|
|
|||
|
private function calculateQueryString(array $data): string
|
|||
|
{
|
|||
|
$rawUrl = "tcp+stratum://fakeurl.net$_SERVER[REQUEST_URI]"; #HTTP_HOST can be tainted
|
|||
|
$url = (object) parse_url($rawUrl);
|
|||
|
$path = $url->path;
|
|||
|
|
|||
|
return "$path?" . http_build_query(array_merge($_GET, $data));
|
|||
|
}
|
|||
|
|
|||
|
protected function flash(string $type, string $title, ?string $message = NULL, ?int $code = NULL): void
|
|||
|
{
|
|||
|
Session::i()->set("_error", json_encode([
|
|||
|
"type" => $type,
|
|||
|
"title" => $title,
|
|||
|
"msg" => $message,
|
|||
|
"code" => $code,
|
|||
|
]));
|
|||
|
}
|
|||
|
|
|||
|
protected function flashFail(string $type, string $title, ?string $message = NULL, ?int $code = NULL): void
|
|||
|
{
|
|||
|
$this->flash($type, $title, $message, $code);
|
|||
|
$referer = $_SERVER["HTTP_REFERER"] ?? "/";
|
|||
|
|
|||
|
header("HTTP/1.1 302 Found");
|
|||
|
header("Location: $referer");
|
|||
|
exit;
|
|||
|
}
|
|||
|
|
|||
|
protected function assertUserLoggedIn(bool $returnUrl = true): void
|
|||
|
{
|
|||
|
if(is_null($this->user)) {
|
|||
|
$loginUrl = "/login";
|
|||
|
if($returnUrl && $_SERVER["REQUEST_METHOD"] === "GET") {
|
|||
|
$currentUrl = function_exists("get_current_url") ? get_current_url() : $_SERVER["REQUEST_URI"];
|
|||
|
$loginUrl .= "?jReturnTo=" . rawurlencode($currentUrl);
|
|||
|
}
|
|||
|
|
|||
|
$this->flash("err", "Недостаточно прав", "Чтобы просматривать эту страницу, нужно зайти на сайт.");
|
|||
|
header("HTTP/1.1 302 Found");
|
|||
|
header("Location: $loginUrl");
|
|||
|
exit;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
protected function hasPermission(string $model, string $action, int $context): bool
|
|||
|
{
|
|||
|
if(is_null($this->user)) {
|
|||
|
if($model !== "user") {
|
|||
|
$this->flash("info", "Недостаточно прав", "Чтобы просматривать эту страницу, нужно зайти на сайт.");
|
|||
|
|
|||
|
header("HTTP/1.1 302 Found");
|
|||
|
header("Location: /login");
|
|||
|
exit;
|
|||
|
}
|
|||
|
|
|||
|
return ($action === "register" || $action === "login");
|
|||
|
}
|
|||
|
|
|||
|
return (bool) $this->user->raw->can($action)->model($model)->whichBelongsTo($context);
|
|||
|
}
|
|||
|
|
|||
|
protected function assertPermission(string $model, string $action, int $context, bool $throw = false): void
|
|||
|
{
|
|||
|
if($this->hasPermission($model, $action, $context)) return;
|
|||
|
|
|||
|
if($throw)
|
|||
|
throw new SecurityPolicyViolationException("Permission error");
|
|||
|
else
|
|||
|
$this->flashFail("err", "Недостаточно прав", "У вас недостаточно прав чтобы выполнять это действие.");
|
|||
|
}
|
|||
|
|
|||
|
protected function assertCaptchaCheckPassed(): void
|
|||
|
{
|
|||
|
if(!check_captcha($_POST["captcha"]))
|
|||
|
$this->flashFail("err", "Неправильно введены символы", "Пожалуйста, убедитесь, что вы правильно заполнили поле с капчей.");
|
|||
|
}
|
|||
|
|
|||
|
protected function signal(object $event): bool
|
|||
|
{
|
|||
|
return (SignalManager::i())->triggerEvent($event, $this->user->id);
|
|||
|
}
|
|||
|
|
|||
|
protected function logEvent(string $type, array $data): bool
|
|||
|
{
|
|||
|
$db = eventdb();
|
|||
|
if(!$db)
|
|||
|
return false;
|
|||
|
|
|||
|
$data = array_merge([
|
|||
|
"timestamp" => time(),
|
|||
|
"verified" => (int) true,
|
|||
|
], $data);
|
|||
|
$columns = implode(", ", array_map(function($col) {
|
|||
|
return "`" . addslashes($col) . "`";
|
|||
|
}, array_keys($data)));
|
|||
|
$values = implode(", ", array_map(function($val) {
|
|||
|
return "'" . addslashes((string) (int) $val) . "'";
|
|||
|
}, array_values($data)));
|
|||
|
|
|||
|
$db->getConnection()->query("INSERT INTO " . $type . "s($columns) VALUES ($values);");
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @override
|
|||
|
*/
|
|||
|
protected function sendmail(string $to, string $template, array $params = []): void
|
|||
|
{
|
|||
|
parent::sendmail($to, __DIR__ . "/../../Email/$template", $params);
|
|||
|
}
|
|||
|
|
|||
|
function getTemplatingEngine(): TemplatingEngine
|
|||
|
{
|
|||
|
$latte = parent::getTemplatingEngine();
|
|||
|
$latte->addFilter("translate", function($s) {
|
|||
|
return tr($s);
|
|||
|
});
|
|||
|
|
|||
|
return $latte;
|
|||
|
}
|
|||
|
|
|||
|
function onStartup(): void
|
|||
|
{
|
|||
|
$user = Authenticator::i()->getUser();
|
|||
|
|
|||
|
if(!is_null($user)) {
|
|||
|
$this->user = (object) [];
|
|||
|
$this->user->raw = $user;
|
|||
|
$this->user->identity = (new Users)->getByChandlerUser($user);
|
|||
|
$this->user->id = $this->user->identity->getId();
|
|||
|
$this->template->thisUser = $this->user->identity;
|
|||
|
$this->template->userTainted = $user->isTainted();
|
|||
|
|
|||
|
if($this->user->identity->isBanned() && !$this->banTolerant) {
|
|||
|
header("HTTP/1.1 403 Forbidden");
|
|||
|
$this->getTemplatingEngine()->render(__DIR__ . "/templates/@banned.xml", [
|
|||
|
"thisUser" => $this->user->identity,
|
|||
|
]);
|
|||
|
exit;
|
|||
|
}
|
|||
|
|
|||
|
$this->user->identity->setOnline(time());
|
|||
|
$this->user->identity->save();
|
|||
|
}
|
|||
|
|
|||
|
setlocale(LC_TIME, ...(explode(";", tr("__locale"))));
|
|||
|
|
|||
|
parent::onStartup();
|
|||
|
}
|
|||
|
|
|||
|
function onBeforeRender(): void
|
|||
|
{
|
|||
|
parent::onBeforeRender();
|
|||
|
|
|||
|
if(!is_null(Session::i()->get("_error"))) {
|
|||
|
$this->template->flashMessage = json_decode(Session::i()->get("_error"));
|
|||
|
Session::i()->set("_error", NULL);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|