[Pkg-owncloud-commits] [owncloud-client] 26/33: Shibboleth: Detect also QNAM redirects

Sandro Knauß hefee-guest at moszumanska.debian.org
Thu Feb 27 19:44:25 UTC 2014


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch upstream
in repository owncloud-client.

commit c7e70533a0b332b5ec91c2683928f3ba4b3042e2
Author: Markus Goetz <markus at woboq.com>
Date:   Tue Feb 25 14:22:01 2014 +0100

    Shibboleth: Detect also QNAM redirects
    
    If a QNAM job (e.g. Quota or ETag job) gets redirected,
    we'll invalidate and then prompt to re-fetch the credentials
    from the user.
    (The keychain credentials will be wrong so they get deleted)
---
 src/creds/abstractcredentials.h                  |  4 ++
 src/creds/shibboleth/shibbolethaccessmanager.cpp |  3 +-
 src/creds/shibbolethcredentials.cpp              | 54 +++++++++++++++++++-----
 src/creds/shibbolethcredentials.h                |  4 ++
 src/mirall/networkjobs.cpp                       |  7 ++-
 5 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/src/creds/abstractcredentials.h b/src/creds/abstractcredentials.h
index 81ef261..3fb8461 100644
--- a/src/creds/abstractcredentials.h
+++ b/src/creds/abstractcredentials.h
@@ -42,6 +42,10 @@ public:
     virtual void persist(Account *account) = 0;
     /** Invalidates auth token, or password for basic auth */
     virtual void invalidateToken(Account *account) = 0;
+    virtual void invalidateAndFetch(Account *account) {
+        invalidateToken(account);
+        fetch(account);
+    }
 
 
     static QString keychainKey(const QString &url, const QString &user);
diff --git a/src/creds/shibboleth/shibbolethaccessmanager.cpp b/src/creds/shibboleth/shibbolethaccessmanager.cpp
index cbef802..451115c 100644
--- a/src/creds/shibboleth/shibbolethaccessmanager.cpp
+++ b/src/creds/shibboleth/shibbolethaccessmanager.cpp
@@ -31,14 +31,13 @@ QNetworkReply* ShibbolethAccessManager::createRequest(QNetworkAccessManager::Ope
         QNetworkCookieJar* jar(cookieJar());
         QUrl url(request.url());
         QList<QNetworkCookie> cookies;
-
         Q_FOREACH(const QNetworkCookie& cookie, jar->cookiesForUrl(url)) {
             if (!cookie.name().startsWith("_shibsession_")) {
                 cookies << cookie;
             }
         }
 
-        cookies << _cookie;
+        cookies << _cookie; // this line and the line above replace all cookies with self and then add the shibboleth cookie (filtering the current shib cookie)
         jar->setCookiesFromUrl(cookies, url);
     }
 
diff --git a/src/creds/shibbolethcredentials.cpp b/src/creds/shibbolethcredentials.cpp
index 7b7019a..443528a 100644
--- a/src/creds/shibbolethcredentials.cpp
+++ b/src/creds/shibbolethcredentials.cpp
@@ -14,6 +14,7 @@
 
 #include <QMutex>
 #include <QSettings>
+#include <QNetworkReply>
 
 #include "creds/shibbolethcredentials.h"
 #include "creds/shibboleth/shibbolethaccessmanager.h"
@@ -76,6 +77,7 @@ ShibbolethCredentials::ShibbolethCredentials()
       _url(),
       _shibCookie(),
       _ready(false),
+      _stillValid(false),
       _browser(0),
       _otherCookies()
 {}
@@ -172,9 +174,22 @@ QNetworkAccessManager* ShibbolethCredentials::getQNAM() const
 
     connect(this, SIGNAL(newCookie(QNetworkCookie)),
             qnam, SLOT(setCookie(QNetworkCookie)));
+    connect(qnam, SIGNAL(finished(QNetworkReply*)),
+            this, SLOT(slotReplyFinished(QNetworkReply*)));
     return qnam;
 }
 
+void ShibbolethCredentials::slotReplyFinished(QNetworkReply* r)
+{
+    QVariant target = r->attribute(QNetworkRequest::RedirectionTargetAttribute);
+    if (target.isValid()) {
+        _stillValid = false;
+        qWarning() << Q_FUNC_INFO << "detected redirect, will open Login Window"; // will be done in NetworkJob's finished signal
+    } else {
+        //_stillValid = true; // gets set when reading from keychain or getting it from browser
+    }
+}
+
 bool ShibbolethCredentials::ready() const
 {
     return _ready;
@@ -201,7 +216,7 @@ void ShibbolethCredentials::fetch(Account *account)
 bool ShibbolethCredentials::stillValid(QNetworkReply *reply)
 {
     Q_UNUSED(reply)
-    return true;
+    return _stillValid;
 }
 
 void ShibbolethCredentials::persist(Account* account)
@@ -213,17 +228,20 @@ void ShibbolethCredentials::persist(Account* account)
     storeShibCookie(_shibCookie, account);
 }
 
+// only used by Application::slotLogout(). Use invalidateAndFetch for normal usage
 void ShibbolethCredentials::invalidateToken(Account *account)
 {
     Q_UNUSED(account)
     _shibCookie = QNetworkCookie();
-    storeShibCookie(_shibCookie, account);
+    storeShibCookie(_shibCookie, account); // store/erase cookie
+
     // ### access to ctx missing, but might not be required at all
     //csync_set_module_property(ctx, "session_key", "");
 }
 
 void ShibbolethCredentials::disposeBrowser()
 {
+    qDebug() << Q_FUNC_INFO;
     disconnect(_browser, SIGNAL(viewHidden()),
                this, SLOT(slotBrowserHidden()));
     disconnect(_browser, SIGNAL(shibbolethCookieReceived(QNetworkCookie, Account*)),
@@ -237,6 +255,7 @@ void ShibbolethCredentials::onShibbolethCookieReceived(const QNetworkCookie& coo
 {
     disposeBrowser();
     _ready = true;
+    _stillValid = true;
     _shibCookie = cookie;
     storeShibCookie(_shibCookie, account);
     Q_EMIT newCookie(_shibCookie);
@@ -290,6 +309,7 @@ void ShibbolethCredentials::slotReadJobDone(QKeychain::Job *job)
     if (job->error() == QKeychain::NoError) {
         ReadPasswordJob *readJob = static_cast<ReadPasswordJob*>(job);
         delete readJob->settings();
+        qDebug() << Q_FUNC_INFO;
         QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(readJob->textData().toUtf8());
         if (cookies.count() > 0) {
             _shibCookie = cookies.first();
@@ -297,18 +317,32 @@ void ShibbolethCredentials::slotReadJobDone(QKeychain::Job *job)
         job->setSettings(account->settingsWithGroup(Theme::instance()->appName()));
 
         _ready = true;
+        _stillValid = true;
         Q_EMIT newCookie(_shibCookie);
         Q_EMIT fetched();
     } else {
-        ShibbolethConfigFile cfg;
-        _browser = new ShibbolethWebView(account, cfg.createCookieJar());
-        connect(_browser, SIGNAL(shibbolethCookieReceived(QNetworkCookie, Account*)),
-                this, SLOT(onShibbolethCookieReceived(QNetworkCookie, Account*)));
-        connect(_browser, SIGNAL(viewHidden()),
-                this, SLOT(slotBrowserHidden()));
-
-        _browser->show();
+        showLoginWindow(account);
+    }
+}
+
+void ShibbolethCredentials::showLoginWindow(Account* account)
+{
+    if (_browser) {
+        _browser->activateWindow();
+        _browser->raise();
+        // FIXME On OS X this does not raise properly
+        return;
     }
+    ShibbolethConfigFile cfg;
+    _browser = new ShibbolethWebView(account, cfg.createCookieJar());
+    connect(_browser, SIGNAL(shibbolethCookieReceived(QNetworkCookie, Account*)),
+            this, SLOT(onShibbolethCookieReceived(QNetworkCookie, Account*)));
+    connect(_browser, SIGNAL(viewHidden()),
+            this, SLOT(slotBrowserHidden()));
+    // FIXME If the browser was hidden (e.g. user closed it) without us logging in, the logic gets stuck
+    // and can only be unstuck by restarting the app or pressing "Sign in" (we should switch to offline but we don't)
+
+    _browser->show();
 }
 
 void ShibbolethCredentials::storeShibCookie(const QNetworkCookie &cookie, Account *account)
diff --git a/src/creds/shibbolethcredentials.h b/src/creds/shibbolethcredentials.h
index b3f922f..483b141 100644
--- a/src/creds/shibbolethcredentials.h
+++ b/src/creds/shibbolethcredentials.h
@@ -52,6 +52,8 @@ public:
 
     QNetworkCookie cookie() const;
 
+    void showLoginWindow(Account*);
+
 public Q_SLOTS:
     void invalidateAndFetch(Account *account);
 
@@ -61,6 +63,7 @@ private Q_SLOTS:
     void onFetched();
     void slotReadJobDone(QKeychain::Job*);
     void slotInvalidateAndFetchInvalidateDone(QKeychain::Job*);
+    void slotReplyFinished(QNetworkReply*);
 
 Q_SIGNALS:
     void newCookie(const QNetworkCookie& cookie);
@@ -74,6 +77,7 @@ private:
 
     QNetworkCookie _shibCookie;
     bool _ready;
+    bool _stillValid;
     ShibbolethWebView* _browser;
     QMap<QUrl, QList<QNetworkCookie> > _otherCookies;
 };
diff --git a/src/mirall/networkjobs.cpp b/src/mirall/networkjobs.cpp
index 7544291..9230da8 100644
--- a/src/mirall/networkjobs.cpp
+++ b/src/mirall/networkjobs.cpp
@@ -34,6 +34,7 @@
 
 #include "creds/credentialsfactory.h"
 #include "creds/abstractcredentials.h"
+#include "creds/shibbolethcredentials.h"
 
 Q_DECLARE_METATYPE(QTimer*)
 
@@ -144,15 +145,13 @@ void AbstractNetworkJob::slotFinished()
     AbstractCredentials *creds = _account->credentials();
     if (!creds->stillValid(_reply) &&! _ignoreCredentialFailure
             && _account->state() != Account::InvalidCredidential) {
-        // invalidate & forget token/password
-        _account->credentials()->invalidateToken(_account);
-
         _account->setState(Account::InvalidCredidential);
 
+        // invalidate & forget token/password
         // but try to re-sign in.
         connect( creds, SIGNAL(fetched()),
                  qApp, SLOT(slotCredentialsFetched()), Qt::UniqueConnection);
-        creds->fetch(_account);   // this triggers Application::runValidator when the credidentials are fetched
+        creds->invalidateAndFetch(_account);   // this triggers Application::runValidator when the credidentials are fetched
     }
     deleteLater();
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list