Line data Source code
1 : /* 2 : * Copyright (C) 2021-2024 Savoir-faire Linux Inc. 3 : * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com> 4 : * 5 : * This program is free software; you can redistribute it and/or modify 6 : * it under the terms of the GNU General Public License as published by 7 : * the Free Software Foundation; either version 3 of the License, or 8 : * (at your option) any later version. 9 : * 10 : * This program is distributed in the hope that it will be useful, 11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 : * GNU General Public License for more details. 14 : * 15 : * You should have received a copy of the GNU General Public License 16 : * along with this program. If not, see <https://www.gnu.org/licenses/>. 17 : */ 18 : 19 : #include <cppunit/TestAssert.h> 20 : #include <cppunit/TestFixture.h> 21 : #include <cppunit/extensions/HelperMacros.h> 22 : 23 : #include <condition_variable> 24 : #include <string> 25 : #include <fstream> 26 : #include <streambuf> 27 : 28 : #include "manager.h" 29 : #include "jamidht/jamiaccount.h" 30 : #include "../../test_runner.h" 31 : #include "jami.h" 32 : #include "fileutils.h" 33 : #include "account_const.h" 34 : #include "common.h" 35 : 36 : using namespace std::string_literals; 37 : using namespace libjami::Account; 38 : 39 : namespace jami { 40 : namespace test { 41 : 42 : class RevokeTest : public CppUnit::TestFixture 43 : { 44 : public: 45 2 : RevokeTest() 46 2 : { 47 : // Init daemon 48 2 : libjami::init(libjami::InitFlag(libjami::LIBJAMI_FLAG_DEBUG | libjami::LIBJAMI_FLAG_CONSOLE_LOG)); 49 2 : if (not Manager::instance().initialized) 50 1 : CPPUNIT_ASSERT(libjami::start("dring-sample.yml")); 51 2 : } 52 4 : ~RevokeTest() { libjami::fini(); } 53 2 : static std::string name() { return "Revoke"; } 54 : void setUp(); 55 : void tearDown(); 56 : 57 : std::string aliceId; 58 : std::string bobId; 59 : 60 : private: 61 : void testRevokeDevice(); 62 : void testRevokeInvalidDevice(); 63 : 64 2 : CPPUNIT_TEST_SUITE(RevokeTest); 65 1 : CPPUNIT_TEST(testRevokeDevice); 66 1 : CPPUNIT_TEST(testRevokeInvalidDevice); 67 4 : CPPUNIT_TEST_SUITE_END(); 68 : }; 69 : 70 : CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(RevokeTest, RevokeTest::name()); 71 : 72 : void 73 2 : RevokeTest::setUp() 74 : { 75 4 : auto actors = load_actors_and_wait_for_announcement("actors/alice-bob-password.yml"); 76 2 : aliceId = actors["alice"]; 77 2 : bobId = actors["bob"]; 78 2 : } 79 : 80 : void 81 2 : RevokeTest::tearDown() 82 : { 83 6 : wait_for_removal_of({aliceId, bobId}); 84 2 : } 85 : 86 : void 87 1 : RevokeTest::testRevokeDevice() 88 : { 89 1 : auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId); 90 : 91 1 : CPPUNIT_ASSERT(aliceAccount->exportArchive("test.gz")); 92 : 93 2 : std::map<std::string, std::string> details = libjami::getAccountTemplate("RING"); 94 1 : details[ConfProperties::ARCHIVE_PATH] = "test.gz"; 95 : 96 1 : std::mutex mtx; 97 1 : std::unique_lock lk {mtx}; 98 1 : std::condition_variable cv; 99 1 : std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers; 100 1 : auto deviceRevoked = false; 101 1 : auto knownChanged = false; 102 1 : std::string alice2Device; 103 1 : confHandlers.insert( 104 2 : libjami::exportable_callback<libjami::ConfigurationSignal::DeviceRevocationEnded>( 105 1 : [&](const std::string& accountId, const std::string& deviceId, int status) { 106 1 : if (accountId == aliceId && deviceId == alice2Device && status == 0) 107 1 : deviceRevoked = true; 108 1 : cv.notify_one(); 109 1 : })); 110 1 : confHandlers.insert(libjami::exportable_callback<libjami::ConfigurationSignal::KnownDevicesChanged>( 111 2 : [&](const std::string& accountId, auto devices) { 112 2 : if (accountId == aliceId && devices.size() == 2) 113 1 : knownChanged = true; 114 2 : cv.notify_one(); 115 2 : })); 116 1 : libjami::registerSignalHandlers(confHandlers); 117 1 : auto alice2Id = jami::Manager::instance().addAccount(details); 118 1 : auto alice2Account = Manager::instance().getAccount<JamiAccount>(alice2Id); 119 4 : CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(60), [&] { return knownChanged; })); 120 1 : alice2Device = std::string(alice2Account->currentDeviceId()); 121 1 : aliceAccount->revokeDevice(alice2Device); 122 2 : CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&] { return deviceRevoked; })); 123 : 124 1 : std::remove("test.gz"); 125 1 : wait_for_removal_of(alice2Id); 126 1 : } 127 : 128 : void 129 1 : RevokeTest::testRevokeInvalidDevice() 130 : { 131 1 : auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId); 132 : 133 1 : std::mutex mtx; 134 1 : std::unique_lock lk {mtx}; 135 1 : std::condition_variable cv; 136 1 : std::map<std::string, std::shared_ptr<libjami::CallbackWrapperBase>> confHandlers; 137 1 : auto revokeFailed = false; 138 1 : confHandlers.insert( 139 2 : libjami::exportable_callback<libjami::ConfigurationSignal::DeviceRevocationEnded>( 140 1 : [&](const std::string& accountId, const std::string& deviceId, int status) { 141 1 : if (accountId == aliceId && deviceId == "foo" && status == 2) 142 1 : revokeFailed = true; 143 1 : cv.notify_one(); 144 1 : })); 145 1 : libjami::registerSignalHandlers(confHandlers); 146 1 : aliceAccount->revokeDevice("foo"); 147 2 : CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(10), [&] { return revokeFailed; })); 148 1 : } 149 : 150 : } // namespace test 151 : } // namespace jami 152 : 153 1 : RING_TEST_RUNNER(jami::test::RevokeTest::name())