diff --git a/VKAPI/Handlers/Wall.php b/VKAPI/Handlers/Wall.php index 9113eb6e..9e4d9180 100644 --- a/VKAPI/Handlers/Wall.php +++ b/VKAPI/Handlers/Wall.php @@ -21,6 +21,7 @@ use openvk\Web\Models\Entities\Note; use openvk\Web\Models\Repositories\Notes as NotesRepo; use openvk\Web\Models\Repositories\Polls as PollsRepo; use openvk\Web\Models\Repositories\Audios as AudiosRepo; +use openvk\Web\Util\EventRateLimiter; final class Wall extends VKAPIRequestHandler { @@ -723,9 +724,11 @@ final class Wall extends VKAPIRequestHandler } if ($owner_id > 0 && $owner_id !== $this->getUser()->getId()) { - (new WallPostNotification($wallOwner, $post, $this->user->identity))->emit(); + (new WallPostNotification($wallOwner, $post, $this->getUser()->getId()))->emit(); } + EventRateLimiter::i()->writeEvent("wall.post", $this->getUser(), $wallOwner); + return (object) ["post_id" => $post->getVirtualId()]; } diff --git a/Web/Util/EventRateLimiter.php b/Web/Util/EventRateLimiter.php new file mode 100644 index 00000000..80fea28a --- /dev/null +++ b/Web/Util/EventRateLimiter.php @@ -0,0 +1,59 @@ +data = $data; + } + + public function write($edb): bool + { + $edb->getConnection()->query("INSERT INTO `user-events` VALUES (?, ?, ?, ?, ?)", ...array_values($this->data)); + + return true; + } +} + +class EventRateLimiter +{ + use TSimpleSingleton; + + public function writeEvent(string $event_name, User $initiator, ?User $reciever = null): bool + { + $eventsConfig = OPENVK_ROOT_CONF["openvk"]["preferences"]["security"]["rateLimits"]["eventsLimit"]; + if (!$eventsConfig['enable']) { + return false; + } + + if (!($e = eventdb())) { + return false; + } + + $data = [ + 'initiatorId' => $initiator->getId(), + 'initiatorIp' => null, + 'receiverId' => null, + 'eventType' => $event_name, + 'eventTime' => time() + ]; + + if ($reciever) { + $data['receiverId'] = $reciever->getId(); + } + + $newEvent = new UserEvent($data); + $newEvent->write($e); + + return true; + } +} diff --git a/install/sqls/eventdb/00001-events-log.sql b/install/sqls/eventdb/00001-events-log.sql new file mode 100644 index 00000000..dc972bec --- /dev/null +++ b/install/sqls/eventdb/00001-events-log.sql @@ -0,0 +1,8 @@ +CREATE TABLE `user-events` +( + `initiatorId` BIGINT(20) NOT NULL, + `initiatorIp` VARBINARY(16) NULL DEFAULT NULL, + `receiverId` BIGINT(20) NOT NULL, + `eventType` CHAR(25) NOT NULL, + `eventTime` BIGINT(20) NOT NULL +) ENGINE = InnoDB; diff --git a/openvk-example.yml b/openvk-example.yml index 6f26803b..784711ba 100644 --- a/openvk-example.yml +++ b/openvk-example.yml @@ -41,6 +41,15 @@ openvk: maxViolations: 50 maxViolationsAge: 120 autoban: true + eventsLimit: + enable: true + restrictionTime: 86400 + list: + groups.create: 5 + groups.sub: 50 + friends.outgoing_sub: 25 + wall.post: 500 + gifts.send: 20 blacklists: limit: 100 applyToAdmins: true