diff --git a/tests/test_chat_join.c b/tests/test_chat_join.c index 354cd2de5..3a2fb6fc1 100644 --- a/tests/test_chat_join.c +++ b/tests/test_chat_join.c @@ -124,6 +124,20 @@ static void make_channel(sqlite3* db, const char* ch_id, topo_node_sqlite_channel_put(db, ch_id, "test", 0, ch_x_pub, ch_x_priv, ch_ed_pub, ch_ed_priv, ch_sig); } +/* Готовое членство подписывается группой; admin разрешает тестовые регистрации в исходном строгом режиме. */ +static void seed_admin(struct UTUN_INSTANCE* dst, struct UTUN_INSTANCE* author, const char* channel, + const uint8_t x[32], const uint8_t ed[32], const uint8_t private[32]) { + uint8_t join[64], tree[64], role[64], body[256]; + const char* tags = "{\"ver\":\"1\",\"admin\":\"e1\"}"; + int n = member_sync_build_join_msg(x, ed, author->node_id, author->my_keys.public_key, 1, body, sizeof(body)); + assert(n > 0 && sc_ed25519_sign(author->my_ed25519_privkey, body, n, join) == SC_OK); + assert(!member_sync_sign_join(private, join, tree)); + n = member_sync_build_owner_msg(author->node_id, tags, body, sizeof(body)); + assert(n > 0 && sc_ed25519_sign(private, body, n, role) == SC_OK); + assert(member_sync_put(dst, channel, author->node_id, author->my_keys.public_key, author->my_ed25519_pubkey, + join, 1, NULL, 0, "{\"name\":\"node\"}", tags, role, 0, 0, tree) >= 0); +} + /* ── джойнер: ключи + join_sig + сериализованный member-блок ── */ struct joiner { @@ -404,6 +418,7 @@ static void t_process_request(void) { uint8_t ch_x_pub[32], ch_x_priv[32], ch_ed_pub[32], ch_ed_priv[32]; make_channel(db, CH_COMP, ch_x_pub, ch_x_priv, ch_ed_pub, ch_ed_priv); + seed_admin(inst, inst, CH_COMP, ch_x_pub, ch_ed_pub, ch_ed_priv); (void)ch_x_priv; (void)ch_ed_priv; /* инвайтер (self) в nodes — чтобы verify_signature резолвил signed_by */ topo_node_sqlite_node_update_verified(db, inst->node_id, "inviter", @@ -435,7 +450,7 @@ static void t_process_request(void) { int in_ch = topo_node_sqlite_member_in_channel(db, CH_COMP, j.node_id); int gs = topo_node_sqlite_member_get_sign(db, CH_COMP, j.node_id, &sb, sig); struct ms_member_rec rec; memset(&rec, 0, sizeof(rec)); - rec.x25519 = j.x_pub; rec.signature = sig; rec.signed_by = sb; + rec.node_id = j.node_id; rec.x25519 = j.x_pub; rec.join_sig = j.join_sig; rec.signature = sig; rec.signed_by = sb; int vs = (gs == 0) ? member_sync_verify_signature(db, CH_COMP, &rec) : -99; if (in_ch == 1 && gs == 0 && sb == inst->node_id && vs == 1 && join_results == 1) OK(); @@ -500,6 +515,7 @@ static void t_validate_pubkey(void) { uint8_t ch_x_pub[32], ch_x_priv[32], ch_ed_pub[32], ch_ed_priv[32]; make_channel(db, "61616161616", ch_x_pub, ch_x_priv, ch_ed_pub, ch_ed_priv); + seed_admin(inst, inst, "61616161616", ch_x_pub, ch_ed_pub, ch_ed_priv); (void)ch_x_priv; (void)ch_ed_priv; struct joiner j; make_joiner(&j, ch_x_pub, ch_ed_pub); @@ -718,9 +734,7 @@ static void t_integration(void) { if (!topo_groups_find(g_inst[i]->topo_groups, g_group_id)) topo_groups_create_group(g_inst[i]->topo_groups, g_group_id, TOPO_GROUP_TYPE_CHAT, CH_INT); for (int m = 0; m < 2; m++) { - member_sync_put(g_inst[i], CH_INT, g_nid[m], - g_inst[m]->my_keys.public_key, g_inst[m]->my_ed25519_pubkey, - NULL, 0, NULL, 0, "{\"name\":\"node\"}", NULL, NULL, 0, 0, NULL); + seed_admin(g_inst[i], g_inst[m], CH_INT, ch_x_pub, ch_ed_pub, ch_ed_priv); topo_node_sqlite_node_update_verified(g_inst[i]->topo_sqlite_db, g_nid[m], "node", g_inst[m]->my_keys.public_key, g_inst[m]->my_ed25519_pubkey, (uint64_t)time(NULL), time(NULL)); diff --git a/tests/test_chat_join_e2e.c b/tests/test_chat_join_e2e.c index 358ef4c99..a9f93b92a 100644 --- a/tests/test_chat_join_e2e.c +++ b/tests/test_chat_join_e2e.c @@ -608,7 +608,7 @@ static int child_main(const char* role, const char* dir, int invalid_key) { uint64_t sb = 0; uint8_t sig[64]; memset(sig, 0, sizeof(sig)); topo_node_sqlite_member_get_sign(db, g_sh.ch_id, g_sh.nid[IDX_J], &sb, sig); struct ms_member_rec rec; memset(&rec, 0, sizeof(rec)); - rec.x25519 = g_sh.x_pub[IDX_J]; rec.signature = sig; rec.signed_by = sb; + rec.node_id = g_sh.nid[IDX_J]; rec.x25519 = g_sh.x_pub[IDX_J]; rec.signature = sig; rec.signed_by = sb; if (member_sync_verify_signature(db, g_sh.ch_id, &rec) != 1) { fprintf(stderr, "A: J signature invalid\n"); goto out; } @@ -638,7 +638,7 @@ static int child_main(const char* role, const char* dir, int invalid_key) { uint64_t sb = 0; uint8_t sig[64]; memset(sig, 0, sizeof(sig)); topo_node_sqlite_member_get_sign(db, g_sh.ch_id, g_sh.nid[IDX_J], &sb, sig); struct ms_member_rec rec; memset(&rec, 0, sizeof(rec)); - rec.x25519 = g_sh.x_pub[IDX_J]; rec.signature = sig; rec.signed_by = sb; + rec.node_id = g_sh.nid[IDX_J]; rec.x25519 = g_sh.x_pub[IDX_J]; rec.signature = sig; rec.signed_by = sb; if (member_sync_verify_signature(db, g_sh.ch_id, &rec) != 1) { fprintf(stderr, "C: J signature invalid\n"); goto out; } diff --git a/tools/chatgui/tests/test_group_avatars.cpp b/tools/chatgui/tests/test_group_avatars.cpp index ed8b0a506..97a3de2dc 100644 --- a/tools/chatgui/tests/test_group_avatars.cpp +++ b/tools/chatgui/tests/test_group_avatars.cpp @@ -28,6 +28,11 @@ extern "C" int gui_bridge_post_uasync_owned_fn(void (*fn)(void*), void* arg) { if (!instance) return -1; uasync_call_soon(instance->ua, arg, fn); return 0; } +extern "C" int gui_bridge_post_bound_fn(void (*fn)(void*), void* arg, UTUN_INSTANCE** binding) { + if (!instance) return -1; + *binding = instance; return gui_bridge_post_uasync_owned_fn(fn, arg); +} +extern "C" void gui_bridge_set_group_policy_result_cb(gui_dm_messages_fn) {} static void coreEvent(UTUN_INSTANCE*, int type, const uint8_t* data, int length) { if (type == CHAT_EVT_GROUP_AVATAR_RESULT && GroupAvatarManager::instance()) GroupAvatarManager::instance()->onResult(data, length); if (type == CHAT_EVT_CHANNEL_DELETED && length > 1 && length == 1 + data[0])