mirror of
https://github.com/openvk/openvk
synced 2025-07-01 13:38:15 +03:00
draft no.0,33
This commit is contained in:
parent
5898b9a455
commit
c3b1e46909
6 changed files with 69 additions and 75 deletions
|
@ -620,10 +620,6 @@ final class Wall extends VKAPIRequestHandler
|
|||
return (object) ["post_id" => $post->getVirtualId()];
|
||||
}
|
||||
|
||||
if (\openvk\Web\Util\EventRateLimiter::i()->tryToLimit($this->getUser(), "wall.post", false)) {
|
||||
$this->failTooOften();
|
||||
}
|
||||
|
||||
$anon = OPENVK_ROOT_CONF["openvk"]["preferences"]["wall"]["anonymousPosting"]["enable"];
|
||||
if ($wallOwner instanceof Club && $from_group == 1 && $signed != 1 && $anon) {
|
||||
$manager = $wallOwner->getManager($this->getUser());
|
||||
|
@ -717,6 +713,10 @@ final class Wall extends VKAPIRequestHandler
|
|||
$post->setSuggested(1);
|
||||
}
|
||||
|
||||
if (\openvk\Web\Util\EventRateLimiter::i()->tryToLimit($this->getUser(), "wall.post")) {
|
||||
$this->failTooOften();
|
||||
}
|
||||
|
||||
$post->save();
|
||||
} catch (\LogicException $ex) {
|
||||
$this->fail(100, "One of the parameters specified was missing or invalid");
|
||||
|
@ -730,8 +730,6 @@ final class Wall extends VKAPIRequestHandler
|
|||
(new WallPostNotification($wallOwner, $post, $this->getUser()))->emit();
|
||||
}
|
||||
|
||||
\openvk\Web\Util\EventRateLimiter::i()->writeEvent("wall.post", $this->getUser(), $wallOwner);
|
||||
|
||||
return (object) ["post_id" => $post->getVirtualId()];
|
||||
}
|
||||
|
||||
|
|
|
@ -1740,41 +1740,56 @@ class User extends RowModel
|
|||
return DatabaseConnection::i()->getContext()->table("blacklist_relations")->where("author", $this->getId())->count();
|
||||
}
|
||||
|
||||
public function recieveEventsData(array $list): array
|
||||
public function getEventCounters(array $list): array
|
||||
{
|
||||
$ev_str = $this->getRecord()->events_counters;
|
||||
$values = [];
|
||||
$counters = [];
|
||||
$compared_counters = [];
|
||||
|
||||
if (!$ev_str) {
|
||||
bdump(sizeof(array_keys($list)));
|
||||
for ($i = 0; $i < sizeof(array_keys($list)); $i++) {
|
||||
$values[] = 0;
|
||||
$counters[] = 0;
|
||||
}
|
||||
} else {
|
||||
$keys = array_keys($list);
|
||||
$values = unpack("S*", base64_decode($ev_str));
|
||||
$counters = unpack("S*", base64_decode($ev_str));
|
||||
}
|
||||
|
||||
$i = 1;
|
||||
|
||||
foreach ($list as $name => $value) {
|
||||
$compared_counters[$name] = $counters[$i] ?? 0;
|
||||
$i += 1;
|
||||
}
|
||||
|
||||
bdump($counters);
|
||||
bdump($compared_counters);
|
||||
return [
|
||||
'counters' => $values,
|
||||
'counters' => $compared_counters,
|
||||
'refresh_time' => $this->getRecord()->events_refresh_time,
|
||||
];
|
||||
}
|
||||
|
||||
public function stateEvents(array $list): void
|
||||
public function stateEvents(array $state_list): void
|
||||
{
|
||||
$this->stateChanges("events_counters", base64_encode(pack("S*", array_values($list))));
|
||||
bdump($state_list);
|
||||
$this->stateChanges("events_counters", base64_encode(pack("S*", ...array_values($state_list))));
|
||||
|
||||
if (!$this->getRecord()->events_refresh_time) {
|
||||
$this->stateChanges("events_refresh_time", time());
|
||||
}
|
||||
}
|
||||
|
||||
public function resetEvents(array $list, int $restriction_length)
|
||||
public function resetEvents(array $list)
|
||||
{
|
||||
$values = [];
|
||||
|
||||
for ($i = 0; $i < sizeof(array_keys($list)); $i++) {
|
||||
$values[] = 0;
|
||||
foreach ($list as $key => $val) {
|
||||
$values[$key] = 0;
|
||||
}
|
||||
|
||||
$this->stateEvents($values);
|
||||
$this->stateChanges("events_refresh_time", $restriction_length + time());
|
||||
$this->stateChanges("events_refresh_time", time());
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ final class GiftsPresenter extends OpenVKPresenter
|
|||
return;
|
||||
}
|
||||
|
||||
if (\openvk\Web\Util\EventRateLimiter::i()->tryToLimit($this->user->identity, "gifts.send", false)) {
|
||||
if (\openvk\Web\Util\EventRateLimiter::i()->tryToLimit($this->user->identity, "gifts.send")) {
|
||||
$this->flashFail("err", tr("error"), tr("limit_exceed_exception"));
|
||||
}
|
||||
|
||||
|
|
|
@ -63,15 +63,15 @@ final class GroupPresenter extends OpenVKPresenter
|
|||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
if (!empty($this->postParam("name")) && mb_strlen(trim($this->postParam("name"))) > 0) {
|
||||
if (\openvk\Web\Util\EventRateLimiter::i()->tryToLimit($this->user->identity, "groups.create")) {
|
||||
$this->flashFail("err", tr("error"), tr("limit_exceed_exception"));
|
||||
}
|
||||
|
||||
$club = new Club();
|
||||
$club->setName($this->postParam("name"));
|
||||
$club->setAbout(empty($this->postParam("about")) ? null : $this->postParam("about"));
|
||||
$club->setOwner($this->user->id);
|
||||
|
||||
if (\openvk\Web\Util\EventRateLimiter::i()->tryToLimit($this->user->identity, "groups.create")) {
|
||||
$this->flashFail("err", tr("error"), tr("limit_exceed_exception"));
|
||||
}
|
||||
|
||||
try {
|
||||
$club->save();
|
||||
} catch (\PDOException $ex) {
|
||||
|
|
|
@ -356,6 +356,10 @@ final class WallPresenter extends OpenVKPresenter
|
|||
$this->flashFail("err", tr("failed_to_publish_post"), tr("post_is_empty_or_too_big"));
|
||||
}
|
||||
|
||||
if (\openvk\Web\Util\EventRateLimiter::i()->tryToLimit($this->user->identity, "wall.post")) {
|
||||
$this->flashFail("err", tr("error"), tr("limit_exceed_exception"));
|
||||
}
|
||||
|
||||
$should_be_suggested = $wall < 0 && !$wallOwner->canBeModifiedBy($this->user->identity) && $wallOwner->getWallType() == 2;
|
||||
try {
|
||||
$post = new Post();
|
||||
|
|
|
@ -13,19 +13,18 @@ class EventRateLimiter
|
|||
use TSimpleSingleton;
|
||||
|
||||
private $config;
|
||||
private $availableFields;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]["eventsLimit"];
|
||||
|
||||
$this->availableFields = array_keys($this->config['list']);
|
||||
}
|
||||
|
||||
/*
|
||||
Checks count of actions for last hours
|
||||
Checks count of actions for last x seconds.
|
||||
|
||||
Uses config path OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]["eventsLimit"]
|
||||
Uses OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]["eventsLimit"]
|
||||
|
||||
This check should be peformed only after checking other conditions cuz by default it increments counter
|
||||
|
||||
Returns:
|
||||
|
||||
|
@ -33,8 +32,9 @@ class EventRateLimiter
|
|||
|
||||
false — the action can be performed
|
||||
*/
|
||||
public function tryToLimit(?User $user, string $event_type, bool $distinct = true): bool
|
||||
public function tryToLimit(?User $user, string $event_type, bool $is_update = true): bool
|
||||
{
|
||||
bdump("TRY TO LIMIT IS CALLLLED");
|
||||
$isEnabled = $this->config['enable'];
|
||||
$isIgnoreForAdmins = $this->config['ignoreForAdmins'];
|
||||
$restrictionTime = $this->config['restrictionTime'];
|
||||
|
@ -49,74 +49,51 @@ class EventRateLimiter
|
|||
}
|
||||
|
||||
$limitForThatEvent = $eventsList[$event_type];
|
||||
$stat = $this->getEvent($event_type, $user);
|
||||
bdump($stat);
|
||||
$eventsStats = $user->getEventCounters($eventsList);
|
||||
|
||||
$is_restrict_over = $stat["refresh_time"] < time() - $restrictionTime;
|
||||
$counters = $eventsStats["counters"];
|
||||
$refresh_time = $eventsStats["refresh_time"];
|
||||
$is_restrict_over = $refresh_time < (time() - $restrictionTime);
|
||||
bdump($refresh_time);
|
||||
bdump("time: " . time());
|
||||
$event_counter = $counters[$event_type];
|
||||
|
||||
if ($is_restrict_over) {
|
||||
$user->resetEvents($eventsList, $restrictionTime);
|
||||
if ($refresh_time && $is_restrict_over) {
|
||||
bdump("RESETTING EVENT COUTNERS");
|
||||
$user->resetEvents($eventsList);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$is = $stat["compared"] > $limitForThatEvent;
|
||||
$is_limit_exceed = $event_counter > $limitForThatEvent;
|
||||
|
||||
if ($is === false) {
|
||||
$this->incrementEvent($event_type, $user);
|
||||
bdump($is_limit_exceed);
|
||||
if (!$is_limit_exceed && $is_update) {
|
||||
$this->incrementEvent($counters, $event_type, $user);
|
||||
}
|
||||
|
||||
return $is;
|
||||
}
|
||||
|
||||
public function getEvent(string $event_type, User $by_user): array
|
||||
{
|
||||
$ev_data = $by_user->recieveEventsData($this->config['list']);
|
||||
$values = $ev_data['counters'];
|
||||
$i = 0;
|
||||
|
||||
$compared = [];
|
||||
bdump($values);
|
||||
|
||||
foreach ($this->config['list'] as $name => $value) {
|
||||
bdump($value);
|
||||
$compared[$name] = $values[$i];
|
||||
$i += 1;
|
||||
}
|
||||
|
||||
return [
|
||||
"compared" => $compared,
|
||||
"refresh_time" => $ev_data["refresh_time"]
|
||||
];
|
||||
return $is_limit_exceed;
|
||||
}
|
||||
|
||||
/*
|
||||
Updates counter for user
|
||||
*/
|
||||
public function incrementEvent(string $event_type, User $initiator): bool
|
||||
public function incrementEvent(array $old_values, string $event_type, User $initiator): bool
|
||||
{
|
||||
bdump("INCREMENT IS CALLED");
|
||||
$isEnabled = $this->config['enable'];
|
||||
$eventsList = OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]["eventsLimit"];
|
||||
$eventsList = $this->config['list'];
|
||||
|
||||
if (!$isEnabled) {
|
||||
return false;
|
||||
}
|
||||
bdump($old_values);
|
||||
|
||||
$ev_data = $initiator->recieveEventsData($eventsList);
|
||||
$values = $ev_data['counters'];
|
||||
$i = 0;
|
||||
$old_values[$event_type] += 1;
|
||||
|
||||
$compared = [];
|
||||
|
||||
foreach ($eventsList as $name => $value) {
|
||||
$compared[$name] = $values[$i];
|
||||
$i += 1;
|
||||
}
|
||||
|
||||
$compared[$event_type] += 1;
|
||||
|
||||
bdump($compared);
|
||||
$initiator->stateEvents($compared);
|
||||
bdump($old_values);
|
||||
$initiator->stateEvents($old_values);
|
||||
$initiator->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue