Page MenuHomePhorge

No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None
diff --git a/src/client/actions/auth.cpp b/src/client/actions/auth.cpp
index 7755612..b24ce84 100644
--- a/src/client/actions/auth.cpp
+++ b/src/client/actions/auth.cpp
@@ -1,191 +1,193 @@
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2020-2022 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <libkazv-config.hpp>
#include <debug.hpp>
#include <jobinterface.hpp>
#include <eventinterface.hpp>
#include "auth.hpp"
#include "status-utils.hpp"
namespace Kazv
{
ClientResult updateClient(ClientModel m, LoginAction a)
{
m.addJob(LoginJob{a.serverUrl,
"m.login.password"s, // type
UserIdentifier{ "m.id.user"s, json{{"user", a.username}} }, // identifier
a.password,
{}, // token, not used
{}, // device id, not used
a.deviceName.value_or("libkazv")}
.withData(json{
{"serverUrl", a.serverUrl},
}));
return { m, lager::noop };
}
ClientResult updateClient(ClientModel m, MLoginTokenLoginAction a)
{
m.addJob(LoginJob{a.serverUrl,
"m.login.token"s, // type
std::nullopt, // identifier
std::nullopt, // password
a.loginToken, // token, not used
{}, // device id, not used
a.deviceName.value_or("libkazv")}
.withData(json{
{"serverUrl", a.serverUrl},
}));
return { m, lager::noop };
}
ClientResult processResponse(ClientModel m, LoginResponse r)
{
if (! r.success()) {
m.addTrigger(LoginFailed{r.errorCode(), r.errorMessage()});
return { std::move(m), failWithResponse(r) };
}
kzo.client.dbg() << "Job success" << std::endl;
auto jw = r.jsonBody();
auto const &j = jw.get();
// TODO: replace this with r.wellKnown()
std::string serverUrl = j.contains("well_known")
? j.at("well_known").at("m.homeserver").at("base_url").get<std::string>()
: r.dataStr("serverUrl");
// Synapse will return the server url with trailing slash
// and not recognize double slashes in the middle
while (serverUrl.back() == '/') {
serverUrl.pop_back();
}
m.serverUrl = serverUrl;
m.userId = r.userId().value_or(DEFVAL);
m.token = r.accessToken().value_or(DEFVAL);
m.deviceId = r.deviceId().value_or(DEFVAL);
m.loggedIn = true;
m.addTrigger(LoginSuccessful{});
return { std::move(m), lager::noop };
}
ClientResult updateClient(ClientModel m, TokenLoginAction a)
{
m.serverUrl = a.serverUrl;
m.userId = a.username;
m.token = a.token;
m.deviceId = a.deviceId;
m.loggedIn = true;
m.addTrigger(LoginSuccessful{});
return { std::move(m), lager::noop };
}
ClientResult updateClient(ClientModel m, LogoutAction)
{
// Note: this only performs a soft-logout.
m.serverUrl = "";
m.userId = "";
m.token = "";
m.deviceId = "";
m.loggedIn = false;
return { std::move(m), lager::noop };
}
ClientResult updateClient(ClientModel m, HardLogoutAction)
{
m.addJob(LogoutJob{m.serverUrl, m.token});
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, LogoutResponse r)
{
if (r.success()) {
m.token = "";
m.loggedIn = false;
return { std::move(m), lager::noop };
} else {
return { std::move(m), failWithResponse(std::move(r)) };
}
}
ClientResult updateClient(ClientModel m, GetWellknownAction a)
{
auto pos = a.userId.find(':');
if (pos == std::string::npos || pos == a.userId.size() - 1) {
return { std::move(m), simpleFail };
}
auto serverUrl = "https://" + a.userId.substr(pos + 1);
m.addJob(GetWellknownJob{serverUrl}
.withData(json{{"serverUrl", serverUrl}}));
return { m, lager::noop };
}
ClientResult processResponse(ClientModel m, GetWellknownResponse r)
{
auto success = r.success() || r.statusCode == 404;
auto error = std::string();
std::string serverUrl = r.dataStr("serverUrl");
if (r.success()) {
auto data = r.data();
if (data.homeserver.baseUrl.empty()) {
success = false;
error = "FAIL_PROMPT";
} else {
serverUrl = data.homeserver.baseUrl;
}
} else {
error = "FAIL_PROMPT";
}
return {
std::move(m),
[success, serverUrl, error, r](auto &&) {
auto data = json{
{"homeserverUrl", serverUrl},
{"error", error},
{"errorCode", r.errorCode()},
};
return EffectStatus(success, data);
}
};
}
ClientResult updateClient(ClientModel m, GetVersionsAction a)
{
m.addJob(GetVersionsJob{a.serverUrl});
return { std::move(m), lager::noop };
}
ClientResult processResponse(ClientModel m, GetVersionsResponse r)
{
+ if (!r.success()) {
+ return {
+ std::move(m),
+ failWithResponse(r)
+ };
+ }
m.versions = r.versions();
return {
std::move(m),
[r](auto &&ctx) {
- if (r.success()) {
- return EffectStatus(r.success(), json{
- {"versions", r.versions()},
- });
- } else {
- return failWithResponse(r)(std::forward<decltype(ctx)>(ctx));
- }
+ return EffectStatus(r.success(), json{
+ {"versions", r.versions()},
+ });
}
};
}
}
diff --git a/src/tests/client/get-versions-test.cpp b/src/tests/client/get-versions-test.cpp
index 61e8f55..4a6b3e9 100644
--- a/src/tests/client/get-versions-test.cpp
+++ b/src/tests/client/get-versions-test.cpp
@@ -1,62 +1,72 @@
/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2025 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <libkazv-config.hpp>
#include <catch2/catch_all.hpp>
#include <boost/asio.hpp>
#include <asio-promise-handler.hpp>
#include "client-test-util.hpp"
#include "factory.hpp"
using namespace Kazv::Factory;
TEST_CASE("Send get versions job", "[client][get-versions]")
{
ClientModel model = makeClient({});
auto [next, _] = ClientModel::update(
model, GetVersionsAction{"https://example.com"});
assert1Job(next);
for1stJob(next, [] (const auto &job) {
REQUIRE(job.jobId() == "GetVersions");
REQUIRE(job.url().find("/versions") != std::string::npos);
});
}
TEST_CASE("Process get versions response", "[client][get-versions]")
{
boost::asio::io_context io;
AsioPromiseHandler ph{io.get_executor()};
auto initialModel = makeClient();
auto store = createTestClientStoreFrom(initialModel, ph);
auto client = Client(store.reader().map([] (auto c) { return SdkModel{c}; }), store, std::nullopt);
WHEN("Success response")
{
auto succResponse = makeResponse("GetVersions", withResponseJsonBody(R"({
"versions": ["r0.0.1", "v1.1"]
})"_json));
store.dispatch(ProcessResponseAction{succResponse})
.then([client] (auto stat) {
REQUIRE(stat.success());
REQUIRE(client.supportVersions().make().get() == immer::array{"r0.0.1"s, "v1.1"s});
});
}
WHEN("Failed response")
{
auto failResponse = makeResponse("GetVersions", withResponseStatusCode(403));
store.dispatch(ProcessResponseAction{failResponse})
.then([client] (auto stat) {
REQUIRE(!stat.success());
});
}
+ WHEN("Failed response without json body")
+ {
+ auto fileResponse = makeResponse("GetVersions",
+ withResponseStatusCode(403) | withResponseBytesBody(""));
+ store.dispatch(ProcessResponseAction{fileResponse})
+ .then([client](auto stat) {
+ REQUIRE(!stat.success());
+ });
+ }
+
io.run();
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Oct 11, 5:39 AM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1785622
Default Alt Text
(8 KB)

Event Timeline