Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/desktop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Schuster <michael@schuster.ms>2019-08-24 17:21:44 +0300
committerRoeland Jago Douma <roeland@famdouma.nl>2019-08-26 21:03:15 +0300
commitfd8345ccbe623ebee624477d2abe002bad181298 (patch)
tree11bf5047899a43c7efe8669dc3ef253101c0122a /src/gui/creds
parent7add98e9a316e42a28e55a5296fef30f557d2461 (diff)
Login Flow V2: adds re-auth upon logout, improvements
- Implements re-auth upon logout -> login - Improves UI and security TODO: - SSL: Client certificate login is possible at the first time only but missing after relaunch Signed-off-by: Michael Schuster <michael@schuster.ms>
Diffstat (limited to 'src/gui/creds')
-rw-r--r--src/gui/creds/flow2auth.cpp38
-rw-r--r--src/gui/creds/flow2auth.h5
-rw-r--r--src/gui/creds/webflowcredentials.cpp25
-rw-r--r--src/gui/creds/webflowcredentialsdialog.cpp49
-rw-r--r--src/gui/creds/webflowcredentialsdialog.h13
5 files changed, 94 insertions, 36 deletions
diff --git a/src/gui/creds/flow2auth.cpp b/src/gui/creds/flow2auth.cpp
index 76ff7c4ac..e570e01d4 100644
--- a/src/gui/creds/flow2auth.cpp
+++ b/src/gui/creds/flow2auth.cpp
@@ -34,9 +34,9 @@ Flow2Auth::~Flow2Auth()
void Flow2Auth::start()
{
- // Note: All startup code is in openBrowser() to allow reinitiate a new request with
- // fresh tokens. Opening the same pollEndpoint link twice triggers an expiration
- // message by the server (security, intended design).
+ // Note: All startup code is in openBrowser() to allow reinitiate a new request with
+ // fresh tokens. Opening the same pollEndpoint link twice triggers an expiration
+ // message by the server (security, intended design).
openBrowser();
}
@@ -91,6 +91,7 @@ void Flow2Auth::openBrowser()
_pollEndpoint = pollEndpoint;
+ // Start polling
ConfigFile cfg;
std::chrono::milliseconds polltime = cfg.remotePollInterval();
qCInfo(lcFlow2auth) << "setting remote poll timer interval to" << polltime.count() << "msec";
@@ -99,10 +100,10 @@ void Flow2Auth::openBrowser()
_pollTimer.start();
- if (!QDesktopServices::openUrl(authorisationLink())) {
- // TODO: Ask the user to copy and open the link instead of failing here!
-
- // We cannot open the browser, then we claim we don't support OAuth.
+ // Try to open Browser
+ if (!QDesktopServices::openUrl(authorisationLink())) {
+ // We cannot open the browser, then we claim we don't support Flow2Auth.
+ // Our UI callee should ask the user to copy and open the link.
emit result(NotSupported, QString());
}
});
@@ -110,7 +111,7 @@ void Flow2Auth::openBrowser()
void Flow2Auth::slotPollTimerTimeout()
{
- _pollTimer.stop();
+ _pollTimer.stop();
// Step 2: Poll
QNetworkRequest req;
@@ -122,6 +123,7 @@ void Flow2Auth::slotPollTimerTimeout()
auto job = _account->sendRequest("POST", _pollEndpoint, req, requestBody);
job->setTimeout(qMin(30 * 1000ll, job->timeoutMsec()));
+
QObject::connect(job, &SimpleNetworkJob::finishedSignal, this, [this](QNetworkReply *reply) {
auto jsonData = reply->readAll();
QJsonParseError jsonParseError;
@@ -149,15 +151,25 @@ void Flow2Auth::slotPollTimerTimeout()
}
qCDebug(lcFlow2auth) << "Error when polling for the appPassword" << json << errorReason;
- _pollTimer.start();
+ // Forget sensitive data
+ appPassword.clear();
+ loginName.clear();
+
+ // Failed: poll again
+ _pollTimer.start();
return;
}
- qCInfo(lcFlow2auth) << "Success getting the appPassword for user: " << loginName << " on server: " << serverUrl;
-
- _account->setUrl(serverUrl);
+ // Success
+ qCInfo(lcFlow2auth) << "Success getting the appPassword for user: " << loginName << ", server: " << serverUrl.toString();
+
+ _account->setUrl(serverUrl);
+
+ emit result(LoggedIn, loginName, appPassword);
- emit result(LoggedIn, loginName, appPassword);
+ // Forget sensitive data
+ appPassword.clear();
+ loginName.clear();
});
}
diff --git a/src/gui/creds/flow2auth.h b/src/gui/creds/flow2auth.h
index 188865a0d..b53834a11 100644
--- a/src/gui/creds/flow2auth.h
+++ b/src/gui/creds/flow2auth.h
@@ -49,10 +49,9 @@ public:
signals:
/**
* The state has changed.
- * when logged in, token has the value of the token.
+ * when logged in, appPassword has the value of the app password.
*/
- // TODO: Remove refreshToken
- void result(Flow2Auth::Result result, const QString &user = QString(), const QString &token = QString(), const QString &refreshToken = QString());
+ void result(Flow2Auth::Result result, const QString &user = QString(), const QString &appPassword = QString());
private slots:
void slotPollTimerTimeout();
diff --git a/src/gui/creds/webflowcredentials.cpp b/src/gui/creds/webflowcredentials.cpp
index 70a709470..ecc0e61d9 100644
--- a/src/gui/creds/webflowcredentials.cpp
+++ b/src/gui/creds/webflowcredentials.cpp
@@ -114,12 +114,17 @@ void WebFlowCredentials::fetchFromKeychain() {
}
void WebFlowCredentials::askFromUser() {
- _askDialog = new WebFlowCredentialsDialog();
+ // LoginFlowV2 > WebViewFlow > OAuth > Shib > Basic
+ bool useFlow2 = (_account->serverVersionInt() >= Account::makeServerVersion(16, 0, 0));
- QUrl url = _account->url();
- QString path = url.path() + "/index.php/login/flow";
- url.setPath(path);
- _askDialog->setUrl(url);
+ _askDialog = new WebFlowCredentialsDialog(_account, useFlow2);
+
+ if (!useFlow2) {
+ QUrl url = _account->url();
+ QString path = url.path() + "/index.php/login/flow";
+ url.setPath(path);
+ _askDialog->setUrl(url);
+ }
QString msg = tr("You have been logged out of %1 as user %2. Please login again")
.arg(_account->displayName(), _user);
@@ -142,10 +147,12 @@ void WebFlowCredentials::slotAskFromUserCredentialsProvided(const QString &user,
.arg(_user);
_askDialog->setError(msg);
- QUrl url = _account->url();
- QString path = url.path() + "/index.php/login/flow";
- url.setPath(path);
- _askDialog->setUrl(url);
+ if (!_askDialog->isUsingFlow2()) {
+ QUrl url = _account->url();
+ QString path = url.path() + "/index.php/login/flow";
+ url.setPath(path);
+ _askDialog->setUrl(url);
+ }
return;
}
diff --git a/src/gui/creds/webflowcredentialsdialog.cpp b/src/gui/creds/webflowcredentialsdialog.cpp
index 2d22ba06e..30a327afa 100644
--- a/src/gui/creds/webflowcredentialsdialog.cpp
+++ b/src/gui/creds/webflowcredentialsdialog.cpp
@@ -3,13 +3,21 @@
#include <QVBoxLayout>
#include <QLabel>
+#include "theme.h"
+#include "wizard/owncloudwizardcommon.h"
#include "wizard/webview.h"
+#include "wizard/flow2authwidget.h"
namespace OCC {
-WebFlowCredentialsDialog::WebFlowCredentialsDialog(QWidget *parent)
- : QDialog(parent)
+WebFlowCredentialsDialog::WebFlowCredentialsDialog(Account *account, bool useFlow2, QWidget *parent)
+ : QDialog(parent),
+ _useFlow2(useFlow2),
+ _flow2AuthWidget(nullptr),
+ _webView(nullptr)
{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
_layout = new QVBoxLayout(this);
//QString msg = tr("You have been logged out of %1 as user %2, please login again")
@@ -17,28 +25,44 @@ WebFlowCredentialsDialog::WebFlowCredentialsDialog(QWidget *parent)
_infoLabel = new QLabel();
_layout->addWidget(_infoLabel);
- _webView = new WebView();
- _layout->addWidget(_webView);
+ if (_useFlow2) {
+ _flow2AuthWidget = new Flow2AuthWidget(account);
+ _layout->addWidget(_flow2AuthWidget);
+
+ connect(_flow2AuthWidget, &Flow2AuthWidget::urlCatched, this, &WebFlowCredentialsDialog::urlCatched);
+ } else {
+ _webView = new WebView();
+ _layout->addWidget(_webView);
+
+ connect(_webView, &WebView::urlCatched, this, &WebFlowCredentialsDialog::urlCatched);
+ }
_errorLabel = new QLabel();
_errorLabel->hide();
_layout->addWidget(_errorLabel);
- setLayout(_layout);
+ Theme *theme = Theme::instance();
+ WizardCommon::initErrorLabel(_errorLabel);
- connect(_webView, &WebView::urlCatched, this, &WebFlowCredentialsDialog::urlCatched);
+ setLayout(_layout);
}
void WebFlowCredentialsDialog::closeEvent(QCloseEvent* e) {
Q_UNUSED(e);
- // Force calling WebView::~WebView() earlier so that _profile and _page are
- // deleted in the correct order.
- delete _webView;
+ if (_webView) {
+ // Force calling WebView::~WebView() earlier so that _profile and _page are
+ // deleted in the correct order.
+ delete _webView;
+ }
+
+ if (_flow2AuthWidget)
+ delete _flow2AuthWidget;
}
void WebFlowCredentialsDialog::setUrl(const QUrl &url) {
- _webView->setUrl(url);
+ if (_webView)
+ _webView->setUrl(url);
}
void WebFlowCredentialsDialog::setInfo(const QString &msg) {
@@ -46,6 +70,11 @@ void WebFlowCredentialsDialog::setInfo(const QString &msg) {
}
void WebFlowCredentialsDialog::setError(const QString &error) {
+ if (_useFlow2 && _flow2AuthWidget) {
+ _flow2AuthWidget->setError(error);
+ return;
+ }
+
if (error.isEmpty()) {
_errorLabel->hide();
} else {
diff --git a/src/gui/creds/webflowcredentialsdialog.h b/src/gui/creds/webflowcredentialsdialog.h
index 9849ee3a4..4e1f21c0d 100644
--- a/src/gui/creds/webflowcredentialsdialog.h
+++ b/src/gui/creds/webflowcredentialsdialog.h
@@ -4,23 +4,30 @@
#include <QDialog>
#include <QUrl>
+#include "accountfwd.h"
+
class QLabel;
class QVBoxLayout;
namespace OCC {
class WebView;
+class Flow2AuthWidget;
class WebFlowCredentialsDialog : public QDialog
{
Q_OBJECT
public:
- WebFlowCredentialsDialog(QWidget *parent = nullptr);
+ WebFlowCredentialsDialog(Account *account, bool useFlow2, QWidget *parent = nullptr);
void setUrl(const QUrl &url);
void setInfo(const QString &msg);
void setError(const QString &error);
+ const bool isUsingFlow2() const {
+ return _useFlow2;
+ }
+
protected:
void closeEvent(QCloseEvent * e) override;
@@ -28,7 +35,11 @@ signals:
void urlCatched(const QString user, const QString pass, const QString host);
private:
+ bool _useFlow2;
+
+ Flow2AuthWidget *_flow2AuthWidget;
WebView *_webView;
+
QLabel *_errorLabel;
QLabel *_infoLabel;
QVBoxLayout *_layout;