-
Nicolas Werner authoredNicolas Werner authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
login.cpp 6.68 KiB
#include "login.h"
#include <QtDebug>
#include <mtx/identifiers.hpp>
#include "client.h"
#include "debug_out.h"
#include "settings.h"
Login::Login(QObject *parent) : QObject(parent) {}
void Login::tryReconnect() {
Settings s;
try {
http::client().set_user(s.user().value());
http::client().set_server(s.server().value());
http::client().set_port(s.server_port().value());
http::client().set_device_id(s.device_id().value());
http::client().set_access_token(s.access_token().value());
emit loginSuccess();
} catch (std::exception &e) {
qWarning() << "Relogin failed: " << QString::fromStdString(e.what());
}
}
void Login::mxidEntered(QString mxid) {
using namespace mtx::identifiers;
std::cout << mxid.toStdString() << "\n";
User user;
try {
user = parse<User>(mxid.toStdString());
} catch (const std::exception &) {
qDebug() << "Can't parse user!"
<< "\n";
emit userParseError("Can't parse User");
return;
}
QString server = QString::fromStdString(user.hostname());
http::client().well_known([this, server](const mtx::responses::WellKnown &well_known, mtx::http::RequestErr err) {
if (err) {
using namespace boost::beast::http;
if (err->status_code == status::not_found) {
qDebug() << "Autodiscovery: No .well-known.";
this->validateServer(server);
return;
}
if (!err->parse_error.empty()) {
emit homeserverInvalid(server, tr("Autodiscovery failed. Received malformed response."));
qDebug() << "Autodiscovery failed. Received malformed response." << *err;
return;
}
emit homeserverInvalid(server, tr("Autodiscovery failed. Unknown error when requesting .well-known."));
qDebug() << "Autodiscovery failed. Unknown error when requesting .weel-known.";
return;
}
qDebug() << "Autodiscovery: Discovered '" << QString::fromStdString(well_known.homeserver.base_url) << "'";
this->validateServer(QString::fromStdString(well_known.homeserver.base_url));
});
}
void Login::homeserverEntered(QString server) { this->validateServer(server); }
void Login::validateServer(QString server) {
http::client().set_server(server.toStdString());
http::client().versions([this, server](const mtx::responses::Versions &, mtx::http::RequestErr err) {
if (err) {
using namespace boost::beast::http;
if (err->status_code == status::not_found) {
emit homeserverInvalid(server, tr("The required endpoints were not found. "
"Possibly not a Matrix server."));
return;
}
if (!err->parse_error.empty()) {
emit homeserverInvalid(server, tr("Received malformed response. Make sure "
"the homeserver domain is valid."));
return;
}
emit homeserverInvalid(server, tr("An unknown error occured. Make sure "
"the homeserver domain is valid."));
return;
}
});
}
void Login::login(QString mxid, QString password, QString server) {
qInfo() << "Logging in\n";
using namespace mtx::identifiers;
std::cout << mxid.toStdString() << "\n";
User user;
try {
user = parse<User>(mxid.toStdString());
} catch (const std::exception &) {
qDebug() << "Can't parse user!"
<< "\n";
emit loginError("Can't parse User");
return;
}
if (password.isEmpty()) {
emit loginError(tr("Empty password"));
return;
}
auto homeserver = user.hostname();
if (server.size() > 0)
homeserver = server.toStdString();
http::client().login(user.localpart(), password.toStdString(), "Spoon",
[this, homeserver](const mtx::responses::Login &response, mtx::http::RequestErr error) {
if (error) {
qDebug() << "Failed login!\n";
if (!error->matrix_error.error.empty()) {
emit loginError(QString::fromStdString(error->matrix_error.error));
return;
} else if (!error->parse_error.empty()) {
emit loginError(QString::fromStdString(error->parse_error));
return;
} else if (error->error_code) {
emit loginError(QString::fromStdString(error->error_code.message()));
return;
} else if (error->status_code != boost::beast::http::status::ok) {
emit loginError(QString::fromStdString(
"http status" + std::to_string((unsigned)error->status_code)));
return;
} else {
emit loginError(tr("Failed to login"));
return;
}
}
qDebug() << "Access token:" << QString::fromStdString(response.access_token)
<< " , device: " << QString::fromStdString(response.device_id);
if (response.well_known) {
qDebug() << "Login response requested to migrate to: "
<< QString::fromStdString(response.well_known->homeserver.base_url);
http::client().set_server(response.well_known->homeserver.base_url);
}
Settings s;
s.access_token(response.access_token);
s.device_id(response.device_id);
s.user(response.user_id);
s.server(http::client().server());
s.server_port(http::client().port());
emit loginSuccess();
});
}
void Login::logout() {
http::client().logout([this](const mtx::responses::Logout &response, mtx::http::RequestErr error) {
if (error) {
qWarning() << "Error logging out";
}
http::client().clear();
Settings s;
s.delete_access_token();
});
}