Bind owned admin transfer requests to the selected database

This commit is contained in:
evgeny committed 2026-10-28 00:58:59 +01:00
1 parent be11fbb8b6
commit 7e412d950a
2 files changed
+32

No files matched your search

@@ -227,6 +227,9 @@ bool gui_bridge_save_member(sqlite3* db, const QString& channel, quint64 node, c
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "member save: invalid GUI request/context"); return false;
}
const QByteArray id = channel.toLatin1(), nick = nickname.toUtf8();
if (ownerJson.size() > 8192 || static_cast<quint64>(nick.size()) + ownerJson.size() + sizeof(MemberEditRequest) + 2 > UINT32_MAX) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "member save: snapshot exceeds allocation/JSON limit"); return false;
}
bool valid = false; quint64 number = channel.toULongLong(&valid);
if (!valid || !number || number > INT64_MAX || QString::number(number) != channel || !++member_sequence) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "member save: invalid channel or exhausted request ID"); return false;
@@ -252,6 +255,31 @@ bool gui_bridge_save_member(sqlite3* db, const QString& channel, quint64 node, c
return true;
}
struct TransferAdminRequest { UTUN_INSTANCE* instance; sqlite3* database; uint64_t node; char channel[64]; };
static void execute_transfer_admin(void* arg) {
auto* request = static_cast<TransferAdminRequest*>(arg);
if (chat_core_get_db(request->instance) == request->database)
chat_core_transfer_admin(request->instance, request->channel, request->node);
else DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: database changed");
u_free(request);
}
bool gui_bridge_transfer_admin(sqlite3* db, const QString& channel, quint64 node) {
bool valid = false; quint64 number = channel.toULongLong(&valid);
if (!db || !node || !valid || !number || number > INT64_MAX || QString::number(number) != channel) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: invalid request"); return false;
}
std::lock_guard<std::mutex> guard(bridge_mutex);
if (!g_inst || !g_ua) { DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: core unavailable"); return false; }
auto* request = static_cast<TransferAdminRequest*>(u_calloc(1, sizeof(TransferAdminRequest)));
if (!request) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: allocation failed"); return false; }
request->instance = g_inst; request->database = db; request->node = node;
const QByteArray id = channel.toLatin1(); memcpy(request->channel, id.constData(), id.size() + 1);
if (post_command(execute_transfer_admin, request, true) < 0) { u_free(request); return false; }
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "admin transfer: queued ch=%s node=%016llx", id.constData(), (unsigned long long)node);
return true;
}
/* ── GuiBridgeReceiver implementation ── */
void GuiBridgeReceiver::processPost(int eventType, QByteArray data) {
+4
View File
@@ -16,3 +16,7 @@ struct sqlite3;
* Аргументы/ошибки логируются без ника, ключей и содержимого JSON. */
bool gui_bridge_save_member(sqlite3* db, const QString& channel, quint64 node, const QString& nickname,
const QByteArray& ownerJson, QObject* context, std::function<void(int)> complete);
/* GUI-only: скопировать команду передачи admin-ключа текущему ядру; db должен совпасть при выполнении.
* true — очередь приняла запрос, не подтверждение доставки ключа; false — отказ с логом без оставшейся памяти. */
bool gui_bridge_transfer_admin(sqlite3* db, const QString& channel, quint64 node);