Совместимость с новыми логами

This commit is contained in:
n1rwana 2023-08-09 23:58:30 +03:00
parent 032e34a82c
commit 79e3ff4415
No known key found for this signature in database
GPG key ID: 184A60085ABF17D8
5 changed files with 189 additions and 168 deletions

View file

@ -28,7 +28,8 @@ class ChandlerUsers
function getById(string $UUID): ?ChandlerUser function getById(string $UUID): ?ChandlerUser
{ {
return new ChandlerUser($this->users->where("id", $UUID)->fetch()); $user = $this->users->where("id", $UUID)->fetch();
return $user ? new ChandlerUser($user) : NULL;
} }
function getList(int $page = 1): \Traversable function getList(int $page = 1): \Traversable

View file

@ -44,9 +44,9 @@ class Users
return $alias->getUser(); return $alias->getUser();
} }
function getByChandlerUser(ChandlerUser $user): ?User function getByChandlerUser(?ChandlerUser $user): ?User
{ {
return $this->toUser($this->users->where("user", $user->getId())->fetch()); return $user ? $this->toUser($this->users->where("user", $user->getId())->fetch()) : NULL;
} }
function find(string $query, array $pars = [], string $sort = "id DESC"): Util\EntityStream function find(string $query, array $pars = [], string $sort = "id DESC"): Util\EntityStream

View file

@ -3,7 +3,7 @@ namespace openvk\Web\Presenters;
use Chandler\Database\Log; use Chandler\Database\Log;
use Chandler\Database\Logs; use Chandler\Database\Logs;
use openvk\Web\Models\Entities\{Voucher, Gift, GiftCategory, User, BannedLink}; use openvk\Web\Models\Entities\{Voucher, Gift, GiftCategory, User, BannedLink};
use openvk\Web\Models\Repositories\{Bans, ChandlerGroups, ChandlerUsers, Photos, Posts, Users, Clubs, Videos, Vouchers, Gifts, BannedLinks, Logs}; use openvk\Web\Models\Repositories\{Bans, ChandlerGroups, ChandlerUsers, Photos, Posts, Users, Clubs, Videos, Vouchers, Gifts, BannedLinks};
use Chandler\Database\DatabaseConnection; use Chandler\Database\DatabaseConnection;
final class AdminPresenter extends OpenVKPresenter final class AdminPresenter extends OpenVKPresenter

View file

@ -7,11 +7,13 @@ use Nette\Utils\Finder;
use Chandler\Database\DatabaseConnection; use Chandler\Database\DatabaseConnection;
use openvk\Web\Models\Entities\Club; use openvk\Web\Models\Entities\Club;
use openvk\Web\Models\Entities\Comment; use openvk\Web\Models\Entities\Comment;
use openvk\Web\Models\Entities\Log; use Chandler\Database\Log;
use openvk\Web\Models\Entities\NoSpamLog; use openvk\Web\Models\Entities\NoSpamLog;
use openvk\Web\Models\Entities\User; use openvk\Web\Models\Entities\User;
use openvk\Web\Models\Repositories\Logs; use openvk\Web\Models\Repositories\ChandlerUsers;
use Chandler\Database\Logs;
use openvk\Web\Models\Repositories\NoSpamLogs; use openvk\Web\Models\Repositories\NoSpamLogs;
use openvk\Web\Models\Repositories\Users;
final class NoSpamPresenter extends OpenVKPresenter final class NoSpamPresenter extends OpenVKPresenter
{ {
@ -141,7 +143,7 @@ final class NoSpamPresenter extends OpenVKPresenter
$this->assertNoCSRF(); $this->assertNoCSRF();
$this->willExecuteWriteAction(); $this->willExecuteWriteAction();
function searchByAdditionalParams(?string $table = NULL, ?string $where = NULL, ?string $ip = NULL, ?string $useragent = NULL, ?int $ts = NULL, ?int $te = NULL, ?int $user = NULL) function searchByAdditionalParams(?string $table = NULL, ?string $where = NULL, ?string $ip = NULL, ?string $useragent = NULL, ?int $ts = NULL, ?int $te = NULL, $user = NULL)
{ {
$db = DatabaseConnection::i()->getContext(); $db = DatabaseConnection::i()->getContext();
if ($table && ($ip || $useragent || $ts || $te || $user)) { if ($table && ($ip || $useragent || $ts || $te || $user)) {
@ -151,35 +153,49 @@ final class NoSpamPresenter extends OpenVKPresenter
if ($useragent) $conditions[] = "`useragent` REGEXP '$useragent'"; if ($useragent) $conditions[] = "`useragent` REGEXP '$useragent'";
if ($ts) $conditions[] = "`ts` < $ts"; if ($ts) $conditions[] = "`ts` < $ts";
if ($te) $conditions[] = "`ts` > $te"; if ($te) $conditions[] = "`ts` > $te";
if ($user) $conditions[] = "`user` = $user"; if ($user) {
$users = new Users;
$_user = $users->getByChandlerUser((new ChandlerUsers)->getById($user))
?? $users->get((int)$user)
?? $users->getByAddress($user)
?? NULL;
if ($_user) {
$conditions[] = "`user` = '" . $_user->getChandlerGUID() . "'";
}
}
$whereStart = "WHERE `object_table` = '$table'"; $whereStart = "WHERE `object_table` = '$table'";
if ($table === "profiles") { if ($table === "profiles") {
$whereStart .= "AND `type` = 0"; $whereStart .= "AND `type` = 0";
} }
$logs = $db->query("SELECT * FROM `logs` $whereStart AND (" . implode(" AND ", $conditions) . ") GROUP BY `object_id`"); $conditions = count($conditions) > 0 ? "AND (" . implode(" AND ", $conditions) . ")" : "";
$response = []; $response = [];
if (!$where) { if ($conditions) {
foreach ($logs as $log) { $logs = $db->query("SELECT * FROM `ChandlerLogs` $whereStart $conditions GROUP BY `object_id`, `object_model`");
$log = (new Logs)->get($log->id);
$response[] = $log->getObject()->unwrap();
}
} else {
foreach ($logs as $log) {
$log = (new Logs)->get($log->id);
$object = $log->getObject()->unwrap();
if (!$object) continue; if (!$where) {
//exit(var_dump(substr_replace($where, "", 0, strlen(" AND")))); foreach ($logs as $log) {
if (str_starts_with($where, " AND")) { $log = (new Logs)->get($log->id);
$where = substr_replace($where, "", 0, strlen(" AND")); $response[] = $log->getObject()->unwrap();
} }
} else {
foreach ($logs as $log) {
$log = (new Logs)->get($log->id);
$object = $log->getObject()->unwrap();
foreach ($db->query("SELECT * FROM `$table` WHERE $where")->fetchAll() as $o) { if (!$object) continue;
if ($object->id === $o["id"]) { if (str_starts_with($where, " AND")) {
$response[] = $object; $where = substr_replace($where, "", 0, strlen(" AND"));
}
foreach ($db->query("SELECT * FROM `$table` WHERE $where")->fetchAll() as $o) {
if ($object->id === $o["id"]) {
$response[] = $object;
}
} }
} }
} }
@ -190,166 +206,170 @@ final class NoSpamPresenter extends OpenVKPresenter
} }
try { try {
$response = []; $response = [];
$processed = 0; $processed = 0;
$where = $this->postParam("where"); $where = $this->postParam("where");
$ip = $this->postParam("ip"); $ip = $this->postParam("ip");
$useragent = $this->postParam("useragent"); $useragent = $this->postParam("useragent");
$searchTerm = $this->postParam("q"); $searchTerm = $this->postParam("q");
$ts = (int)$this->postParam("ts"); $ts = (int)$this->postParam("ts");
$te = (int)$this->postParam("te"); $te = (int)$this->postParam("te");
$user = (int)$this->postParam("user"); $user = $this->postParam("user");
if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user) if (!$ip && !$useragent && !$searchTerm && !$ts && !$te && !$where && !$searchTerm && !$user)
$this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]); $this->returnJson(["success" => false, "error" => "Нет запроса. Заполните поле \"подстрока\" или введите запрос \"WHERE\" в поле под ним."]);
$models = explode(",", $this->postParam("models")); $models = explode(",", $this->postParam("models"));
foreach ($models as $_model) { foreach ($models as $_model) {
$model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $_model; $model_name = NoSpamPresenter::ENTITIES_NAMESPACE . "\\" . $_model;
if (!class_exists($model_name)) { if (!class_exists($model_name)) {
continue; continue;
}
$model = new $model_name;
$c = new \ReflectionClass($model_name);
if ($c->isAbstract() || $c->getName() == NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") {
continue;
}
$db = DatabaseConnection::i()->getContext();
$table = $model->getTableName();
$columns = $db->getStructure()->getColumns($table);
if ($searchTerm) {
$conditions = [];
$need_deleted = false;
foreach ($columns as $column) {
if ($column["name"] == "deleted") {
$need_deleted = true;
} else {
$conditions[] = "`$column[name]` REGEXP '$searchTerm'";
}
} }
$conditions = implode(" OR ", $conditions);
$model = new $model_name; $where = ($this->postParam("where") ? " AND ($conditions)" : "($conditions)");
if ($need_deleted) $where .= " AND (`deleted` = 0)";
}
$c = new \ReflectionClass($model_name); $rows = [];
if ($c->isAbstract() || $c->getName() == NoSpamPresenter::ENTITIES_NAMESPACE . "\\Correspondence") { if ($ip || $useragent || $ts || $te || $user) {
continue; $rows = searchByAdditionalParams($table, $where, $ip, $useragent, $ts, $te, $user);
} }
$db = DatabaseConnection::i()->getContext(); if (count($rows) === 0) {
$table = $model->getTableName(); if (!$searchTerm) {
$columns = $db->getStructure()->getColumns($table); if (str_starts_with($where, " AND")) {
if ($searchTerm && !$this->postParam("where")) {
if ($searchTerm) { $where = substr_replace($where, "", 0, strlen(" AND"));
$conditions = [];
$need_deleted = false;
foreach ($columns as $column) {
if ($column["name"] == "deleted") {
$need_deleted = true;
} else { } else {
$conditions[] = "`$column[name]` REGEXP '$searchTerm'"; $where = "(" . $this->postParam("where") . ")" . $where;
} }
} }
$conditions = implode(" OR ", $conditions);
$where = ($this->postParam("where") ? " AND ($conditions)" : "($conditions)");
if ($need_deleted) $where .= " AND (`deleted` = 0)";
}
$rows = [];
if ($ip || $useragent || $ts || $te || $user) {
$rows = searchByAdditionalParams($table, $where, $ip, $useragent, $ts, $te, $user);
}
if (count($rows) === 0) {
if (!$searchTerm) {
if (str_starts_with($where, " AND")) {
if ($searchTerm && !$this->postParam("where")) {
$where = substr_replace($where, "", 0, strlen(" AND"));
} else {
$where = "(" . $this->postParam("where") . ")" . $where;
}
}
if (!$where) {
$rows = [];
} else {
$result = $db->query("SELECT * FROM `$table` WHERE $where"); $result = $db->query("SELECT * FROM `$table` WHERE $where");
$rows = $result->fetchAll(); $rows = $result->fetchAll();
} }
} }
if (!in_array((int)$this->postParam("ban"), [1, 2, 3])) {
foreach ($rows as $key => $object) {
$object = (array)$object;
$_obj = [];
foreach ($object as $key => $value) {
foreach ($columns as $column) {
if ($column["name"] === $key && in_array(strtoupper($column["nativetype"]), ["BLOB", "BINARY", "VARBINARY", "TINYBLOB", "MEDIUMBLOB", "LONGBLOB"])) {
$value = "[BINARY]";
break;
}
}
$_obj[$key] = $value;
$_obj["__model_name"] = $_model;
}
$response[] = $_obj;
}
} else {
$ids = [];
foreach ($rows as $object) {
$object = new $model_name($db->table($table)->get($object->id));
if (!$object) continue;
$ids[] = $object->getId();
}
$log = new NoSpamLog;
$log->setUser($this->user->id);
$log->setModel($_model);
if ($searchTerm) {
$log->setRegex($searchTerm);
} else {
$log->setRequest($where);
}
$log->setBan_Type((int)$this->postParam("ban"));
$log->setCount(count($rows));
$log->setTime(time());
$log->setItems(implode(",", $ids));
$log->save();
$banned_ids = [];
foreach ($rows as $object) {
$object = new $model_name($db->table($table)->get($object->id));
if (!$object) continue;
$owner = NULL;
$methods = ["getOwner", "getUser", "getRecipient", "getInitiator"];
if (method_exists($object, "ban")) {
$owner = $object;
} else {
foreach ($methods as $method) {
if (method_exists($object, $method)) {
$owner = $object->$method();
break;
}
}
}
if ($owner instanceof User && $owner->getId() === $this->user->id) {
if (count($rows) === 1) {
$this->returnJson(["success" => false, "error" => "\"Производственная травма\" — Вы не можете блокировать или удалять свой же контент"]);
} else {
continue;
}
}
if (in_array((int)$this->postParam("ban"), [2, 3])) {
if ($owner) {
$_id = ($owner instanceof Club ? $owner->getId() * -1 : $owner->getId());
if (!in_array($_id, $banned_ids)) {
if ($owner instanceof User) {
$owner->ban("**content-noSpamTemplate-" . $log->getId() . "**", false, time() + $owner->getNewBanTime(), $this->user->id);
} else {
$owner->ban("Подозрительная активность");
}
$banned_ids[] = $_id;
}
}
}
if (in_array((int)$this->postParam("ban"), [1, 3]))
$object->delete();
}
$processed++;
}
} }
$this->returnJson(["success" => true, "processed" => $processed, "count" => count($response), "list" => $response]); if (!in_array((int)$this->postParam("ban"), [1, 2, 3])) {
foreach ($rows as $key => $object) {
$object = (array)$object;
$_obj = [];
foreach ($object as $key => $value) {
foreach ($columns as $column) {
if ($column["name"] === $key && in_array(strtoupper($column["nativetype"]), ["BLOB", "BINARY", "VARBINARY", "TINYBLOB", "MEDIUMBLOB", "LONGBLOB"])) {
$value = "[BINARY]";
break;
}
}
$_obj[$key] = $value;
$_obj["__model_name"] = $_model;
}
$response[] = $_obj;
}
} else {
$ids = [];
foreach ($rows as $object) {
$object = new $model_name($db->table($table)->get($object->id));
if (!$object) continue;
$ids[] = $object->getId();
}
$log = new NoSpamLog;
$log->setUser($this->user->id);
$log->setModel($_model);
if ($searchTerm) {
$log->setRegex($searchTerm);
} else {
$log->setRequest($where);
}
$log->setBan_Type((int)$this->postParam("ban"));
$log->setCount(count($rows));
$log->setTime(time());
$log->setItems(implode(",", $ids));
$log->save();
$banned_ids = [];
foreach ($rows as $object) {
$object = new $model_name($db->table($table)->get($object->id));
if (!$object) continue;
$owner = NULL;
$methods = ["getOwner", "getUser", "getRecipient", "getInitiator"];
if (method_exists($object, "ban")) {
$owner = $object;
} else {
foreach ($methods as $method) {
if (method_exists($object, $method)) {
$owner = $object->$method();
break;
}
}
}
if ($owner instanceof User && $owner->getId() === $this->user->id) {
if (count($rows) === 1) {
$this->returnJson(["success" => false, "error" => "\"Производственная травма\" — Вы не можете блокировать или удалять свой же контент"]);
} else {
continue;
}
}
if (in_array((int)$this->postParam("ban"), [2, 3])) {
if ($owner) {
$_id = ($owner instanceof Club ? $owner->getId() * -1 : $owner->getId());
if (!in_array($_id, $banned_ids)) {
if ($owner instanceof User) {
$owner->ban("**content-noSpamTemplate-" . $log->getId() . "**", false, time() + $owner->getNewBanTime(), $this->user->id);
} else {
$owner->ban("Подозрительная активность");
}
$banned_ids[] = $_id;
}
}
}
if (in_array((int)$this->postParam("ban"), [1, 3]))
$object->delete();
}
$processed++;
}
}
$this->returnJson(["success" => true, "processed" => $processed, "count" => count($response), "list" => $response]);
} catch (\Throwable $e) { } catch (\Throwable $e) {
$this->returnJson(["success" => false, "error" => $e->getMessage()]); $this->returnJson(["success" => false, "error" => $e->getMessage()]);
} }

View file

@ -58,7 +58,7 @@
<span class="nobold">Пользователь:</span> <span class="nobold">Пользователь:</span>
</td> </td>
<td> <td>
<input type="text" name="user" placeholder="ID" id="user"> <input type="text" name="user" placeholder="Ссылка на страницу" id="user">
</td> </td>
</tr> </tr>
<tr style="width: 129px"> <tr style="width: 129px">