/*
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QDebug>
#include <QFile>
#include <QImageReader>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QPixmap>
#include <QSettings>
#include <QUrlQuery>
#include "Login.h"
#include "MatrixClient.h"
#include "MessageEvent.h"
#include "Profile.h"
#include "Register.h"
#include "RoomMessages.h"
#include "Sync.h"
#include "Versions.h"
MatrixClient::MatrixClient(QString server, QObject *parent)
: QNetworkAccessManager(parent)
, clientApiUrl_{"/_matrix/client/r0"}
, mediaApiUrl_{"/_matrix/media/r0"}
, server_{"https://" + server}
{
QSettings settings;
txn_id_ = settings.value("client/transaction_id", 1).toInt();
connect(this,
&QNetworkAccessManager::networkAccessibleChanged,
this,
[=](NetworkAccessibility status) {
if (status != NetworkAccessibility::Accessible)
setNetworkAccessible(NetworkAccessibility::Accessible);
});
}
void
MatrixClient::reset() noexcept
{
next_batch_.clear();
server_.clear();
token_.clear();
txn_id_ = 0;
}
void
MatrixClient::login(const QString &username, const QString &password) noexcept
{
QUrl endpoint(server_);
endpoint.setPath(clientApiUrl_ + "/login");
QNetworkRequest request(endpoint);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
LoginRequest body(username, password);
auto reply = post(request, body.serialize());
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
reply->deleteLater();
int status_code =
reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (status_code == 403) {
emit loginError(tr("Wrong username or password"));
return;
}
if (status_code == 404) {
emit loginError(tr("Login endpoint was not found on the server"));
return;
}
if (status_code >= 400) {
qWarning() << "Login error: " << reply->errorString();
emit loginError(tr("An unknown error occured. Please try again."));
return;
}
auto data = reply->readAll();
auto json = QJsonDocument::fromJson(data);
LoginResponse response;
try {
response.deserialize(json);
auto hostname = server_.host();
if (server_.port() > 0)
hostname = QString("%1:%2").arg(server_.host()).arg(server_.port());
emit loginSuccess(
response.getUserId(), hostname, response.getAccessToken());
} catch (DeserializationException &e) {
qWarning() << "Malformed JSON response" << e.what();
emit loginError(tr("Malformed response. Possibly not a Matrix server"));
}
});
}
void
MatrixClient::logout() noexcept
{
QUrlQuery query;
query.addQueryItem("access_token", token_);
QUrl endpoint(server_);
endpoint.setPath(clientApiUrl_ + "/logout");
endpoint.setQuery(query);
QNetworkRequest request(endpoint);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QJsonObject body{};
auto reply = post(request, QJsonDocument(body).toJson(QJsonDocument::Compact));
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
reply->deleteLater();
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (status != 200) {
qWarning() << "Logout error: " << reply->errorString();
return;
}
emit loggedOut();
});
}
void
MatrixClient::regist