mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 23:28:14 +03:00
OAuth2: Have a link to the browser in the owncloud UI
When the browser is open, ad a link in the ui to re-open the browser. Issue #5893
This commit is contained in:
parent
6be122edc4
commit
5738110cb6
9 changed files with 50 additions and 13 deletions
|
@ -30,6 +30,7 @@
|
||||||
#include "accountmanager.h"
|
#include "accountmanager.h"
|
||||||
#include "owncloudsetupwizard.h"
|
#include "owncloudsetupwizard.h"
|
||||||
#include "creds/abstractcredentials.h"
|
#include "creds/abstractcredentials.h"
|
||||||
|
#include "creds/httpcredentialsgui.h"
|
||||||
#include "tooltipupdater.h"
|
#include "tooltipupdater.h"
|
||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
|
@ -180,8 +181,8 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent)
|
||||||
|
|
||||||
ui->connectLabel->setText(tr("No account configured."));
|
ui->connectLabel->setText(tr("No account configured."));
|
||||||
|
|
||||||
connect(_accountState, SIGNAL(stateChanged(int)), SLOT(slotAccountStateChanged(int)));
|
connect(_accountState, &AccountState::stateChanged, this, &AccountSettings::slotAccountStateChanged);
|
||||||
slotAccountStateChanged(_accountState->state());
|
slotAccountStateChanged();
|
||||||
|
|
||||||
connect(&_quotaInfo, SIGNAL(quotaUpdated(qint64, qint64)),
|
connect(&_quotaInfo, SIGNAL(quotaUpdated(qint64, qint64)),
|
||||||
this, SLOT(slotUpdateQuota(qint64, qint64)));
|
this, SLOT(slotUpdateQuota(qint64, qint64)));
|
||||||
|
@ -622,8 +623,9 @@ void AccountSettings::slotUpdateQuota(qint64 total, qint64 used)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotAccountStateChanged(int state)
|
void AccountSettings::slotAccountStateChanged()
|
||||||
{
|
{
|
||||||
|
int state = _accountState ? _accountState->state() : AccountState::Disconnected;
|
||||||
if (_accountState) {
|
if (_accountState) {
|
||||||
ui->sslButton->updateAccountState(_accountState);
|
ui->sslButton->updateAccountState(_accountState);
|
||||||
AccountPtr account = _accountState->account();
|
AccountPtr account = _accountState->account();
|
||||||
|
@ -654,6 +656,20 @@ void AccountSettings::slotAccountStateChanged(int state)
|
||||||
showConnectionLabel(tr("Server %1 is currently in maintenance mode.").arg(server));
|
showConnectionLabel(tr("Server %1 is currently in maintenance mode.").arg(server));
|
||||||
} else if (state == AccountState::SignedOut) {
|
} else if (state == AccountState::SignedOut) {
|
||||||
showConnectionLabel(tr("Signed out from %1.").arg(serverWithUser));
|
showConnectionLabel(tr("Signed out from %1.").arg(serverWithUser));
|
||||||
|
} else if (state == AccountState::AskingCredentials) {
|
||||||
|
QUrl url;
|
||||||
|
if (auto cred = qobject_cast<HttpCredentialsGui *>(account->credentials())) {
|
||||||
|
connect(cred, &HttpCredentialsGui::authorisationLinkChanged,
|
||||||
|
this, &AccountSettings::slotAccountStateChanged, Qt::UniqueConnection);
|
||||||
|
url = cred->authorisationLink();
|
||||||
|
}
|
||||||
|
if (url.isValid()) {
|
||||||
|
showConnectionLabel(tr("Obtaining authorization from the browser. "
|
||||||
|
"<a href='%1'>Click here</a> to re-open the browser.")
|
||||||
|
.arg(url.toString(QUrl::FullyEncoded)));
|
||||||
|
} else {
|
||||||
|
showConnectionLabel(tr("Connecting to %1...").arg(serverWithUser));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
showConnectionLabel(tr("No connection to %1 at %2.")
|
showConnectionLabel(tr("No connection to %1 at %2.")
|
||||||
.arg(Utility::escape(Theme::instance()->appNameGUI()), server),
|
.arg(Utility::escape(Theme::instance()->appNameGUI()), server),
|
||||||
|
|
|
@ -65,7 +65,7 @@ signals:
|
||||||
public slots:
|
public slots:
|
||||||
void slotOpenOC();
|
void slotOpenOC();
|
||||||
void slotUpdateQuota(qint64, qint64);
|
void slotUpdateQuota(qint64, qint64);
|
||||||
void slotAccountStateChanged(int state);
|
void slotAccountStateChanged();
|
||||||
|
|
||||||
AccountState *accountsState() { return _accountState; }
|
AccountState *accountsState() { return _accountState; }
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,8 @@ QString AccountState::stateString(State state)
|
||||||
return tr("Network error");
|
return tr("Network error");
|
||||||
case ConfigurationError:
|
case ConfigurationError:
|
||||||
return tr("Configuration error");
|
return tr("Configuration error");
|
||||||
|
case AskingCredentials:
|
||||||
|
return tr("Asking Credentials");
|
||||||
}
|
}
|
||||||
return tr("Unknown account state");
|
return tr("Unknown account state");
|
||||||
}
|
}
|
||||||
|
@ -307,7 +309,7 @@ void AccountState::slotInvalidCredentials()
|
||||||
account()->credentials()->invalidateToken();
|
account()->credentials()->invalidateToken();
|
||||||
account()->credentials()->askFromUser();
|
account()->credentials()->askFromUser();
|
||||||
|
|
||||||
setState(ConfigurationError);
|
setState(AskingCredentials);
|
||||||
_waitingForNewCredentials = true;
|
_waitingForNewCredentials = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,11 @@ public:
|
||||||
/// again automatically.
|
/// again automatically.
|
||||||
NetworkError,
|
NetworkError,
|
||||||
|
|
||||||
/// An error like invalid credentials where retrying won't help.
|
/// Server configuration error. (For example: unsupported version)
|
||||||
ConfigurationError
|
ConfigurationError,
|
||||||
|
|
||||||
|
/// We are currently asking the user for credentials
|
||||||
|
AskingCredentials
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The actual current connectivity status.
|
/// The actual current connectivity status.
|
||||||
|
|
|
@ -308,7 +308,8 @@ void Application::slotCheckConnection()
|
||||||
// Don't check if we're manually signed out or
|
// Don't check if we're manually signed out or
|
||||||
// when the error is permanent.
|
// when the error is permanent.
|
||||||
if (state != AccountState::SignedOut
|
if (state != AccountState::SignedOut
|
||||||
&& state != AccountState::ConfigurationError) {
|
&& state != AccountState::ConfigurationError
|
||||||
|
&& state != AccountState::AskingCredentials) {
|
||||||
accountState->checkConnectivity();
|
accountState->checkConnectivity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,10 @@ void HttpCredentialsGui::askFromUser()
|
||||||
_asyncAuth.reset(new OAuth(_account, this));
|
_asyncAuth.reset(new OAuth(_account, this));
|
||||||
connect(_asyncAuth.data(), &OAuth::result,
|
connect(_asyncAuth.data(), &OAuth::result,
|
||||||
this, &HttpCredentialsGui::asyncAuthResult);
|
this, &HttpCredentialsGui::asyncAuthResult);
|
||||||
|
connect(_asyncAuth.data(), &OAuth::destroyed,
|
||||||
|
this, &HttpCredentialsGui::authorisationLinkChanged);
|
||||||
_asyncAuth->start();
|
_asyncAuth->start();
|
||||||
|
emit authorisationLinkChanged();
|
||||||
} else if (reply->error() == QNetworkReply::AuthenticationRequiredError) {
|
} else if (reply->error() == QNetworkReply::AuthenticationRequiredError) {
|
||||||
// Show the dialog
|
// Show the dialog
|
||||||
// We will re-enter the event loop, so better wait the next iteration
|
// We will re-enter the event loop, so better wait the next iteration
|
||||||
|
|
|
@ -49,12 +49,21 @@ public:
|
||||||
* or call showDialog to ask the password
|
* or call showDialog to ask the password
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void askFromUser() Q_DECL_OVERRIDE;
|
Q_INVOKABLE void askFromUser() Q_DECL_OVERRIDE;
|
||||||
|
/**
|
||||||
|
* In case of oauth, return an URL to the link to open the browser.
|
||||||
|
* An invalid URL otherwise
|
||||||
|
*/
|
||||||
|
QUrl authorisationLink() const { return _asyncAuth ? _asyncAuth->authorisationLink() : QUrl(); }
|
||||||
|
|
||||||
|
|
||||||
static QString requestAppPasswordText(const Account *account);
|
static QString requestAppPasswordText(const Account *account);
|
||||||
private slots:
|
private slots:
|
||||||
void asyncAuthResult(OAuth::Result, const QString &user, const QString &accessToken, const QString &refreshToken);
|
void asyncAuthResult(OAuth::Result, const QString &user, const QString &accessToken, const QString &refreshToken);
|
||||||
void showDialog();
|
void showDialog();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void authorisationLinkChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<OAuth, QScopedPointerObjectDeleteLater<OAuth>> _asyncAuth;
|
QScopedPointer<OAuth, QScopedPointerObjectDeleteLater<OAuth>> _asyncAuth;
|
||||||
};
|
};
|
||||||
|
|
|
@ -131,17 +131,18 @@ void OAuth::start()
|
||||||
QTimer::singleShot(5 * 60 * 1000, this, [this] { result(Error); });
|
QTimer::singleShot(5 * 60 * 1000, this, [this] { result(Error); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QUrl OAuth::authorisationLink() const
|
||||||
bool OAuth::openBrowser()
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(_server.isListening());
|
Q_ASSERT(_server.isListening());
|
||||||
auto url = QUrl(_account->url().toString()
|
return QUrl(_account->url().toString()
|
||||||
+ QLatin1String("/index.php/apps/oauth2/authorize?response_type=code&client_id=")
|
+ QLatin1String("/index.php/apps/oauth2/authorize?response_type=code&client_id=")
|
||||||
+ Theme::instance()->oauthClientId()
|
+ Theme::instance()->oauthClientId()
|
||||||
+ QLatin1String("&redirect_uri=http://localhost:") + QString::number(_server.serverPort()));
|
+ QLatin1String("&redirect_uri=http://localhost:") + QString::number(_server.serverPort()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OAuth::openBrowser()
|
||||||
if (!QDesktopServices::openUrl(url)) {
|
{
|
||||||
|
if (!QDesktopServices::openUrl(authorisationLink())) {
|
||||||
// We cannot open the browser, then we claim we don't support OAuth.
|
// We cannot open the browser, then we claim we don't support OAuth.
|
||||||
emit result(NotSupported, QString());
|
emit result(NotSupported, QString());
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ public:
|
||||||
Q_ENUM(Result);
|
Q_ENUM(Result);
|
||||||
void start();
|
void start();
|
||||||
bool openBrowser();
|
bool openBrowser();
|
||||||
|
QUrl authorisationLink() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue