addcertificatedialog.ui
proxyauthdialog.ui
mnemonicdialog.ui
+ wizard/flow2authwidget.ui
wizard/owncloudadvancedsetuppage.ui
wizard/owncloudconnectionmethoddialog.ui
wizard/owncloudhttpcredspage.ui
wizard/owncloudoauthcredspage.ui
- wizard/flow2authcredspage.ui
- wizard/flow2authwidget.ui
wizard/owncloudsetupnocredspage.ui
wizard/owncloudwizardresultpage.ui
wizard/webview.ui
*/
#include <QDesktopServices>
+#include <QApplication>
+#include <QClipboard>
#include <QTimer>
#include <QBuffer>
#include "account.h"
-#include "creds/flow2auth.h"
+#include "flow2auth.h"
#include <QJsonObject>
#include <QJsonDocument>
#include "theme.h"
Q_LOGGING_CATEGORY(lcFlow2auth, "nextcloud.sync.credentials.flow2auth", QtInfoMsg)
+
+Flow2Auth::Flow2Auth(Account *account, QObject *parent)
+ : QObject(parent)
+ , _account(account)
+ , _isBusy(false)
+ , _hasToken(false)
+{
+ _pollTimer.setInterval(1000);
+ QObject::connect(&_pollTimer, &QTimer::timeout, this, &Flow2Auth::slotPollTimerTimeout);
+}
+
Flow2Auth::~Flow2Auth()
{
}
void Flow2Auth::openBrowser()
{
- _pollTimer.stop();
+ fetchNewToken(TokenAction::actionOpenBrowser);
+}
+
+void Flow2Auth::copyLinkToClipboard()
+{
+ fetchNewToken(TokenAction::actionCopyLinkToClipboard);
+}
+
+void Flow2Auth::fetchNewToken(const TokenAction action)
+{
+ if(_isBusy)
+ return;
+
+ _isBusy = true;
+ _hasToken = false;
+
+ emit statusChanged(PollStatus::statusFetchToken, 0);
// Step 1: Initiate a login, do an anonymous POST request
QUrl url = Utility::concatUrlPath(_account->url().toString(), QLatin1String("/index.php/login/v2"));
auto job = _account->sendRequest("POST", url, req);
job->setTimeout(qMin(30 * 1000ll, job->timeoutMsec()));
- QObject::connect(job, &SimpleNetworkJob::finishedSignal, this, [this](QNetworkReply *reply) {
+ QObject::connect(job, &SimpleNetworkJob::finishedSignal, this, [this, action](QNetworkReply *reply) {
auto jsonData = reply->readAll();
QJsonParseError jsonParseError;
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
+ QString pollToken, pollEndpoint, loginUrl;
- QString pollToken = json.value("poll").toObject().value("token").toString();
- QString pollEndpoint = json.value("poll").toObject().value("endpoint").toString();
- QUrl loginUrl = json["login"].toString();
+ if (reply->error() == QNetworkReply::NoError && jsonParseError.error == QJsonParseError::NoError
+ && !json.isEmpty()) {
+ pollToken = json.value("poll").toObject().value("token").toString();
+ pollEndpoint = json.value("poll").toObject().value("endpoint").toString();
+ loginUrl = json["login"].toString();
+ }
if (reply->error() != QNetworkReply::NoError || jsonParseError.error != QJsonParseError::NoError
|| json.isEmpty() || pollToken.isEmpty() || pollEndpoint.isEmpty() || loginUrl.isEmpty()) {
errorReason = tr("The reply from the server did not contain all expected fields");
}
qCWarning(lcFlow2auth) << "Error when getting the loginUrl" << json << errorReason;
- emit result(Error);
+ emit result(Error, errorReason);
+ _pollTimer.stop();
+ _isBusy = false;
return;
}
ConfigFile cfg;
std::chrono::milliseconds polltime = cfg.remotePollInterval();
qCInfo(lcFlow2auth) << "setting remote poll timer interval to" << polltime.count() << "msec";
- _pollTimer.setInterval(1000);
- QObject::connect(&_pollTimer, &QTimer::timeout, this, &Flow2Auth::slotPollTimerTimeout);
_secondsInterval = (polltime.count() / 1000);
_secondsLeft = _secondsInterval;
- emit statusChanged(_secondsLeft);
- _pollTimer.start();
+ emit statusChanged(PollStatus::statusPollCountdown, _secondsLeft);
+ if(!_pollTimer.isActive()) {
+ _pollTimer.start();
+ }
- // 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());
+
+ switch(action)
+ {
+ case actionOpenBrowser:
+ // Try to open Browser
+ if (!QDesktopServices::openUrl(authorisationLink())) {
+ // We cannot open the browser, then we claim we don't support Flow2Auth.
+ // Our UI callee will ask the user to copy and open the link.
+ emit result(NotSupported);
+ }
+ break;
+ case actionCopyLinkToClipboard:
+ QApplication::clipboard()->setText(authorisationLink().toString(QUrl::FullyEncoded));
+ emit statusChanged(PollStatus::statusCopyLinkToClipboard, 0);
+ break;
}
+
+ _isBusy = false;
+ _hasToken = true;
});
}
void Flow2Auth::slotPollTimerTimeout()
{
- _pollTimer.stop();
+ if(_isBusy || !_hasToken)
+ return;
- _secondsLeft--;
- emit statusChanged(_secondsLeft);
+ _isBusy = true;
+ _secondsLeft--;
if(_secondsLeft > 0) {
- _pollTimer.start();
+ emit statusChanged(PollStatus::statusPollCountdown, _secondsLeft);
+ _isBusy = false;
return;
}
+ emit statusChanged(PollStatus::statusPollNow, 0);
// Step 2: Poll
QNetworkRequest req;
auto jsonData = reply->readAll();
QJsonParseError jsonParseError;
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
-
- QUrl serverUrl = json["server"].toString();
- QString loginName = json["loginName"].toString();
- QString appPassword = json["appPassword"].toString();
+ QUrl serverUrl;
+ QString loginName, appPassword;
+
+ if (reply->error() == QNetworkReply::NoError && jsonParseError.error == QJsonParseError::NoError
+ && !json.isEmpty()) {
+ serverUrl = json["server"].toString();
+ loginName = json["loginName"].toString();
+ appPassword = json["appPassword"].toString();
+ }
if (reply->error() != QNetworkReply::NoError || jsonParseError.error != QJsonParseError::NoError
|| json.isEmpty() || serverUrl.isEmpty() || loginName.isEmpty() || appPassword.isEmpty()) {
}
qCDebug(lcFlow2auth) << "Error when polling for the appPassword" << json << errorReason;
+ // We get a 404 until authentication is done, so don't show this error in the GUI.
+ if(reply->error() != QNetworkReply::ContentNotFoundError)
+ emit result(Error, errorReason);
+
// Forget sensitive data
appPassword.clear();
loginName.clear();
// Failed: poll again
_secondsLeft = _secondsInterval;
- _pollTimer.start();
+ _isBusy = false;
return;
}
+ _pollTimer.stop();
+
// Success
qCInfo(lcFlow2auth) << "Success getting the appPassword for user: " << loginName << ", server: " << serverUrl.toString();
_account->setUrl(serverUrl);
- emit result(LoggedIn, loginName, appPassword);
+ emit result(LoggedIn, QString(), loginName, appPassword);
// Forget sensitive data
appPassword.clear();
loginName.clear();
+
+ _loginUrl.clear();
+ _pollToken.clear();
+ _pollEndpoint.clear();
+
+ _isBusy = false;
+ _hasToken = false;
});
}
void Flow2Auth::slotPollNow()
{
// poll now if we're not already doing so
- if(_pollTimer.isActive()) {
- _secondsLeft = 1;
- slotPollTimerTimeout();
- }
+ if(_isBusy || !_hasToken)
+ return;
+
+ _secondsLeft = 1;
+ slotPollTimerTimeout();
}
} // namespace OCC
{
Q_OBJECT
public:
- Flow2Auth(Account *account, QObject *parent)
- : QObject(parent)
- , _account(account)
- {
- }
+ enum TokenAction {
+ actionOpenBrowser = 1,
+ actionCopyLinkToClipboard
+ };
+ enum PollStatus {
+ statusPollCountdown = 1,
+ statusPollNow,
+ statusFetchToken,
+ statusCopyLinkToClipboard
+ };
+
+ Flow2Auth(Account *account, QObject *parent);
~Flow2Auth();
enum Result { NotSupported,
Q_ENUM(Result);
void start();
void openBrowser();
+ void copyLinkToClipboard();
QUrl authorisationLink() const;
signals:
* The state has changed.
* when logged in, appPassword has the value of the app password.
*/
- void result(Flow2Auth::Result result, const QString &user = QString(), const QString &appPassword = QString());
+ void result(Flow2Auth::Result result, const QString &errorString = QString(),
+ const QString &user = QString(), const QString &appPassword = QString());
- void statusChanged(int secondsLeft);
+ void statusChanged(const PollStatus status, int secondsLeft);
public slots:
void slotPollNow();
void slotPollTimerTimeout();
private:
+ void fetchNewToken(const TokenAction action);
+
Account *_account;
QUrl _loginUrl;
QString _pollToken;
QTimer _pollTimer;
int _secondsLeft;
int _secondsInterval;
+ bool _isBusy;
+ bool _hasToken;
};
-
} // namespace OCC
_containerLayout->addWidget(_infoLabel);
if (_useFlow2) {
- _flow2AuthWidget = new Flow2AuthWidget(account);
_flow2AuthWidget = new Flow2AuthWidget();
_containerLayout->addWidget(_flow2AuthWidget);
- connect(_flow2AuthWidget, &Flow2AuthWidget::urlCatched, this, &WebFlowCredentialsDialog::urlCatched);
+ connect(_flow2AuthWidget, &Flow2AuthWidget::authResult, this, &WebFlowCredentialsDialog::slotFlow2AuthResult);
// Connect styleChanged events to our widgets, so they can adapt (Dark-/Light-Mode switching)
connect(this, &WebFlowCredentialsDialog::styleChanged, _flow2AuthWidget, &Flow2AuthWidget::slotStyleChanged);
// allow Flow2 page to poll on window activation
connect(this, &WebFlowCredentialsDialog::onActivate, _flow2AuthWidget, &Flow2AuthWidget::slotPollNow);
+
+ _flow2AuthWidget->startAuth(account);
} else {
_webView = new WebView();
_containerLayout->addWidget(_webView);
}
if (_flow2AuthWidget) {
+ _flow2AuthWidget->resetAuth();
_flow2AuthWidget->deleteLater();
_flow2AuthWidget = nullptr;
}
});
}
+void WebFlowCredentialsDialog::slotFlow2AuthResult(Flow2Auth::Result r, const QString &errorString, const QString &user, const QString &appPassword)
+{
+ if(r == Flow2Auth::LoggedIn) {
+ emit urlCatched(user, appPassword, QString());
+ } else {
+ // bring window to top
+ slotShowSettingsDialog();
+ }
+}
+
} // namespace OCC
#include <QUrl>
#include "accountfwd.h"
+#include "creds/flow2auth.h"
class QLabel;
class QVBoxLayout;
void changeEvent(QEvent *) override;
public slots:
+ void slotFlow2AuthResult(Flow2Auth::Result, const QString &errorString, const QString &user, const QString &appPassword);
void slotShowSettingsDialog();
signals:
*/
#include <QVariant>
-#include <QMenu>
-#include <QClipboard>
+#include <QVBoxLayout>
-#include "wizard/flow2authcredspage.h"
+#include "flow2authcredspage.h"
#include "theme.h"
#include "account.h"
#include "cookiejar.h"
#include "wizard/owncloudwizardcommon.h"
#include "wizard/owncloudwizard.h"
+#include "wizard/flow2authwidget.h"
#include "creds/credentialsfactory.h"
#include "creds/webflowcredentials.h"
-#include "QProgressIndicator.h"
-
namespace OCC {
Flow2AuthCredsPage::Flow2AuthCredsPage()
- : AbstractCredentialsWizardPage()
- , _ui()
- , _progressIndi(new QProgressIndicator(this))
+ : AbstractCredentialsWizardPage(),
+ _flow2AuthWidget(nullptr)
{
- _ui.setupUi(this);
-
- Theme *theme = Theme::instance();
- _ui.topLabel->hide();
- _ui.bottomLabel->hide();
- QVariant variant = theme->customMedia(Theme::oCSetupTop);
- WizardCommon::setupCustomMedia(variant, _ui.topLabel);
- variant = theme->customMedia(Theme::oCSetupBottom);
- WizardCommon::setupCustomMedia(variant, _ui.bottomLabel);
-
- WizardCommon::initErrorLabel(_ui.errorLabel);
+ _layout = new QVBoxLayout(this);
setTitle(WizardCommon::titleTemplate().arg(tr("Connect to %1").arg(Theme::instance()->appNameGUI())));
setSubTitle(WizardCommon::subTitleTemplate().arg(tr("Login in your browser (Login Flow v2)")));
- connect(_ui.openLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthCredsPage::slotOpenBrowser);
- connect(_ui.copyLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthCredsPage::slotCopyLinkToClipboard);
+ _flow2AuthWidget = new Flow2AuthWidget();
+ _layout->addWidget(_flow2AuthWidget);
+
+ connect(_flow2AuthWidget, &Flow2AuthWidget::authResult, this, &Flow2AuthCredsPage::slotFlow2AuthResult);
- _ui.horizontalLayout->addWidget(_progressIndi);
- stopSpinner(false);
+ // Connect styleChanged events to our widgets, so they can adapt (Dark-/Light-Mode switching)
+ connect(this, &Flow2AuthCredsPage::styleChanged, _flow2AuthWidget, &Flow2AuthWidget::slotStyleChanged);
- customizeStyle();
+ // allow Flow2 page to poll on window activation
+ connect(this, &Flow2AuthCredsPage::pollNow, _flow2AuthWidget, &Flow2AuthWidget::slotPollNow);
}
void Flow2AuthCredsPage::initializePage()
OwncloudWizard *ocWizard = qobject_cast<OwncloudWizard *>(wizard());
Q_ASSERT(ocWizard);
ocWizard->account()->setCredentials(CredentialsFactory::create("http"));
- _asyncAuth.reset(new Flow2Auth(ocWizard->account().data(), this));
- connect(_asyncAuth.data(), &Flow2Auth::result, this, &Flow2AuthCredsPage::asyncAuthResult, Qt::QueuedConnection);
- connect(_asyncAuth.data(), &Flow2Auth::statusChanged, this, &Flow2AuthCredsPage::slotStatusChanged);
- connect(this, &Flow2AuthCredsPage::pollNow, _asyncAuth.data(), &Flow2Auth::slotPollNow);
- _asyncAuth->start();
+
+ if(_flow2AuthWidget)
+ _flow2AuthWidget->startAuth(ocWizard->account().data());
// Don't hide the wizard (avoid user confusion)!
//wizard()->hide();
{
// The next or back button was activated, show the wizard again
wizard()->show();
- _asyncAuth.reset();
+ if(_flow2AuthWidget)
+ _flow2AuthWidget->resetAuth();
// Forget sensitive data
_appPassword.clear();
_user.clear();
}
-void Flow2AuthCredsPage::asyncAuthResult(Flow2Auth::Result r, const QString &user,
- const QString &appPassword)
+void Flow2AuthCredsPage::slotFlow2AuthResult(Flow2Auth::Result r, const QString &errorString, const QString &user, const QString &appPassword)
{
- stopSpinner(false);
-
switch (r) {
case Flow2Auth::NotSupported: {
/* Flow2Auth not supported (can't open browser) */
- _ui.errorLabel->setText(tr("Unable to open the Browser, please copy the link to your Browser."));
- _ui.errorLabel->show();
+ wizard()->show();
/* Don't fallback to HTTP credentials */
/*OwncloudWizard *ocWizard = qobject_cast<OwncloudWizard *>(wizard());
}
case Flow2Auth::Error:
/* Error while getting the access token. (Timeout, or the server did not accept our client credentials */
- _ui.errorLabel->show();
wizard()->show();
break;
case Flow2Auth::LoggedIn: {
return false; /* We can never go forward manually */
}
-void Flow2AuthCredsPage::slotOpenBrowser()
-{
- if (_ui.errorLabel)
- _ui.errorLabel->hide();
-
- if (_asyncAuth)
- _asyncAuth->openBrowser();
-}
-
-void Flow2AuthCredsPage::slotCopyLinkToClipboard()
-{
- if (_asyncAuth)
- QApplication::clipboard()->setText(_asyncAuth->authorisationLink().toString(QUrl::FullyEncoded));
-}
-
void Flow2AuthCredsPage::slotPollNow()
{
emit pollNow();
}
-void Flow2AuthCredsPage::slotStatusChanged(int secondsLeft)
-{
- const bool pollingNow = (secondsLeft == 0);
-
- _ui.statusLabel->setText(tr("Polling for authorization") + (pollingNow ? "" : QString(" " + tr("in %1 seconds").arg(secondsLeft))) + "...");
-
- if(pollingNow)
- startSpinner();
- else
- stopSpinner(true);
-}
-
-void Flow2AuthCredsPage::startSpinner()
-{
- _ui.horizontalLayout->setEnabled(true);
- _ui.statusLabel->setVisible(true);
- _progressIndi->setVisible(true);
- _progressIndi->startAnimation();
-
- _ui.openLinkButton->setEnabled(false);
- _ui.copyLinkButton->setEnabled(false);
-}
-
-void Flow2AuthCredsPage::stopSpinner(bool showStatusLabel)
-{
- _ui.horizontalLayout->setEnabled(false);
- _ui.statusLabel->setVisible(showStatusLabel);
- _progressIndi->setVisible(false);
- _progressIndi->stopAnimation();
-
- _ui.openLinkButton->setEnabled(true);
- _ui.copyLinkButton->setEnabled(true);
-}
-
void Flow2AuthCredsPage::slotStyleChanged()
{
- customizeStyle();
-}
-
-void Flow2AuthCredsPage::customizeStyle()
-{
- if(_progressIndi)
- _progressIndi->setColor(QGuiApplication::palette().color(QPalette::Text));
+ emit styleChanged();
}
} // namespace OCC
#include "accountfwd.h"
#include "creds/flow2auth.h"
-#include "ui_flow2authcredspage.h"
-
+class QVBoxLayout;
class QProgressIndicator;
namespace OCC {
+class Flow2AuthWidget;
+
class Flow2AuthCredsPage : public AbstractCredentialsWizardPage
{
Q_OBJECT
bool isComplete() const override;
public Q_SLOTS:
- void asyncAuthResult(Flow2Auth::Result, const QString &user, const QString &appPassword);
+ void slotFlow2AuthResult(Flow2Auth::Result, const QString &errorString, const QString &user, const QString &appPassword);
void slotPollNow();
- void slotStatusChanged(int secondsLeft);
void slotStyleChanged();
signals:
void connectToOCUrl(const QString &);
void pollNow();
+ void styleChanged();
public:
QString _user;
QString _appPassword;
- QScopedPointer<Flow2Auth> _asyncAuth;
- Ui_Flow2AuthCredsPage _ui;
-
-protected slots:
- void slotOpenBrowser();
- void slotCopyLinkToClipboard();
private:
- void startSpinner();
- void stopSpinner(bool showStatusLabel);
- void customizeStyle();
-
- QProgressIndicator *_progressIndi;
+ Flow2AuthWidget *_flow2AuthWidget;
+ QVBoxLayout *_layout;
};
} // namespace OCC
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>Flow2AuthCredsPage</class>
- <widget class="QWidget" name="Flow2AuthCredsPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>424</width>
- <height>373</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Browser Authentication</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="topLabel">
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Please switch to your browser to proceed.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="errorLabel">
- <property name="text">
- <string>An error occurred while connecting. Please try again.</string>
- </property>
- <property name="textFormat">
- <enum>Qt::PlainText</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCommandLinkButton" name="openLinkButton">
- <property name="text">
- <string>Re-open Browser</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCommandLinkButton" name="copyLinkButton">
- <property name="font">
- <font>
- <weight>50</weight>
- <bold>false</bold>
- </font>
- </property>
- <property name="text">
- <string>Copy link</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>10</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="statusLabel">
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout"/>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>127</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="bottomLabel">
- <property name="text">
- <string notr="true">TextLabel</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
#include "flow2authwidget.h"
-#include <QDesktopServices>
-#include <QProgressBar>
-#include <QLoggingCategory>
-#include <QLocale>
-#include <QMessageBox>
-
-#include <QMenu>
-#include <QClipboard>
-
#include "common/utility.h"
#include "account.h"
#include "wizard/owncloudwizardcommon.h"
Q_LOGGING_CATEGORY(lcFlow2AuthWidget, "gui.wizard.flow2authwidget", QtInfoMsg)
-Flow2AuthWidget::Flow2AuthWidget(Account *account, QWidget *parent)
+Flow2AuthWidget::Flow2AuthWidget(QWidget *parent)
: QWidget(parent)
- , _account(account)
+ , _account(nullptr)
, _ui()
, _progressIndi(new QProgressIndicator(this))
{
_ui.setupUi(this);
WizardCommon::initErrorLabel(_ui.errorLabel);
+ _ui.errorLabel->setTextFormat(Qt::RichText);
connect(_ui.openLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthWidget::slotOpenBrowser);
connect(_ui.copyLinkButton, &QCommandLinkButton::clicked, this, &Flow2AuthWidget::slotCopyLinkToClipboard);
_ui.horizontalLayout->addWidget(_progressIndi);
stopSpinner(false);
+ customizeStyle();
+}
+
+void Flow2AuthWidget::startAuth(Account *account)
+{
+ Flow2Auth *oldAuth = _asyncAuth.take();
+ if(oldAuth)
+ oldAuth->deleteLater();
+
+ if(account) {
+ _account = account;
+
_asyncAuth.reset(new Flow2Auth(_account, this));
- connect(_asyncAuth.data(), &Flow2Auth::result, this, &Flow2AuthWidget::asyncAuthResult, Qt::QueuedConnection);
+ connect(_asyncAuth.data(), &Flow2Auth::result, this, &Flow2AuthWidget::slotAuthResult, Qt::QueuedConnection);
connect(_asyncAuth.data(), &Flow2Auth::statusChanged, this, &Flow2AuthWidget::slotStatusChanged);
connect(this, &Flow2AuthWidget::pollNow, _asyncAuth.data(), &Flow2Auth::slotPollNow);
_asyncAuth->start();
+ }
+}
- customizeStyle();
+void Flow2AuthWidget::resetAuth(Account *account)
+{
+ startAuth(account);
}
-void Flow2AuthWidget::asyncAuthResult(Flow2Auth::Result r, const QString &user,
- const QString &appPassword)
+void Flow2AuthWidget::slotAuthResult(Flow2Auth::Result r, const QString &errorString, const QString &user, const QString &appPassword)
{
stopSpinner(false);
break;
case Flow2Auth::Error:
/* Error while getting the access token. (Timeout, or the server did not accept our client credentials */
+ _ui.errorLabel->setText(errorString);
_ui.errorLabel->show();
break;
case Flow2Auth::LoggedIn: {
- _user = user;
- _appPassword = appPassword;
- emit urlCatched(_user, _appPassword, QString());
+ _ui.errorLabel->hide();
break;
}
}
+
+ emit authResult(r, errorString, user, appPassword);
}
void Flow2AuthWidget::setError(const QString &error) {
}
Flow2AuthWidget::~Flow2AuthWidget() {
- _asyncAuth.reset();
-
// Forget sensitive data
- _appPassword.clear();
- _user.clear();
+ _asyncAuth.reset();
}
void Flow2AuthWidget::slotOpenBrowser()
void Flow2AuthWidget::slotCopyLinkToClipboard()
{
+ if (_ui.errorLabel)
+ _ui.errorLabel->hide();
+
if (_asyncAuth)
- QApplication::clipboard()->setText(_asyncAuth->authorisationLink().toString(QUrl::FullyEncoded));
+ _asyncAuth->copyLinkToClipboard();
}
void Flow2AuthWidget::slotPollNow()
emit pollNow();
}
-void Flow2AuthWidget::slotStatusChanged(int secondsLeft)
+void Flow2AuthWidget::slotStatusChanged(Flow2Auth::PollStatus status, int secondsLeft)
{
- const bool pollingNow = (secondsLeft == 0);
-
- _ui.statusLabel->setText(tr("Polling for authorization") + (pollingNow ? "" : QString(" " + tr("in %1 seconds").arg(secondsLeft))) + "...");
-
- if(pollingNow)
+ switch(status)
+{
+ case Flow2Auth::statusPollCountdown:
+ _ui.statusLabel->setText(tr("Waiting for authorization") + QString(" (%1)").arg(secondsLeft));
+ stopSpinner(true);
+ break;
+ case Flow2Auth::statusPollNow:
+ _ui.statusLabel->setText(tr("Polling for authorization") + "...");
+ startSpinner();
+ break;
+ case Flow2Auth::statusFetchToken:
+ _ui.statusLabel->setText(tr("Starting authorization") + "...");
startSpinner();
- else
+ break;
+ case Flow2Auth::statusCopyLinkToClipboard:
+ _ui.statusLabel->setText(tr("Link copied to clipboard."));
stopSpinner(true);
+ break;
+ }
}
void Flow2AuthWidget::startSpinner()
{
Q_OBJECT
public:
- Flow2AuthWidget(Account *account, QWidget *parent = nullptr);
+ Flow2AuthWidget(QWidget *parent = nullptr);
virtual ~Flow2AuthWidget();
+ void startAuth(Account *account);
+ void resetAuth(Account *account = nullptr);
void setError(const QString &error);
public Q_SLOTS:
- void asyncAuthResult(Flow2Auth::Result, const QString &user, const QString &appPassword);
+ void slotAuthResult(Flow2Auth::Result, const QString &errorString, const QString &user, const QString &appPassword);
void slotPollNow();
- void slotStatusChanged(int secondsLeft);
+ void slotStatusChanged(Flow2Auth::PollStatus status, int secondsLeft);
void slotStyleChanged();
signals:
- void urlCatched(const QString user, const QString pass, const QString host);
+ void authResult(Flow2Auth::Result, const QString &errorString, const QString &user, const QString &appPassword);
void pollNow();
private:
Account *_account;
- QString _user;
- QString _appPassword;
QScopedPointer<Flow2Auth> _asyncAuth;
Ui_Flow2AuthWidget _ui;