Show a notification instead of a login window on startup #3350
authorJocelyn Turcotte <jturcotte@woboq.com>
Tue, 1 Sep 2015 13:37:58 +0000 (15:37 +0200)
committerJocelyn Turcotte <jturcotte@woboq.com>
Tue, 1 Sep 2015 16:40:20 +0000 (18:40 +0200)
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.

14 files changed:
src/gui/accountstate.cpp
src/gui/accountstate.h
src/gui/application.cpp
src/gui/creds/shibbolethcredentials.cpp
src/gui/creds/shibbolethcredentials.h
src/libsync/connectionvalidator.cpp
src/libsync/connectionvalidator.h
src/libsync/creds/abstractcredentials.h
src/libsync/creds/dummycredentials.cpp
src/libsync/creds/dummycredentials.h
src/libsync/creds/httpcredentials.cpp
src/libsync/creds/httpcredentials.h
src/libsync/creds/tokencredentials.cpp
src/libsync/creds/tokencredentials.h

index 76314128a21a8ac7d7a70b92000e8102e032e5d3..70d5d20099c0b54493efa0e3a647e5ce98f1c89c 100644 (file)
@@ -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<QSettings> AccountState::settings()
index f56364e104f87723d4947e77a67049fcc6f3aaac..7280334d12bb5006efe6a17ac86d766a9c84a70b 100644 (file)
@@ -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<QSettings> settings();
index 78102670c93425ad2b49d59270afec42064e2cc5..0b2460b1b3a249ee57b7bbace2ec2a8a92996781 100644 (file)
@@ -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);
         }
     }
 
index 9a98111cecacfcfd74324864ab07b0f8f850f4c2..c65f71bbbbb193e7da3b4ef9d792b263fafe23b9 100644 (file)
@@ -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();
     }
 }
 
index a4e2663e7085b7163b11fdfec308fa9c5497bacd..424803825598231e8034ba5ddc3c4d40adeef9cf 100644 (file)
@@ -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<ShibbolethWebView> _browser;
     QNetworkCookie _shibCookie;
     QString _user;
index 80be8f8d6f8684c8ea9ac91585ab910d27371bf6..bcc285c952a6e9dc766a80e838206163d3782103 100644 (file)
 
 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();
index a80d56f187fc754b47d14bbdac00641cef556bb1..f723831307f1fba34593eaf34ef6f27f855e2ded 100644 (file)
@@ -20,6 +20,7 @@
 #include <QVariantMap>
 #include <QNetworkReply>
 #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;
 };
 
index 2338132359db96fa4be313340cbeef6e958c09cc..658f4f4bed2bd0b3e8662d240d4c43f35a8919da 100644 (file)
@@ -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 */
index 56257fa4af66c900f8d49d138383c878136b8361..3dbfaa0dde9605469f6e191eb6ae817d33c42f1f 100644 (file)
@@ -56,7 +56,7 @@ bool DummyCredentials::stillValid(QNetworkReply *reply)
     return true;
 }
 
-void DummyCredentials::fetch()
+void DummyCredentials::fetch(FetchMode)
 {
     Q_EMIT(fetched());
 }
index 315e696b53731dfa752b5597279511d5986b6cc4..8536d20427c7702027c5b2e94b2fbbaab8435c24 100644 (file)
@@ -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 {}
 };
index 32c4745e9496dfbf1babc413286d4827c58f9e69..8ce1af2daeae14e0e0856c43769420360ab6ca0b 100644 (file)
@@ -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;
index 14674a92ccf7071ec03806041ad900d3560e06b8..685502d0e7db1f91da12e9c2ccf90329dc962f42 100644 (file)
@@ -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
index eee692a8cc7e620c86967bbcf69d66063b55c7f1..5e4896df5eba46a270762359895e4541e3ef3ad2 100644 (file)
@@ -166,7 +166,7 @@ bool TokenCredentials::ready() const
     return _ready;
 }
 
-void TokenCredentials::fetch()
+void TokenCredentials::fetch(FetchMode)
 {
     Q_EMIT fetched();
 }
index de3fe0e9f818f16ffe844180bbf72b37c33f6f3f..3e5d1dfda9e7ceb6abb1ce938ee06c19a437b529 100644 (file)
@@ -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;