Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85805276
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Oct 11, 5:39 AM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1785622
Default Alt Text
(8 KB)
Attached To
Mode
rL libkazv
Attached
Detach File
Event Timeline
Log In to Comment