1 #include <atomic>
2
3 #include <gtest/gtest.h>
4
5 #include <nlohmann/json.hpp>
6
7 #include "mtxclient/crypto/client.hpp"
8 #include "mtxclient/crypto/types.hpp"
9 #include "mtxclient/http/client.hpp"
10
11 #include "mtx/requests.hpp"
12 #include "mtx/responses.hpp"
13
14 #include "test_helpers.hpp"
15
16 using namespace mtx::client;
17 using namespace mtx::http;
18 using namespace mtx::crypto;
19
20 using namespace mtx::identifiers;
21 using namespace mtx::events;
22 using namespace mtx::events::msg;
23 using namespace mtx::events::collections;
24 using namespace mtx::responses;
25
26 using namespace std;
27
28 using namespace nlohmann;
29
TEST(Devices,DeleteDevices)30 TEST(Devices, DeleteDevices)
31 {
32 auto alice = make_test_client();
33
34 alice->login(
35 "alice", "secret", [](const mtx::responses::Login &, RequestErr err) { check_error(err); });
36
37 auto alice_dummy = make_test_client();
38 alice_dummy->login(
39 "alice", "secret", [](const mtx::responses::Login &, RequestErr err) { check_error(err); });
40
41 while (alice->access_token().empty() || alice_dummy->access_token().empty())
42 sleep();
43
44 std::string myDevice = alice->device_id();
45
46 atomic_int responses(0);
47 std::vector<std::string> device_ids;
48
49 // Get list of devices, fill device_ids with all devices except current
50 alice->query_devices(
51 [&responses, &device_ids, myDevice](const mtx::responses::QueryDevices &res, RequestErr err) {
52 check_error(err);
53 for (auto it = res.devices.begin(); it != res.devices.end(); ++it)
54 if (it->device_id != myDevice)
55 device_ids.push_back(it->device_id);
56 responses += 1;
57 });
58
59 while (responses != 1)
60 sleep();
61
62 // Delete all devices except current
63 alice->delete_devices(
64 device_ids,
65 mtx::http::UIAHandler([](const mtx::http::UIAHandler &h,
66 const mtx::user_interactive::Unauthorized &unauthorized) {
67 ASSERT_EQ(unauthorized.flows.size(), 1);
68 ASSERT_EQ(unauthorized.flows[0].stages.size(), 1);
69 ASSERT_EQ(unauthorized.flows[0].stages[0], mtx::user_interactive::auth_types::password);
70
71 mtx::user_interactive::Auth auth;
72 auth.session = unauthorized.session;
73 mtx::user_interactive::auth::Password pass{};
74 pass.password = "secret";
75 pass.identifier_user = "alice";
76 pass.identifier_type = mtx::user_interactive::auth::Password::IdType::UserId;
77 auth.content = pass;
78 h.next(auth);
79 }),
80 [&responses](RequestErr e) {
81 check_error(e);
82 responses += 1;
83 });
84
85 while (responses != 2)
86 sleep();
87
88 // Check if the current device is the only device left
89 alice->query_devices(
90 [&responses, myDevice](const mtx::responses::QueryDevices &res, RequestErr err) {
91 check_error(err);
92 ASSERT_EQ(res.devices.size(), 1);
93 ASSERT_EQ(res.devices.begin()->device_id, myDevice);
94 responses += 1;
95 });
96
97 // Check if dummy can no longer retrieve list of devices because their token was removed
98 alice_dummy->query_devices(
99 [&responses](const mtx::responses::QueryDevices &res, RequestErr err) {
100 ASSERT_TRUE(err);
101 ASSERT_EQ(res.devices.size(), 0);
102 EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode), "M_UNKNOWN_TOKEN");
103 });
104
105 while (responses != 3)
106 sleep();
107
108 // Delete current device
109 alice->delete_device(
110 myDevice,
111 mtx::http::UIAHandler([](const mtx::http::UIAHandler &h,
112 const mtx::user_interactive::Unauthorized &unauthorized) {
113 ASSERT_EQ(unauthorized.flows.size(), 1);
114 ASSERT_EQ(unauthorized.flows[0].stages.size(), 1);
115 ASSERT_EQ(unauthorized.flows[0].stages[0], mtx::user_interactive::auth_types::password);
116
117 mtx::user_interactive::Auth auth;
118 auth.session = unauthorized.session;
119 mtx::user_interactive::auth::Password pass{};
120 pass.password = "secret";
121 pass.identifier_user = "alice";
122 pass.identifier_type = mtx::user_interactive::auth::Password::IdType::UserId;
123 auth.content = pass;
124 h.next(auth);
125 }),
126 [&responses](RequestErr e) {
127 check_error(e);
128 responses += 1;
129 });
130
131 alice->close();
132 }
133
TEST(Devices,RenameDevices)134 TEST(Devices, RenameDevices)
135 {
136 auto alice_one = make_test_client();
137 auto alice_two = make_test_client();
138
139 alice_one->login(
140 "alice", "secret", [](const mtx::responses::Login &, RequestErr err) { check_error(err); });
141 alice_two->login(
142 "alice", "secret", [](const mtx::responses::Login &, RequestErr err) { check_error(err); });
143
144 while (alice_one->access_token().empty() || alice_two->access_token().empty())
145 sleep();
146
147 atomic_int responses(0);
148
149 // Rename the two logged in devices to Alice One and Alice Two
150 alice_one->set_device_name(alice_one->device_id(), "Alice One", [&responses](RequestErr err) {
151 check_error(err);
152 responses += 1;
153 });
154 alice_two->set_device_name(alice_two->device_id(), "Alice Two", [&responses](RequestErr err) {
155 check_error(err);
156 responses += 1;
157 });
158
159 while (responses != 2)
160 sleep();
161
162 // Request info for current devices and confirm display name changed
163 alice_one->get_device(alice_one->device_id(),
164 [&responses](const mtx::responses::Device &res, RequestErr err) {
165 ASSERT_EQ(res.display_name, "Alice One");
166 check_error(err);
167 responses += 1;
168 });
169 alice_two->get_device(alice_two->device_id(),
170 [&responses](const mtx::responses::Device &res, RequestErr err) {
171 ASSERT_EQ(res.display_name, "Alice Two");
172 check_error(err);
173 responses += 1;
174 });
175
176 while (responses != 4)
177 sleep();
178
179 // Request device list and check both One and Two are in the list
180 alice_one->query_devices([&responses](const mtx::responses::QueryDevices &res, RequestErr err) {
181 check_error(err);
182 bool oneFound = false;
183 bool twoFound = false;
184 for (auto it = res.devices.begin(); it != res.devices.end(); ++it) {
185 if (it->display_name == "Alice One")
186 oneFound = true;
187 if (it->display_name == "Alice Two")
188 twoFound = true;
189 }
190 ASSERT_EQ(oneFound, true);
191 ASSERT_EQ(twoFound, true);
192 responses += 1;
193 });
194
195 while (responses != 5)
196 sleep();
197
198 alice_one->close();
199 alice_two->close();
200 }
201