From: Jocelyn Turcotte Date: Tue, 1 Sep 2015 13:37:58 +0000 (+0200) Subject: Show a notification instead of a login window on startup #3350 X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~1592 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=dcb687929f1323e9fea8a9e4bd48cdd3fa8312d9;p=nextcloud-desktop.git Show a notification instead of a login window on startup #3350 The original problem is that showing a popup not originated from the main settings window while it's focused won't be shown in front to the user. This try not to highjack the user's attention of the user by showing a notification when checking the connection for valid credentials, and require the user to sign in through the UI. There are still issues with showing that popup from the tray icon, but the user will most likely be looking for the popup in that case. The new sign in button directly in the settings account works properly. --- diff --git a/src/gui/accountstate.cpp b/src/gui/accountstate.cpp index 76314128a..70d5d2009 100644 --- a/src/gui/accountstate.cpp +++ b/src/gui/accountstate.cpp @@ -79,7 +79,7 @@ void AccountState::setState(State state) _connectionStatus = ConnectionValidator::Undefined; _connectionErrors.clear(); } else if (oldState == SignedOut && _state == Disconnected) { - checkConnectivity(); + checkConnectivity(AbstractCredentials::Interactive); } } @@ -131,7 +131,7 @@ bool AccountState::isConnectedOrTemporarilyUnavailable() const return isConnected() || _state == ServiceUnavailable; } -void AccountState::checkConnectivity() +void AccountState::checkConnectivity(AbstractCredentials::FetchMode credentialsFetchMode) { if (isSignedOut() || _waitingForNewCredentials) { return; @@ -141,7 +141,7 @@ void AccountState::checkConnectivity() qDebug() << "ConnectionValidator already running, ignoring"; return; } - ConnectionValidator * conValidator = new ConnectionValidator(account()); + ConnectionValidator * conValidator = new ConnectionValidator(account(), credentialsFetchMode); _connectionValidator = conValidator; connect(conValidator, SIGNAL(connectionResult(ConnectionValidator::Status,QStringList)), SLOT(slotConnectionValidatorResult(ConnectionValidator::Status,QStringList))); @@ -243,7 +243,10 @@ void AccountState::slotCredentialsFetched(AbstractCredentials* credentials) delete _connectionValidator; } - checkConnectivity(); + // If we made it this far, it means that we either fetched credentials + // interactively, or that we already aborted for missing/invalid credentials. + Q_ASSERT(credentials->ready()); + checkConnectivity(AbstractCredentials::Interactive); } std::unique_ptr AccountState::settings() diff --git a/src/gui/accountstate.h b/src/gui/accountstate.h index f56364e10..7280334d1 100644 --- a/src/gui/accountstate.h +++ b/src/gui/accountstate.h @@ -84,7 +84,7 @@ public: /// Triggers a ping to the server to update state and /// connection status and errors. - void checkConnectivity(); + void checkConnectivity(AbstractCredentials::FetchMode credentialsFetchMode); /** Returns a new settings object for this account, already in the right groups. */ std::unique_ptr settings(); diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 78102670c..0b2460b1b 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -223,7 +223,7 @@ void Application::slotCheckConnection() // when the error is permanent. if (state != AccountState::SignedOut && state != AccountState::ConfigurationError) { - accountState->checkConnectivity(); + accountState->checkConnectivity(AbstractCredentials::NonInteractive); } } diff --git a/src/gui/creds/shibbolethcredentials.cpp b/src/gui/creds/shibbolethcredentials.cpp index 9a98111ce..c65f71bbb 100644 --- a/src/gui/creds/shibbolethcredentials.cpp +++ b/src/gui/creds/shibbolethcredentials.cpp @@ -28,6 +28,7 @@ #include "accessmanager.h" #include "account.h" +#include "logger.h" #include "theme.h" #include "cookiejar.h" #include "syncengine.h" @@ -94,6 +95,7 @@ ShibbolethCredentials::ShibbolethCredentials(const QNetworkCookie& cookie) : _ready(true), _stillValid(true), _fetchJobInProgress(false), + _interactiveFetch(true), _browser(0), _shibCookie(cookie) { @@ -191,11 +193,12 @@ bool ShibbolethCredentials::ready() const return _ready; } -void ShibbolethCredentials::fetch() +void ShibbolethCredentials::fetch(FetchMode mode) { if(_fetchJobInProgress) { return; } + _interactiveFetch = mode == Interactive; if (_user.isEmpty()) { _user = _account->credentialSetting(QLatin1String(userC)).toString(); @@ -357,8 +360,13 @@ void ShibbolethCredentials::slotReadJobDone(QKeychain::Job *job) _stillValid = true; _fetchJobInProgress = false; Q_EMIT fetched(); - } else { + } else if (_interactiveFetch) { showLoginWindow(); + } else { + Logger::instance()->postOptionalGuiLog(tr("Reauthentication required"), tr("You need to re-login to continue using the account %1.").arg(_account->displayName())); + _ready = false; + _fetchJobInProgress = false; + Q_EMIT fetched(); } } diff --git a/src/gui/creds/shibbolethcredentials.h b/src/gui/creds/shibbolethcredentials.h index a4e2663e7..424803825 100644 --- a/src/gui/creds/shibbolethcredentials.h +++ b/src/gui/creds/shibbolethcredentials.h @@ -55,7 +55,7 @@ public: QString user() const Q_DECL_OVERRIDE; QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE; bool ready() const Q_DECL_OVERRIDE; - void fetch() Q_DECL_OVERRIDE; + void fetch(FetchMode mode = Interactive) Q_DECL_OVERRIDE; bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE; void persist() Q_DECL_OVERRIDE; void invalidateToken() Q_DECL_OVERRIDE; @@ -94,6 +94,7 @@ private: bool _ready; bool _stillValid; bool _fetchJobInProgress; + bool _interactiveFetch; QPointer _browser; QNetworkCookie _shibCookie; QString _user; diff --git a/src/libsync/connectionvalidator.cpp b/src/libsync/connectionvalidator.cpp index 80be8f8d6..bcc285c95 100644 --- a/src/libsync/connectionvalidator.cpp +++ b/src/libsync/connectionvalidator.cpp @@ -23,9 +23,10 @@ namespace OCC { -ConnectionValidator::ConnectionValidator(AccountPtr account, QObject *parent) +ConnectionValidator::ConnectionValidator(AccountPtr account, AbstractCredentials::FetchMode credentialsFetchMode, QObject *parent) : QObject(parent), _account(account), + _credentialsFetchMode(credentialsFetchMode), _isCheckingServerAndAuth(false) { } @@ -128,7 +129,7 @@ void ConnectionValidator::slotStatusFound(const QUrl&url, const QVariantMap &inf // We can't proceed with the auth check because we don't have credentials. // Fetch them now! Once fetched, a new connectivity check will be // initiated anyway. - creds->fetch(); + creds->fetch(_credentialsFetchMode); // no result is reported deleteLater(); diff --git a/src/libsync/connectionvalidator.h b/src/libsync/connectionvalidator.h index a80d56f18..f72383130 100644 --- a/src/libsync/connectionvalidator.h +++ b/src/libsync/connectionvalidator.h @@ -20,6 +20,7 @@ #include #include #include "accountfwd.h" +#include "creds/abstractcredentials.h" namespace OCC { @@ -68,7 +69,7 @@ class OWNCLOUDSYNC_EXPORT ConnectionValidator : public QObject { Q_OBJECT public: - explicit ConnectionValidator(AccountPtr account, QObject *parent = 0); + explicit ConnectionValidator(AccountPtr account, AbstractCredentials::FetchMode credentialsFetchMode, QObject *parent = 0); enum Status { Undefined, @@ -114,6 +115,7 @@ private: QStringList _errors; AccountPtr _account; + AbstractCredentials::FetchMode _credentialsFetchMode; bool _isCheckingServerAndAuth; }; diff --git a/src/libsync/creds/abstractcredentials.h b/src/libsync/creds/abstractcredentials.h index 233813235..658f4f4be 100644 --- a/src/libsync/creds/abstractcredentials.h +++ b/src/libsync/creds/abstractcredentials.h @@ -30,6 +30,7 @@ class OWNCLOUDSYNC_EXPORT AbstractCredentials : public QObject Q_OBJECT public: + enum FetchMode { Interactive, NonInteractive }; AbstractCredentials(); // No need for virtual destructor - QObject already has one. @@ -48,7 +49,7 @@ public: virtual QString user() const = 0; virtual QNetworkAccessManager* getQNAM() const = 0; virtual bool ready() const = 0; - virtual void fetch() = 0; + virtual void fetch(FetchMode mode = Interactive) = 0; virtual bool stillValid(QNetworkReply *reply) = 0; virtual void persist() = 0; /** Invalidates auth token, or password for basic auth */ diff --git a/src/libsync/creds/dummycredentials.cpp b/src/libsync/creds/dummycredentials.cpp index 56257fa4a..3dbfaa0dd 100644 --- a/src/libsync/creds/dummycredentials.cpp +++ b/src/libsync/creds/dummycredentials.cpp @@ -56,7 +56,7 @@ bool DummyCredentials::stillValid(QNetworkReply *reply) return true; } -void DummyCredentials::fetch() +void DummyCredentials::fetch(FetchMode) { Q_EMIT(fetched()); } diff --git a/src/libsync/creds/dummycredentials.h b/src/libsync/creds/dummycredentials.h index 315e696b5..8536d2042 100644 --- a/src/libsync/creds/dummycredentials.h +++ b/src/libsync/creds/dummycredentials.h @@ -35,7 +35,7 @@ public: QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE; bool ready() const Q_DECL_OVERRIDE; bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE; - void fetch() Q_DECL_OVERRIDE; + void fetch(FetchMode mode = Interactive) Q_DECL_OVERRIDE; void persist() Q_DECL_OVERRIDE; void invalidateToken() Q_DECL_OVERRIDE {} }; diff --git a/src/libsync/creds/httpcredentials.cpp b/src/libsync/creds/httpcredentials.cpp index 32c4745e9..8ce1af2da 100644 --- a/src/libsync/creds/httpcredentials.cpp +++ b/src/libsync/creds/httpcredentials.cpp @@ -24,6 +24,7 @@ #include "account.h" #include "accessmanager.h" +#include "logger.h" #include "utility.h" #include "theme.h" #include "syncengine.h" @@ -87,7 +88,8 @@ HttpCredentials::HttpCredentials() _certificatePath(), _certificatePasswd(), _ready(false), - _fetchJobInProgress(false) + _fetchJobInProgress(false), + _interactiveFetch(true) { } @@ -97,7 +99,8 @@ HttpCredentials::HttpCredentials(const QString& user, const QString& password, c _certificatePath(certificatePath), _certificatePasswd(certificatePasswd), _ready(true), - _fetchJobInProgress(false) + _fetchJobInProgress(false), + _interactiveFetch(true) { } @@ -199,11 +202,12 @@ QString HttpCredentials::fetchUser() return _user; } -void HttpCredentials::fetch() +void HttpCredentials::fetch(FetchMode mode) { if (_fetchJobInProgress) { return; } + _interactiveFetch = mode == Interactive; // User must be fetched from config file fetchUser(); @@ -274,8 +278,12 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *job) job->errorString()); } - bool ok; - QString pwd = queryPassword(&ok, hint); + bool ok = false; + QString pwd; + if (_interactiveFetch) + pwd = queryPassword(&ok, hint); + else + Logger::instance()->postOptionalGuiLog(tr("Reauthentication required"), tr("You need to re-login to continue using the account %1.").arg(_account->displayName())); _fetchJobInProgress = false; if (ok) { _password = pwd; diff --git a/src/libsync/creds/httpcredentials.h b/src/libsync/creds/httpcredentials.h index 14674a92c..685502d0e 100644 --- a/src/libsync/creds/httpcredentials.h +++ b/src/libsync/creds/httpcredentials.h @@ -44,7 +44,7 @@ public: QString authType() const Q_DECL_OVERRIDE; QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE; bool ready() const Q_DECL_OVERRIDE; - void fetch() Q_DECL_OVERRIDE; + void fetch(FetchMode mode = Interactive) Q_DECL_OVERRIDE; bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE; void persist() Q_DECL_OVERRIDE; QString user() const Q_DECL_OVERRIDE; @@ -74,6 +74,7 @@ private: QString _certificatePasswd; bool _ready; bool _fetchJobInProgress; //True if the keychain job is in progress or the input dialog visible + bool _interactiveFetch; }; } // namespace OCC diff --git a/src/libsync/creds/tokencredentials.cpp b/src/libsync/creds/tokencredentials.cpp index eee692a8c..5e4896df5 100644 --- a/src/libsync/creds/tokencredentials.cpp +++ b/src/libsync/creds/tokencredentials.cpp @@ -166,7 +166,7 @@ bool TokenCredentials::ready() const return _ready; } -void TokenCredentials::fetch() +void TokenCredentials::fetch(FetchMode) { Q_EMIT fetched(); } diff --git a/src/libsync/creds/tokencredentials.h b/src/libsync/creds/tokencredentials.h index de3fe0e9f..3e5d1dfda 100644 --- a/src/libsync/creds/tokencredentials.h +++ b/src/libsync/creds/tokencredentials.h @@ -46,7 +46,7 @@ public: QString authType() const Q_DECL_OVERRIDE; QNetworkAccessManager* getQNAM() const Q_DECL_OVERRIDE; bool ready() const Q_DECL_OVERRIDE; - void fetch() Q_DECL_OVERRIDE; + void fetch(FetchMode mode = Interactive) Q_DECL_OVERRIDE; bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE; void persist() Q_DECL_OVERRIDE; QString user() const Q_DECL_OVERRIDE;