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

github.com/owncloud/client.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFabian Müller <fmueller@owncloud.com>2022-05-23 16:28:09 +0300
committerHannah von Reth <vonreth@kde.org>2022-07-06 14:36:05 +0300
commit20b0d2c7d22fbbf03bcbf787f2f4db0e91e9545f (patch)
tree93ea0673d055744d0f5103f0f9cf6027754a038d /src
parent01ee11e448a10717d5c3db70a2aca420ddf95fd2 (diff)
Use modal dialog to re-authorize OAuth2 accounts
This replaces the "Open browser" button within the account settings.
Diffstat (limited to 'src')
-rw-r--r--src/gui/CMakeLists.txt2
-rw-r--r--src/gui/accountsettings.cpp52
-rw-r--r--src/gui/accountsettings.h3
-rw-r--r--src/gui/accountsettings.ui11
-rw-r--r--src/gui/askforoauthlogindialog.cpp54
-rw-r--r--src/gui/askforoauthlogindialog.h42
-rw-r--r--src/gui/askforoauthlogindialog.ui106
-rw-r--r--src/gui/creds/httpcredentialsgui.cpp15
-rw-r--r--src/gui/creds/httpcredentialsgui.h3
9 files changed, 264 insertions, 24 deletions
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 733e0401f..9444cc7ef 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -24,6 +24,7 @@ set(client_UI_SRCS
proxyauthdialog.ui
notificationwidget.ui
logbrowser.ui
+ askforoauthlogindialog.ui
)
set(client_SRCS
@@ -79,6 +80,7 @@ set(client_SRCS
translations.cpp
creds/httpcredentialsgui.cpp
updateurldialog.cpp
+ askforoauthlogindialog.cpp
models/activitylistmodel.cpp
models/expandingheaderview.cpp
diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp
index 2fd40b121..9659bf0ab 100644
--- a/src/gui/accountsettings.cpp
+++ b/src/gui/accountsettings.cpp
@@ -39,22 +39,24 @@
#include <math.h>
+#include <QAction>
+#include <QClipboard>
#include <QDesktopServices>
#include <QDir>
+#include <QIcon>
+#include <QKeySequence>
#include <QListWidgetItem>
#include <QMessageBox>
-#include <QAction>
-#include <QVBoxLayout>
+#include <QToolTip>
#include <QTreeView>
-#include <QKeySequence>
-#include <QIcon>
+#include <QVBoxLayout>
#include <QVariant>
-#include <QToolTip>
-#include <qstringlistmodel.h>
#include <qpropertyanimation.h>
+#include <qstringlistmodel.h>
#include "account.h"
#include "askexperimentalvirtualfilesfeaturemessagebox.h"
+#include "askforoauthlogindialog.h"
namespace OCC {
@@ -186,11 +188,6 @@ AccountSettings::AccountSettings(AccountStatePtr accountState, QWidget *parent)
connect(&_quotaInfo, &QuotaInfo::quotaUpdated,
this, &AccountSettings::slotUpdateQuota);
-
- ui->openBrowserButton->setVisible(false);
- connect(ui->openBrowserButton, &QToolButton::clicked, this, [this]{
- qobject_cast<HttpCredentialsGui *>(_accountState->account()->credentials())->openBrowser();
- });
}
@@ -797,7 +794,9 @@ void AccountSettings::slotAccountStateChanged()
errors << tr("The server version %1 is unsupported! Proceed at your own risk.").arg(account->capabilities().status().versionString());
}
showConnectionLabel(tr("Connected to %1.").arg(serverWithUser), errors);
- ui->openBrowserButton->setVisible(false);
+ if (_askForOAuthLoginDialog != nullptr) {
+ _askForOAuthLoginDialog->accept();
+ }
break;
}
case AccountState::ServiceUnavailable:
@@ -812,10 +811,31 @@ void AccountSettings::slotAccountStateChanged()
case AccountState::AskingCredentials: {
auto cred = qobject_cast<HttpCredentialsGui *>(account->credentials());
if (cred && cred->isUsingOAuth()) {
- connect(cred, &HttpCredentialsGui::authorisationLinkChanged,
- this, &AccountSettings::slotAccountStateChanged, Qt::UniqueConnection);
- showConnectionLabel(tr("Obtaining authorization from the browser."));
- ui->openBrowserButton->setVisible(true);
+ if (_askForOAuthLoginDialog != nullptr) {
+ qCDebug(lcAccountSettings) << "ask for OAuth login dialog is shown already";
+ return;
+ }
+
+ qCDebug(lcAccountSettings) << "showing modal dialog asking user to log in again via OAuth2";
+
+ _askForOAuthLoginDialog = new AskForOAuthLoginDialog(_accountState->account(), this);
+
+ // make sure to clean up the memory and to null the QPointer once finished
+ _askForOAuthLoginDialog->setAttribute(Qt::WA_DeleteOnClose);
+
+ connect(
+ cred, &HttpCredentialsGui::authorisationLinkChanged,
+ this, &AccountSettings::slotAccountStateChanged,
+ Qt::UniqueConnection);
+
+ connect(_askForOAuthLoginDialog, &AskForOAuthLoginDialog::rejected, this, [this]() {
+ // if a user dismisses the dialog, we have no choice but signing them out
+ _accountState->signOutByUi();
+ });
+
+ showConnectionLabel(tr("Reauthorization required."));
+
+ _askForOAuthLoginDialog->show();
} else {
showConnectionLabel(tr("Connecting to %1...").arg(serverWithUser));
}
diff --git a/src/gui/accountsettings.h b/src/gui/accountsettings.h
index 819d7367b..e23e5f2dd 100644
--- a/src/gui/accountsettings.h
+++ b/src/gui/accountsettings.h
@@ -104,6 +104,9 @@ private:
QuotaInfo _quotaInfo;
QAction *_toggleSignInOutAction;
QAction *_addAccountAction;
+
+ // needed to make sure we show only one dialog at a time
+ QPointer<QDialog> _askForOAuthLoginDialog = nullptr;
};
} // namespace OCC
diff --git a/src/gui/accountsettings.ui b/src/gui/accountsettings.ui
index b9904a3f2..9e88c37dd 100644
--- a/src/gui/accountsettings.ui
+++ b/src/gui/accountsettings.ui
@@ -40,13 +40,6 @@
</widget>
</item>
<item>
- <widget class="QToolButton" name="openBrowserButton">
- <property name="text">
- <string>Re-open Browser</string>
- </property>
- </widget>
- </item>
- <item>
<widget class="QToolButton" name="_accountToolbox">
<property name="text">
<string>...</string>
@@ -280,6 +273,8 @@
</item>
</layout>
</widget>
- <resources/>
+ <resources>
+ <include location="../../client.qrc"/>
+ </resources>
<connections/>
</ui>
diff --git a/src/gui/askforoauthlogindialog.cpp b/src/gui/askforoauthlogindialog.cpp
new file mode 100644
index 000000000..1eaff71a3
--- /dev/null
+++ b/src/gui/askforoauthlogindialog.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) Fabian Müller <fmueller@owncloud.com>
+ *
+ * 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 2 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.
+ */
+
+#include "askforoauthlogindialog.h"
+#include "application.h"
+#include "creds/httpcredentialsgui.h"
+#include "theme.h"
+#include "ui_askforoauthlogindialog.h"
+
+#include <QClipboard>
+
+namespace OCC {
+
+AskForOAuthLoginDialog::AskForOAuthLoginDialog(AccountPtr accountPtr, QWidget *parent)
+ : QDialog(parent)
+ , _ui(new ::Ui::AskForOAuthLoginDialog)
+{
+ _ui->setupUi(this);
+
+ _ui->label->setText(tr("The account %1 has been logged out by the server.\n\nPlease use your browser to log into %2.").arg(accountPtr->displayName(), Theme::instance()->appNameGUI()));
+ _ui->iconLabel->setPixmap(Theme::instance()->applicationIcon().pixmap(64, 64));
+
+ setModal(true);
+
+ setFixedSize(this->sizeHint());
+
+ connect(_ui->openBrowserButton, &QPushButton::clicked, this, [this, accountPtr]() {
+ qobject_cast<HttpCredentialsGui *>(accountPtr->credentials())->openBrowser();
+ _ui->openBrowserButton->setText(tr("Reopen browser"));
+ });
+ connect(_ui->copyUrlToClipboardButton, &QPushButton::clicked, this, [accountPtr]() {
+ // TODO: use authorisationLinkAsync
+ auto link = qobject_cast<HttpCredentialsGui *>(accountPtr->credentials())->authorisationLink().toString();
+ ocApp()->clipboard()->setText(link);
+ });
+}
+
+AskForOAuthLoginDialog::~AskForOAuthLoginDialog()
+{
+ delete _ui;
+}
+
+} // OCC
diff --git a/src/gui/askforoauthlogindialog.h b/src/gui/askforoauthlogindialog.h
new file mode 100644
index 000000000..4b63c180c
--- /dev/null
+++ b/src/gui/askforoauthlogindialog.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) Fabian Müller <fmueller@owncloud.com>
+ *
+ * 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 2 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.
+ */
+
+#pragma once
+
+#include "account.h"
+#include <QDialog>
+
+namespace Ui {
+class AskForOAuthLoginDialog;
+}
+
+namespace OCC {
+
+class AskForOAuthLoginDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit AskForOAuthLoginDialog(AccountPtr accountPtr, QWidget *parent = nullptr);
+ ~AskForOAuthLoginDialog() override;
+
+Q_SIGNALS:
+ void openBrowserButtonClicked();
+ void copyUrlToClipboardButtonClicked();
+
+private:
+ ::Ui::AskForOAuthLoginDialog *_ui;
+};
+
+} // OCC
diff --git a/src/gui/askforoauthlogindialog.ui b/src/gui/askforoauthlogindialog.ui
new file mode 100644
index 000000000..9d83c0970
--- /dev/null
+++ b/src/gui/askforoauthlogindialog.ui
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AskForOAuthLoginDialog</class>
+ <widget class="QDialog" name="AskForOAuthLoginDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>435</width>
+ <height>135</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Login required</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="iconLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string notr="true">icon (placeholder)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>50</height>
+ </size>
+ </property>
+ <property name="text">
+ <string notr="true">The account has been logged out [...] &lt;placeholder&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>10</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="openBrowserButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Open browser</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="copyUrlToClipboardButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Copy URL to clipboard</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../resources/client.qrc">
+ <normaloff>:/client/resources/light/clipboard.svg</normaloff>:/client/resources/light/clipboard.svg</iconset>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources>
+ <include location="../resources/client.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/src/gui/creds/httpcredentialsgui.cpp b/src/gui/creds/httpcredentialsgui.cpp
index 136339a27..601178f01 100644
--- a/src/gui/creds/httpcredentialsgui.cpp
+++ b/src/gui/creds/httpcredentialsgui.cpp
@@ -166,4 +166,19 @@ QString HttpCredentialsGui::requestAppPasswordText(const Account *account)
return tr("<a href=\"%1\">Click here</a> to request an app password from the web interface.")
.arg(Utility::concatUrlPath(baseUrl, QStringLiteral("/index.php/settings/personal?sectionid=security#apppasswords")).toString());
}
+
+QUrl HttpCredentialsGui::authorisationLink() const
+{
+ OC_ASSERT(isUsingOAuth());
+ if (isUsingOAuth()) {
+ if (_asyncAuth) {
+ return _asyncAuth->authorisationLink();
+ } else {
+ qCWarning(lcHttpCredentialsGui) << "There is no authentication job running, did the previous attempt fail?";
+ return {};
+ }
+ }
+ return {};
+}
+
} // namespace OCC
diff --git a/src/gui/creds/httpcredentialsgui.h b/src/gui/creds/httpcredentialsgui.h
index 2332735f3..d567ac8a3 100644
--- a/src/gui/creds/httpcredentialsgui.h
+++ b/src/gui/creds/httpcredentialsgui.h
@@ -45,6 +45,9 @@ public:
}
void openBrowser();
+
+ QUrl authorisationLink() const;
+
/**
* This will query the server and either uses OAuth via _asyncAuth->start()
* or call showDialog to ask the password