diff --git a/src/jamidht/contact_list.cpp b/src/jamidht/contact_list.cpp index 49328d3a28f6650e963140f2958989cee3fb0a61..755327a16d299a1849ea27234e18af369d44ceec 100644 --- a/src/jamidht/contact_list.cpp +++ b/src/jamidht/contact_list.cpp @@ -114,6 +114,7 @@ ContactList::removeContact(const dht::InfoHash& h, bool ban) else if (not c->second.isActive() and c->second.banned == ban) return false; c->second.removed = std::time(nullptr); + c->second.confirmed = false; c->second.banned = ban; auto uri = h.toString(); trust_.setCertificateStatus(uri, diff --git a/src/jamidht/conversation_module.cpp b/src/jamidht/conversation_module.cpp index 03b94154612b6a21ffb708484def324c9667071a..841ded0512526e5f5b0d7815d370f6fa59dec5d5 100644 --- a/src/jamidht/conversation_module.cpp +++ b/src/jamidht/conversation_module.cpp @@ -1686,7 +1686,7 @@ ConversationModule::isBannedDevice(const std::string& convId, const std::string& } void -ConversationModule::removeContact(const std::string& uri, bool) +ConversationModule::removeContact(const std::string& uri, bool banned) { // Remove linked conversation's requests { @@ -1706,6 +1706,8 @@ ConversationModule::removeContact(const std::string& uri, bool) if (update) pimpl_->saveConvRequests(); } + if (banned) + return; // Keep the conversation in banned model // Remove related conversation auto isSelf = uri == pimpl_->username_; std::vector<std::string> toRm; diff --git a/test/unitTest/conversation/conversationMembersEvent.cpp b/test/unitTest/conversation/conversationMembersEvent.cpp index 9c4ad3845a8c6c602023abd05b0e107ba107ed1d..4e47c28a65381c2a4d0450e1f8133a6b8645e3f6 100644 --- a/test/unitTest/conversation/conversationMembersEvent.cpp +++ b/test/unitTest/conversation/conversationMembersEvent.cpp @@ -85,6 +85,7 @@ public: void testAvoidTwoOneToOneMultiDevices(); void testRemoveRequestBannedMultiDevices(); void testBanUnbanMultiDevice(); + void testBanUnbanGotFirstConv(); std::string aliceId; std::string bobId; @@ -123,6 +124,7 @@ private: CPPUNIT_TEST(testAvoidTwoOneToOneMultiDevices); CPPUNIT_TEST(testRemoveRequestBannedMultiDevices); CPPUNIT_TEST(testBanUnbanMultiDevice); + CPPUNIT_TEST(testBanUnbanGotFirstConv); CPPUNIT_TEST_SUITE_END(); }; @@ -2389,6 +2391,135 @@ ConversationMembersEventTest::testBanUnbanMultiDevice() cv.wait_for(lk, 30s, [&]() { return conversationReadyBob && conversationReadyBob2; })); } +void +ConversationMembersEventTest::testBanUnbanGotFirstConv() +{ + auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId); + auto bobAccount = Manager::instance().getAccount<JamiAccount>(bobId); + auto bobUri = bobAccount->getUsername(); + auto aliceUri = aliceAccount->getUsername(); + + std::mutex mtx; + std::unique_lock<std::mutex> lk {mtx}; + std::condition_variable cv; + std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>> confHandlers; + auto requestReceived = false, requestReceivedBob2 = false; + confHandlers.insert( + DRing::exportable_callback<DRing::ConversationSignal::ConversationRequestReceived>( + [&](const std::string& accountId, + const std::string& conversationId, + std::map<std::string, std::string> /*metadatas*/) { + if (accountId == bobId) + requestReceived = true; + else if (accountId == bob2Id) + requestReceivedBob2 = true; + cv.notify_one(); + })); + std::string convId; + auto conversationReadyBob = false, conversationReadyBob2 = false; + confHandlers.insert(DRing::exportable_callback<DRing::ConversationSignal::ConversationReady>( + [&](const std::string& accountId, const std::string& conversationId) { + if (accountId == aliceId) { + convId = conversationId; + } else if (accountId == bobId && conversationId == convId) { + conversationReadyBob = true; + } else if (accountId == bob2Id && conversationId == convId) { + conversationReadyBob2 = true; + } + cv.notify_one(); + })); + auto bob2Started = false; + confHandlers.insert( + DRing::exportable_callback<DRing::ConfigurationSignal::VolatileDetailsChanged>( + [&](const std::string& accountId, const std::map<std::string, std::string>& details) { + if (accountId == bob2Id) { + auto daemonStatus = details.at( + DRing::Account::VolatileProperties::DEVICE_ANNOUNCED); + if (daemonStatus == "true") + bob2Started = true; + } + cv.notify_one(); + })); + auto bob2ContactRemoved = false; + confHandlers.insert(DRing::exportable_callback<DRing::ConfigurationSignal::ContactRemoved>( + [&](const std::string& accountId, const std::string& uri, bool banned) { + if (accountId == bob2Id && uri == aliceUri && banned) { + bob2ContactRemoved = true; + } + cv.notify_one(); + })); + auto bobMsgReceived = false, bob2MsgReceived = false; + confHandlers.insert(DRing::exportable_callback<DRing::ConversationSignal::MessageReceived>( + [&](const std::string& accountId, + const std::string& conversationId, + std::map<std::string, std::string> message) { + if (accountId == bobId && conversationId == convId) + bobMsgReceived = true; + else if (accountId == bob2Id && conversationId == convId) + bob2MsgReceived = true; + cv.notify_one(); + })); + auto contactAddedBob = false, contactAddedBob2 = false; + confHandlers.insert(DRing::exportable_callback<DRing::ConfigurationSignal::ContactAdded>( + [&](const std::string& accountId, const std::string& uri, bool) { + if (accountId == bobId && uri == aliceUri) { + contactAddedBob = true; + } else if (accountId == bob2Id && uri == aliceUri) { + contactAddedBob2 = true; + } + cv.notify_one(); + })); + DRing::registerSignalHandlers(confHandlers); + + // Bob creates a second device + auto bobArchive = std::filesystem::current_path().string() + "/bob.gz"; + std::remove(bobArchive.c_str()); + bobAccount->exportArchive(bobArchive); + std::map<std::string, std::string> details = DRing::getAccountTemplate("RING"); + details[ConfProperties::TYPE] = "RING"; + details[ConfProperties::DISPLAYNAME] = "BOB2"; + details[ConfProperties::ALIAS] = "BOB2"; + details[ConfProperties::UPNP_ENABLED] = "true"; + details[ConfProperties::ARCHIVE_PASSWORD] = ""; + details[ConfProperties::ARCHIVE_PIN] = ""; + details[ConfProperties::ARCHIVE_PATH] = bobArchive; + bob2Id = Manager::instance().addAccount(details); + + CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return bob2Started; })); + + // Alice adds bob + requestReceived = false; + aliceAccount->addContact(bobUri); + aliceAccount->sendTrustRequest(bobUri, {}); + CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived && requestReceivedBob2; })); + CPPUNIT_ASSERT(DRing::getConversationRequests(bob2Id).size() == 1); + + // Accepts requests + DRing::acceptConversationRequest(bobId, convId); + CPPUNIT_ASSERT( + cv.wait_for(lk, 30s, [&]() { return conversationReadyBob && conversationReadyBob2; })); + + // Bob bans alice, should update bob2 + bobAccount->removeContact(aliceUri, true); + CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return bob2ContactRemoved; })); + + // Alice sends messages, bob & bob2 should not get it! + bobMsgReceived = false, bob2MsgReceived = false; + DRing::sendMessage(aliceId, convId, "hi"s, ""); + CPPUNIT_ASSERT(!cv.wait_for(lk, 30s, [&]() { return bobMsgReceived && bob2MsgReceived; })); + + // Bobs re-add Alice + contactAddedBob = false, contactAddedBob2 = false; + bobAccount->addContact(aliceUri); + CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return contactAddedBob && contactAddedBob2; })); + std::this_thread::sleep_for(10s); + + // Alice can sends some messages now + bobMsgReceived = false, bob2MsgReceived = false; + DRing::sendMessage(aliceId, convId, "hi"s, ""); + CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return bobMsgReceived && bob2MsgReceived; })); +} + } // namespace test } // namespace jami diff --git a/test/unitTest/conversation/conversationRequest.cpp b/test/unitTest/conversation/conversationRequest.cpp index 4187cc2d91be28fa23f6727e652704b11cf7cae7..c7cf8b5744508e31b485e096e9614f1ab72d1b01 100644 --- a/test/unitTest/conversation/conversationRequest.cpp +++ b/test/unitTest/conversation/conversationRequest.cpp @@ -774,7 +774,7 @@ ConversationRequestTest::testBanContact() !cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; })); auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID() + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId; - CPPUNIT_ASSERT(!fileutils::isDirectory(repoPath)); + CPPUNIT_ASSERT(fileutils::isDirectory(repoPath)); } void