Merge pull request #600 from govynnus/registration-well-known

Registration well known
This commit is contained in:
DeepBlueV7.X 2021-06-03 18:12:33 +00:00 committed by GitHub
commit f08fb0264d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 32 deletions

View file

@ -11,6 +11,7 @@
#include <QtMath> #include <QtMath>
#include <mtx/responses/register.hpp> #include <mtx/responses/register.hpp>
#include <mtx/responses/well-known.hpp>
#include "Config.h" #include "Config.h"
#include "Logging.h" #include "Logging.h"
@ -108,6 +109,10 @@ RegisterPage::RegisterPage(QWidget *parent)
error_password_confirmation_label_->setWordWrap(true); error_password_confirmation_label_->setWordWrap(true);
error_password_confirmation_label_->hide(); error_password_confirmation_label_->hide();
error_server_label_ = new QLabel(this);
error_server_label_->setWordWrap(true);
error_server_label_->hide();
form_layout_->addWidget(username_input_, Qt::AlignHCenter); form_layout_->addWidget(username_input_, Qt::AlignHCenter);
form_layout_->addWidget(error_username_label_, Qt::AlignHCenter); form_layout_->addWidget(error_username_label_, Qt::AlignHCenter);
form_layout_->addWidget(password_input_, Qt::AlignHCenter); form_layout_->addWidget(password_input_, Qt::AlignHCenter);
@ -115,6 +120,7 @@ RegisterPage::RegisterPage(QWidget *parent)
form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter); form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter);
form_layout_->addWidget(error_password_confirmation_label_, Qt::AlignHCenter); form_layout_->addWidget(error_password_confirmation_label_, Qt::AlignHCenter);
form_layout_->addWidget(server_input_, Qt::AlignHCenter); form_layout_->addWidget(server_input_, Qt::AlignHCenter);
form_layout_->addWidget(error_server_label_, Qt::AlignHCenter);
button_layout_ = new QHBoxLayout(); button_layout_ = new QHBoxLayout();
button_layout_->setSpacing(0); button_layout_->setSpacing(0);
@ -140,6 +146,17 @@ RegisterPage::RegisterPage(QWidget *parent)
top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter); top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter);
top_layout_->addStretch(1); top_layout_->addStretch(1);
connect(
this,
&RegisterPage::versionErrorCb,
this,
[this](const QString &msg) {
error_server_label_->show();
server_input_->setValid(false);
showError(error_server_label_, msg);
},
Qt::QueuedConnection);
connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked())); connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked()));
connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked())); connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked()));
@ -351,10 +368,12 @@ RegisterPage::checkFields()
error_username_label_->setText(""); error_username_label_->setText("");
error_password_label_->setText(""); error_password_label_->setText("");
error_password_confirmation_label_->setText(""); error_password_confirmation_label_->setText("");
error_server_label_->setText("");
error_username_label_->hide(); error_username_label_->hide();
error_password_label_->hide(); error_password_label_->hide();
error_password_confirmation_label_->hide(); error_password_confirmation_label_->hide();
error_server_label_->hide();
password_confirmation_->setValid(true); password_confirmation_->setValid(true);
server_input_->setValid(true); server_input_->setValid(true);
@ -379,7 +398,8 @@ RegisterPage::checkFields()
all_fields_good = false; all_fields_good = false;
} else if (server_input_->isModified() && } else if (server_input_->isModified() &&
(!server_input_->hasAcceptableInput() || server_input_->text().isEmpty())) { (!server_input_->hasAcceptableInput() || server_input_->text().isEmpty())) {
showError(tr("Invalid server name")); error_server_label_->show();
showError(error_server_label_, tr("Invalid server name"));
server_input_->setValid(false); server_input_->setValid(false);
all_fields_good = false; all_fields_good = false;
} }
@ -406,51 +426,113 @@ RegisterPage::onRegisterButtonClicked()
http::client()->set_server(server); http::client()->set_server(server);
http::client()->verify_certificates( http::client()->verify_certificates(
!UserSettings::instance()->disableCertificateValidation()); !UserSettings::instance()->disableCertificateValidation());
http::client()->registration(
username, http::client()->well_known(
password, [this, username, password](const mtx::responses::WellKnown &res,
[this, username, password](const mtx::responses::Register &res,
mtx::http::RequestErr err) { mtx::http::RequestErr err) {
if (!err) { if (err) {
http::client()->set_user(res.user_id); using namespace boost::beast::http;
http::client()->set_access_token(res.access_token);
emit registerOk(); if (err->status_code == status::not_found) {
return; nhlog::net()->info("Autodiscovery: No .well-known.");
} checkVersionAndRegister(username, password);
// The server requires registration flows.
if (err->status_code == boost::beast::http::status::unauthorized) {
if (err->matrix_error.unauthorized.flows.empty()) {
nhlog::net()->warn(
"failed to retrieve registration flows1: ({}) "
"{}",
static_cast<int>(err->status_code),
err->matrix_error.error);
emit errorOccurred();
emit registerErrorCb(
QString::fromStdString(err->matrix_error.error));
return; return;
} }
emit registrationFlow( if (!err->parse_error.empty()) {
username, password, err->matrix_error.unauthorized); emit versionErrorCb(tr(
"Autodiscovery failed. Received malformed response."));
nhlog::net()->error(
"Autodiscovery failed. Received malformed response.");
return;
}
emit versionErrorCb(tr("Autodiscovery failed. Unknown error when "
"requesting .well-known."));
nhlog::net()->error("Autodiscovery failed. Unknown error when "
"requesting .well-known. {}",
err->error_code.message());
return; return;
} }
nhlog::net()->error( nhlog::net()->info("Autodiscovery: Discovered '" +
"failed to register: status_code ({}), matrix_error({})", res.homeserver.base_url + "'");
static_cast<int>(err->status_code), http::client()->set_server(res.homeserver.base_url);
err->matrix_error.error); checkVersionAndRegister(username, password);
emit registerErrorCb(QString::fromStdString(err->matrix_error.error));
emit errorOccurred();
}); });
emit registering(); emit registering();
} }
} }
void
RegisterPage::checkVersionAndRegister(const std::string &username, const std::string &password)
{
http::client()->versions(
[this, username, password](const mtx::responses::Versions &, mtx::http::RequestErr err) {
if (err) {
using namespace boost::beast::http;
if (err->status_code == status::not_found) {
emit versionErrorCb(tr("The required endpoints were not found. "
"Possibly not a Matrix server."));
return;
}
if (!err->parse_error.empty()) {
emit versionErrorCb(tr("Received malformed response. Make sure "
"the homeserver domain is valid."));
return;
}
emit versionErrorCb(tr(
"An unknown error occured. Make sure the homeserver domain is valid."));
return;
}
http::client()->registration(
username,
password,
[this, username, password](const mtx::responses::Register &res,
mtx::http::RequestErr err) {
if (!err) {
http::client()->set_user(res.user_id);
http::client()->set_access_token(res.access_token);
emit registerOk();
return;
}
// The server requires registration flows.
if (err->status_code == boost::beast::http::status::unauthorized) {
if (err->matrix_error.unauthorized.flows.empty()) {
nhlog::net()->warn(
"failed to retrieve registration flows1: ({}) "
"{}",
static_cast<int>(err->status_code),
err->matrix_error.error);
emit errorOccurred();
emit registerErrorCb(
QString::fromStdString(err->matrix_error.error));
return;
}
emit registrationFlow(
username, password, err->matrix_error.unauthorized);
return;
}
nhlog::net()->error(
"failed to register: status_code ({}), matrix_error({})",
static_cast<int>(err->status_code),
err->matrix_error.error);
emit registerErrorCb(QString::fromStdString(err->matrix_error.error));
emit errorOccurred();
});
});
}
void void
RegisterPage::paintEvent(QPaintEvent *) RegisterPage::paintEvent(QPaintEvent *)
{ {

View file

@ -31,6 +31,10 @@ protected:
signals: signals:
void backButtonClicked(); void backButtonClicked();
void errorOccurred(); void errorOccurred();
//! Used to trigger the corresponding slot outside of the main thread.
void versionErrorCb(const QString &err);
void registering(); void registering();
void registerOk(); void registerOk();
void registerErrorCb(const QString &msg); void registerErrorCb(const QString &msg);
@ -52,6 +56,7 @@ private:
bool checkOneField(QLabel *label, const TextField *t_field, const QString &msg); bool checkOneField(QLabel *label, const TextField *t_field, const QString &msg);
bool checkFields(); bool checkFields();
void showError(QLabel *label, const QString &msg); void showError(QLabel *label, const QString &msg);
void checkVersionAndRegister(const std::string &username, const std::string &password);
QVBoxLayout *top_layout_; QVBoxLayout *top_layout_;
QHBoxLayout *back_layout_; QHBoxLayout *back_layout_;
@ -63,6 +68,7 @@ private:
QLabel *error_username_label_; QLabel *error_username_label_;
QLabel *error_password_label_; QLabel *error_password_label_;
QLabel *error_password_confirmation_label_; QLabel *error_password_confirmation_label_;
QLabel *error_server_label_;
FlatButton *back_button_; FlatButton *back_button_;
RaisedButton *register_button_; RaisedButton *register_button_;