summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeepBlueV7.X <nicolas.werner@hotmail.de>2021-06-03 18:12:33 +0000
committerGitHub <noreply@github.com>2021-06-03 18:12:33 +0000
commitf08fb0264d2c6c19d0399f14c02a1317779a2d61 (patch)
tree71f44ce383e6f47693d1313bf99e9ba862677b92
parentMerge pull request #594 from pcworld/narrow-view-notification (diff)
parentDo a .well-known lookup during registration (diff)
downloadnheko-f08fb0264d2c6c19d0399f14c02a1317779a2d61.tar.xz
Merge pull request #600 from govynnus/registration-well-known
Registration well known
-rw-r--r--src/RegisterPage.cpp144
-rw-r--r--src/RegisterPage.h6
2 files changed, 119 insertions, 31 deletions
diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp
index 5c5545ec..36fd71a8 100644
--- a/src/RegisterPage.cpp
+++ b/src/RegisterPage.cpp
@@ -11,6 +11,7 @@
 #include <QtMath>
 
 #include <mtx/responses/register.hpp>
+#include <mtx/responses/well-known.hpp>
 
 #include "Config.h"
 #include "Logging.h"
@@ -108,6 +109,10 @@ RegisterPage::RegisterPage(QWidget *parent)
         error_password_confirmation_label_->setWordWrap(true);
         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(error_username_label_, 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(error_password_confirmation_label_, Qt::AlignHCenter);
         form_layout_->addWidget(server_input_, Qt::AlignHCenter);
+        form_layout_->addWidget(error_server_label_, Qt::AlignHCenter);
 
         button_layout_ = new QHBoxLayout();
         button_layout_->setSpacing(0);
@@ -140,6 +146,17 @@ RegisterPage::RegisterPage(QWidget *parent)
         top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter);
         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(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked()));
 
@@ -351,10 +368,12 @@ RegisterPage::checkFields()
         error_username_label_->setText("");
         error_password_label_->setText("");
         error_password_confirmation_label_->setText("");
+        error_server_label_->setText("");
 
         error_username_label_->hide();
         error_password_label_->hide();
         error_password_confirmation_label_->hide();
+        error_server_label_->hide();
 
         password_confirmation_->setValid(true);
         server_input_->setValid(true);
@@ -379,7 +398,8 @@ RegisterPage::checkFields()
                 all_fields_good = false;
         } else if (server_input_->isModified() &&
                    (!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);
                 all_fields_good = false;
         }
@@ -406,45 +426,39 @@ RegisterPage::onRegisterButtonClicked()
                 http::client()->set_server(server);
                 http::client()->verify_certificates(
                   !UserSettings::instance()->disableCertificateValidation());
-                http::client()->registration(
-                  username,
-                  password,
-                  [this, username, password](const mtx::responses::Register &res,
+
+                http::client()->well_known(
+                  [this, username, password](const mtx::responses::WellKnown &res,
                                              mtx::http::RequestErr err) {
-                          if (!err) {
-                                  http::client()->set_user(res.user_id);
-                                  http::client()->set_access_token(res.access_token);
+                          if (err) {
+                                  using namespace boost::beast::http;
 
-                                  emit registerOk();
-                                  return;
-                          }
+                                  if (err->status_code == status::not_found) {
+                                          nhlog::net()->info("Autodiscovery: No .well-known.");
+                                          checkVersionAndRegister(username, password);
+                                          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));
+                                  if (!err->parse_error.empty()) {
+                                          emit versionErrorCb(tr(
+                                            "Autodiscovery failed. Received malformed response."));
+                                          nhlog::net()->error(
+                                            "Autodiscovery failed. Received malformed response.");
                                           return;
                                   }
 
-                                  emit registrationFlow(
-                                    username, password, err->matrix_error.unauthorized);
+                                  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;
                           }
 
-                          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();
+                          nhlog::net()->info("Autodiscovery: Discovered '" +
+                                             res.homeserver.base_url + "'");
+                          http::client()->set_server(res.homeserver.base_url);
+                          checkVersionAndRegister(username, password);
                   });
 
                 emit registering();
@@ -452,6 +466,74 @@ RegisterPage::onRegisterButtonClicked()
 }
 
 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
 RegisterPage::paintEvent(QPaintEvent *)
 {
         QStyleOption opt;
diff --git a/src/RegisterPage.h b/src/RegisterPage.h
index 2f05d04c..0e4a45d0 100644
--- a/src/RegisterPage.h
+++ b/src/RegisterPage.h
@@ -31,6 +31,10 @@ protected:
 signals:
         void backButtonClicked();
         void errorOccurred();
+
+        //! Used to trigger the corresponding slot outside of the main thread.
+        void versionErrorCb(const QString &err);
+
         void registering();
         void registerOk();
         void registerErrorCb(const QString &msg);
@@ -52,6 +56,7 @@ private:
         bool checkOneField(QLabel *label, const TextField *t_field, const QString &msg);
         bool checkFields();
         void showError(QLabel *label, const QString &msg);
+        void checkVersionAndRegister(const std::string &username, const std::string &password);
         QVBoxLayout *top_layout_;
 
         QHBoxLayout *back_layout_;
@@ -63,6 +68,7 @@ private:
         QLabel *error_username_label_;
         QLabel *error_password_label_;
         QLabel *error_password_confirmation_label_;
+        QLabel *error_server_label_;
 
         FlatButton *back_button_;
         RaisedButton *register_button_;