mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-29 12:19:03 +03:00
CookieJar refactoring required to overcome issues in Shibboleth support
The shibboleth implementation no longer maintains its own QNAM. Instead, MirallAccessManager now holds a custom QNAM implementation which saves cookies to a file on disk. This patch also reduces some complexity wrt the browser window, which used to be deleted via a roundtrip to its callee, which is not longer required. Fixes #1764 and Enterprise bug #165 Going forward, AbstractCredentials::getQNAM() could maybe removed entirely.
This commit is contained in:
parent
e62eb62a01
commit
ba959f7cf9
19 changed files with 336 additions and 518 deletions
|
@ -104,6 +104,7 @@ set(libsync_SRCS
|
|||
mirall/quotainfo.cpp
|
||||
mirall/clientproxy.cpp
|
||||
mirall/syncrunfilelog.cpp
|
||||
mirall/cookiejar.cpp
|
||||
creds/dummycredentials.cpp
|
||||
creds/abstractcredentials.cpp
|
||||
creds/credentialsfactory.cpp
|
||||
|
@ -121,11 +122,8 @@ else()
|
|||
${libsync_SRCS}
|
||||
creds/httpcredentials.cpp
|
||||
creds/shibbolethcredentials.cpp
|
||||
creds/shibboleth/shibbolethaccessmanager.cpp
|
||||
creds/shibboleth/shibbolethcookiejar.cpp
|
||||
creds/shibboleth/shibbolethwebview.cpp
|
||||
creds/shibboleth/shibbolethrefresher.cpp
|
||||
creds/shibboleth/shibbolethconfigfile.cpp
|
||||
creds/shibboleth/authenticationdialog.cpp
|
||||
creds/shibboleth/shibbolethuserjob.cpp
|
||||
)
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkCookieJar>
|
||||
|
||||
#include "creds/shibboleth/shibbolethaccessmanager.h"
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
ShibbolethAccessManager::ShibbolethAccessManager(const QNetworkCookie& cookie, QObject* parent)
|
||||
: MirallAccessManager (parent),
|
||||
_cookie(cookie)
|
||||
{}
|
||||
|
||||
QNetworkReply* ShibbolethAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest& request, QIODevice* outgoingData)
|
||||
{
|
||||
if (!_cookie.name().isEmpty()) {
|
||||
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; // 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);
|
||||
}
|
||||
|
||||
qDebug() << "Creating a request to " << request.url().toString() << " with shibboleth cookie:" << _cookie.name();
|
||||
|
||||
return MirallAccessManager::createRequest (op, request, outgoingData);
|
||||
}
|
||||
|
||||
void ShibbolethAccessManager::setCookie(const QNetworkCookie& cookie)
|
||||
{
|
||||
qDebug() << "Got new shibboleth cookie:" << cookie.name();
|
||||
_cookie = cookie;
|
||||
}
|
||||
|
||||
} // ns Mirall
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef MIRALL_WIZARD_SHIBBOLETH_ACCESS_MANAGER_H
|
||||
#define MIRALL_WIZARD_SHIBBOLETH_ACCESS_MANAGER_H
|
||||
|
||||
#include <QNetworkCookie>
|
||||
|
||||
#include "mirall/mirallaccessmanager.h"
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
class ShibbolethAccessManager : public MirallAccessManager
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ShibbolethAccessManager(const QNetworkCookie& cookie, QObject* parent = 0);
|
||||
|
||||
public Q_SLOTS:
|
||||
void setCookie(const QNetworkCookie& cookie);
|
||||
|
||||
protected:
|
||||
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest& request, QIODevice* outgoingData = 0);
|
||||
|
||||
private:
|
||||
QNetworkCookie _cookie;
|
||||
};
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
#endif
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "creds/shibboleth/shibbolethconfigfile.h"
|
||||
#include "creds/shibboleth/shibbolethcookiejar.h"
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const char otherCookiesC[] = "otherCookies";
|
||||
|
||||
} // ns
|
||||
|
||||
void ShibbolethConfigFile::storeCookies(const QMap<QUrl, QList<QNetworkCookie> >& cookiesForUrl)
|
||||
{
|
||||
if (cookiesForUrl.isEmpty()) {
|
||||
removeData(QString(), QString::fromLatin1(otherCookiesC));
|
||||
} else {
|
||||
QByteArray data;
|
||||
QTextStream stream(&data);
|
||||
|
||||
Q_FOREACH (const QUrl& url, cookiesForUrl.keys()) {
|
||||
const QList<QNetworkCookie>& cookies(cookiesForUrl[url]);
|
||||
|
||||
if (cookies.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
stream << "URL: " << url.toString().toUtf8() << "\n";
|
||||
qDebug() << "URL: " << url.toString().toUtf8();
|
||||
|
||||
Q_FOREACH (const QNetworkCookie& cookie, cookies) {
|
||||
stream << cookie.toRawForm(QNetworkCookie::NameAndValueOnly) << "\n";
|
||||
qDebug() << cookie.toRawForm(QNetworkCookie::NameAndValueOnly);
|
||||
}
|
||||
}
|
||||
|
||||
stream.flush();
|
||||
|
||||
const QByteArray encodedCookies(data.toBase64());
|
||||
|
||||
qDebug() << "Raw cookies:\n" << data;
|
||||
qDebug() << "Encoded cookies: " << encodedCookies;
|
||||
|
||||
storeData(QString(), QString::fromLatin1(otherCookiesC), QVariant(encodedCookies));
|
||||
}
|
||||
}
|
||||
|
||||
ShibbolethCookieJar* ShibbolethConfigFile::createCookieJar() const
|
||||
{
|
||||
ShibbolethCookieJar* jar = new ShibbolethCookieJar();
|
||||
const QVariant variant(retrieveData(QString(), QString::fromLatin1(otherCookiesC)));
|
||||
|
||||
if (variant.isValid()) {
|
||||
QByteArray data(QByteArray::fromBase64(variant.toByteArray()));
|
||||
QTextStream stream (&data);
|
||||
const QString urlHeader(QString::fromLatin1("URL: "));
|
||||
QUrl currentUrl;
|
||||
QList<QNetworkCookie> currentCookies;
|
||||
|
||||
qDebug() << "Got valid cookies variant: " << data;
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
const QString line(stream.readLine());
|
||||
|
||||
qDebug() << line;
|
||||
|
||||
if (line.startsWith(urlHeader)) {
|
||||
if (!currentUrl.isEmpty() && !currentCookies.isEmpty()) {
|
||||
jar->setCookiesFromUrl(currentCookies, currentUrl);
|
||||
currentCookies.clear();
|
||||
currentUrl.clear();
|
||||
}
|
||||
currentUrl = QUrl(line.mid(5));
|
||||
} else if (!currentUrl.isEmpty()) {
|
||||
const int equalPos(line.indexOf('='));
|
||||
|
||||
currentCookies << QNetworkCookie(line.left(equalPos).toUtf8(), line.mid(equalPos + 1).toUtf8());
|
||||
}
|
||||
}
|
||||
if (!currentUrl.isEmpty() && !currentCookies.isEmpty()) {
|
||||
jar->setCookiesFromUrl(currentCookies, currentUrl);
|
||||
}
|
||||
}
|
||||
|
||||
return jar;
|
||||
}
|
||||
|
||||
} // ns Mirall
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef MIRALL_CREDS_SHIBBOLETH_CONFIG_FILE_H
|
||||
#define MIRALL_CREDS_SHIBBOLETH_CONFIG_FILE_H
|
||||
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QNetworkCookie>
|
||||
#include <QUrl>
|
||||
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
class ShibbolethCookieJar;
|
||||
|
||||
class ShibbolethConfigFile : public MirallConfigFile
|
||||
{
|
||||
public:
|
||||
void storeCookies(const QMap<QUrl, QList<QNetworkCookie> >& cookies);
|
||||
ShibbolethCookieJar* createCookieJar() const;
|
||||
};
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
#endif
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "creds/shibboleth/shibbolethcookiejar.h"
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
ShibbolethCookieJar::ShibbolethCookieJar (QObject* parent)
|
||||
: QNetworkCookieJar (parent)
|
||||
{}
|
||||
|
||||
bool ShibbolethCookieJar::setCookiesFromUrl (const QList<QNetworkCookie>& cookieList, const QUrl& url)
|
||||
{
|
||||
if (QNetworkCookieJar::setCookiesFromUrl (cookieList, url)) {
|
||||
Q_EMIT newCookiesForUrl (cookieList, url);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // ns Mirall
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef MIRALL_WIZARD_SHIBBOLETH_COOKIE_JAR_H
|
||||
#define MIRALL_WIZARD_SHIBBOLETH_COOKIE_JAR_H
|
||||
|
||||
#include <QNetworkCookieJar>
|
||||
#include <QList>
|
||||
|
||||
class QUrl;
|
||||
class QNetworkCookie;
|
||||
|
||||
namespace Mirall
|
||||
{
|
||||
|
||||
class ShibbolethCookieJar : public QNetworkCookieJar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ShibbolethCookieJar (QObject* parent = 0);
|
||||
|
||||
virtual bool setCookiesFromUrl (const QList<QNetworkCookie>& cookieList, const QUrl& url);
|
||||
|
||||
Q_SIGNALS:
|
||||
void newCookiesForUrl (const QList<QNetworkCookie>& cookieList, const QUrl& url);
|
||||
};
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
#endif
|
|
@ -20,9 +20,9 @@
|
|||
#include <QAuthenticator>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include "creds/shibboleth/shibbolethcookiejar.h"
|
||||
#include "creds/shibboleth/shibbolethwebview.h"
|
||||
#include "creds/shibboleth/authenticationdialog.h"
|
||||
#include "creds/shibboleth/shibbolethwebview.h"
|
||||
#include "creds/shibbolethcredentials.h"
|
||||
#include "mirall/account.h"
|
||||
#include "mirall/mirallaccessmanager.h"
|
||||
#include "mirall/theme.h"
|
||||
|
@ -30,80 +30,50 @@
|
|||
namespace Mirall
|
||||
{
|
||||
|
||||
void ShibbolethWebView::setup(Account *account, ShibbolethCookieJar* jar)
|
||||
ShibbolethWebView::ShibbolethWebView(Account* account, QWidget* parent)
|
||||
: QWebView(parent)
|
||||
, _account(account)
|
||||
{
|
||||
_account = account;
|
||||
MirallAccessManager* nm = new MirallAccessManager(this);
|
||||
// we need our own QNAM, but the we offload the SSL error handling to
|
||||
// the account object, which already can do this
|
||||
connect(nm, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
account, SLOT(slotHandleErrors(QNetworkReply*,QList<QSslError>)));
|
||||
connect(nm, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
|
||||
SLOT(slotHandleAuthentication(QNetworkReply*,QAuthenticator*)));
|
||||
|
||||
// no minimize
|
||||
setWindowFlags(Qt::Dialog);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
QWebPage* page = new QWebPage(this);
|
||||
|
||||
jar->setParent(this);
|
||||
connect(jar, SIGNAL (newCookiesForUrl (QList<QNetworkCookie>, QUrl)),
|
||||
this, SLOT (onNewCookiesForUrl (QList<QNetworkCookie>, QUrl)));
|
||||
page->setNetworkAccessManager(account->networkAccessManager());
|
||||
connect(page, SIGNAL(loadStarted()),
|
||||
this, SLOT(slotLoadStarted()));
|
||||
connect(page, SIGNAL(loadFinished(bool)),
|
||||
this, SLOT(slotLoadFinished(bool)));
|
||||
|
||||
nm->setCookieJar(jar);
|
||||
page->setNetworkAccessManager(nm);
|
||||
|
||||
connect(page->networkAccessManager()->cookieJar(),
|
||||
SIGNAL(newCookiesForUrl (QList<QNetworkCookie>, QUrl)),
|
||||
this, SLOT(onNewCookiesForUrl (QList<QNetworkCookie>, QUrl)));
|
||||
page->mainFrame()->load(account->url());
|
||||
this->setPage(page);
|
||||
setWindowTitle(tr("%1 - Authenticate").arg(Theme::instance()->appNameGUI()));
|
||||
}
|
||||
|
||||
ShibbolethWebView::ShibbolethWebView(Account* account, QWidget* parent)
|
||||
: QWebView(parent)
|
||||
{
|
||||
setup(account, new ShibbolethCookieJar(this));
|
||||
}
|
||||
|
||||
ShibbolethWebView::~ShibbolethWebView()
|
||||
{
|
||||
slotLoadFinished();
|
||||
}
|
||||
|
||||
ShibbolethWebView::ShibbolethWebView(Account* account, ShibbolethCookieJar* jar, QWidget* parent)
|
||||
: QWebView(parent)
|
||||
{
|
||||
setup(account, jar);
|
||||
}
|
||||
|
||||
void ShibbolethWebView::onNewCookiesForUrl (const QList<QNetworkCookie>& cookieList, const QUrl& url)
|
||||
{
|
||||
QList<QNetworkCookie> otherCookies;
|
||||
QNetworkCookie shibCookie;
|
||||
|
||||
Q_FOREACH (const QNetworkCookie& cookie, cookieList) {
|
||||
if (cookie.name().startsWith ("_shibsession_")) {
|
||||
if (shibCookie.name().isEmpty()) {
|
||||
shibCookie = cookie;
|
||||
} else {
|
||||
qWarning() << "Too many Shibboleth session cookies at once!";
|
||||
}
|
||||
} else {
|
||||
otherCookies << cookie;
|
||||
qDebug() << "Received cookies for URL" << url << ":" << cookieList << ". Account object has URL" << _account->url();
|
||||
if (url.host() == _account->url().host()) {
|
||||
QNetworkCookie shibCookie = ShibbolethCredentials::findShibCookie(_account, cookieList);
|
||||
if (shibCookie != QNetworkCookie()) {
|
||||
Q_EMIT shibbolethCookieReceived(shibCookie, _account);
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!otherCookies.isEmpty()) {
|
||||
Q_EMIT otherCookiesReceived(otherCookies, url);
|
||||
}
|
||||
if (!shibCookie.name().isEmpty()) {
|
||||
Q_EMIT shibbolethCookieReceived(shibCookie, _account);
|
||||
}
|
||||
}
|
||||
|
||||
void ShibbolethWebView::hideEvent(QHideEvent* event)
|
||||
void ShibbolethWebView::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
Q_EMIT viewHidden();
|
||||
QWebView::hideEvent(event);
|
||||
QWebView::closeEvent(event);
|
||||
}
|
||||
|
||||
void ShibbolethWebView::slotLoadStarted()
|
||||
|
|
|
@ -37,13 +37,11 @@ public:
|
|||
ShibbolethWebView(Account *account, ShibbolethCookieJar* jar, QWidget* parent = 0);
|
||||
~ShibbolethWebView();
|
||||
|
||||
protected:
|
||||
void hideEvent(QHideEvent* event);
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
Q_SIGNALS:
|
||||
void shibbolethCookieReceived(const QNetworkCookie& cookie, Account* account);
|
||||
void shibbolethCookieReceived(const QNetworkCookie &cookie, Account *account);
|
||||
void viewHidden();
|
||||
void otherCookiesReceived(const QList<QNetworkCookie>& cookieList, const QUrl& url);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onNewCookiesForUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url);
|
||||
|
|
|
@ -16,18 +16,19 @@
|
|||
#include <QSettings>
|
||||
#include <QNetworkReply>
|
||||
#include <QMessageBox>
|
||||
#include <qdebug.h>
|
||||
#include <QDebug>
|
||||
|
||||
#include "creds/shibbolethcredentials.h"
|
||||
#include "creds/shibboleth/shibbolethaccessmanager.h"
|
||||
#include "creds/shibboleth/shibbolethwebview.h"
|
||||
#include "creds/shibboleth/shibbolethrefresher.h"
|
||||
#include "creds/shibboleth/shibbolethconfigfile.h"
|
||||
#include "creds/shibbolethcredentials.h"
|
||||
#include "shibboleth/shibbolethuserjob.h"
|
||||
#include "creds/credentialscommon.h"
|
||||
|
||||
#include "mirall/mirallaccessmanager.h"
|
||||
#include "mirall/account.h"
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/cookiejar.h"
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
#include <qt5keychain/keychain.h>
|
||||
|
@ -45,6 +46,7 @@ namespace
|
|||
|
||||
// Not "user" because it has a special meaning for http
|
||||
const char userC[] = "shib_user";
|
||||
const char shibCookieNameC[] = "_shibsession_";
|
||||
|
||||
int shibboleth_redirect_callback(CSYNC* csync_ctx,
|
||||
const char* uri)
|
||||
|
@ -66,7 +68,6 @@ int shibboleth_redirect_callback(CSYNC* csync_ctx,
|
|||
Account *account = AccountManager::instance()->account();
|
||||
ShibbolethCredentials* creds = qobject_cast<ShibbolethCredentials*>(account->credentials());
|
||||
|
||||
|
||||
if (!creds) {
|
||||
qDebug() << "Not a Shibboleth creds instance!";
|
||||
return 1;
|
||||
|
@ -85,18 +86,9 @@ int shibboleth_redirect_callback(CSYNC* csync_ctx,
|
|||
ShibbolethCredentials::ShibbolethCredentials()
|
||||
: AbstractCredentials(),
|
||||
_url(),
|
||||
_shibCookie(),
|
||||
_ready(false),
|
||||
_stillValid(false),
|
||||
_browser(0),
|
||||
_otherCookies()
|
||||
{}
|
||||
|
||||
ShibbolethCredentials::ShibbolethCredentials(const QNetworkCookie& cookie, const QMap<QUrl, QList<QNetworkCookie> >& otherCookies)
|
||||
: _shibCookie(cookie),
|
||||
_ready(true),
|
||||
_browser(0),
|
||||
_otherCookies(otherCookies)
|
||||
_browser(0)
|
||||
{}
|
||||
|
||||
void ShibbolethCredentials::syncContextPreInit(CSYNC* ctx)
|
||||
|
@ -111,29 +103,11 @@ QByteArray ShibbolethCredentials::prepareCookieData() const
|
|||
// have any way to get "session_key" module property from
|
||||
// csync. Had we have it, then we could just append shibboleth
|
||||
// cookies to the "session_key" value and set it in csync module.
|
||||
QList<QNetworkCookie> cookies(AccountManager::instance()->account()->lastAuthCookies());
|
||||
QMap<QString, QString> uniqueCookies;
|
||||
Account *account = AccountManager::instance()->account();
|
||||
QList<QNetworkCookie> cookies = accountCookies(account);
|
||||
|
||||
cookies << _shibCookie;
|
||||
// Stuff cookies inside csync, then we can avoid the intermediate HTTP 401 reply
|
||||
// when https://github.com/owncloud/core/pull/4042 is merged.
|
||||
foreach(QNetworkCookie c, cookies) {
|
||||
const QString cookieName(c.name());
|
||||
|
||||
if (cookieName.startsWith("_shibsession_")) {
|
||||
continue;
|
||||
}
|
||||
uniqueCookies.insert(cookieName, c.value());
|
||||
}
|
||||
|
||||
if (!_shibCookie.name().isEmpty()) {
|
||||
uniqueCookies.insert(_shibCookie.name(), _shibCookie.value());
|
||||
}
|
||||
foreach(const QString& cookieName, uniqueCookies.keys()) {
|
||||
cookiesAsString += cookieName;
|
||||
cookiesAsString += '=';
|
||||
cookiesAsString += uniqueCookies[cookieName];
|
||||
cookiesAsString += "; ";
|
||||
foreach(const QNetworkCookie &cookie, cookies) {
|
||||
cookiesAsString += cookie.toRawForm(QNetworkCookie::NameAndValueOnly) + QLatin1String("; ");
|
||||
}
|
||||
|
||||
return cookiesAsString.toLatin1();
|
||||
|
@ -153,7 +127,7 @@ bool ShibbolethCredentials::changed(AbstractCredentials* credentials) const
|
|||
{
|
||||
ShibbolethCredentials* other(dynamic_cast< ShibbolethCredentials* >(credentials));
|
||||
|
||||
if (!other || other->cookie() != this->cookie()) {
|
||||
if (_shibCookie != other->_shibCookie || _user != other->_user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -170,17 +144,9 @@ QString ShibbolethCredentials::user() const
|
|||
return _user;
|
||||
}
|
||||
|
||||
QNetworkCookie ShibbolethCredentials::cookie() const
|
||||
{
|
||||
return _shibCookie;
|
||||
}
|
||||
|
||||
QNetworkAccessManager* ShibbolethCredentials::getQNAM() const
|
||||
{
|
||||
ShibbolethAccessManager* qnam(new ShibbolethAccessManager(_shibCookie));
|
||||
|
||||
connect(this, SIGNAL(newCookie(QNetworkCookie)),
|
||||
qnam, SLOT(setCookie(QNetworkCookie)));
|
||||
QNetworkAccessManager* qnam(new MirallAccessManager);
|
||||
connect(qnam, SIGNAL(finished(QNetworkReply*)),
|
||||
this, SLOT(slotReplyFinished(QNetworkReply*)));
|
||||
return qnam;
|
||||
|
@ -231,44 +197,30 @@ bool ShibbolethCredentials::stillValid(QNetworkReply *reply)
|
|||
|
||||
void ShibbolethCredentials::persist(Account* account)
|
||||
{
|
||||
ShibbolethConfigFile cfg;
|
||||
|
||||
cfg.storeCookies(_otherCookies);
|
||||
|
||||
storeShibCookie(_shibCookie, account);
|
||||
if (!_user.isEmpty())
|
||||
if (!_user.isEmpty()) {
|
||||
account->setCredentialSetting(QLatin1String(userC), _user);
|
||||
}
|
||||
}
|
||||
|
||||
// only used by Application::slotLogout(). Use invalidateAndFetch for normal usage
|
||||
void ShibbolethCredentials::invalidateToken(Account *account)
|
||||
{
|
||||
Q_UNUSED(account)
|
||||
if (!removeFromCookieJar(_shibCookie)) {
|
||||
qDebug() << "invalidateToken() called but no shibCookie in in cookie jar!";
|
||||
}
|
||||
removeShibCookie(account);
|
||||
_shibCookie = QNetworkCookie();
|
||||
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()
|
||||
void ShibbolethCredentials::onShibbolethCookieReceived(const QNetworkCookie& shibCookie, Account *account)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
disconnect(_browser, SIGNAL(viewHidden()),
|
||||
this, SLOT(slotBrowserHidden()));
|
||||
disconnect(_browser, SIGNAL(shibbolethCookieReceived(QNetworkCookie, Account*)),
|
||||
this, SLOT(onShibbolethCookieReceived(QNetworkCookie, Account*)));
|
||||
_browser->hide();
|
||||
_browser->deleteLater();
|
||||
_browser = 0;
|
||||
}
|
||||
|
||||
void ShibbolethCredentials::onShibbolethCookieReceived(const QNetworkCookie& cookie, Account* account)
|
||||
{
|
||||
disposeBrowser();
|
||||
_shibCookie = cookie;
|
||||
storeShibCookie(_shibCookie, account);
|
||||
Q_EMIT newCookie(_shibCookie);
|
||||
storeShibCookie(shibCookie, account);
|
||||
_shibCookie = shibCookie;
|
||||
addToCookieJar(shibCookie);
|
||||
|
||||
// Now fetch the user...
|
||||
// But we must first do a request to webdav so the session is enabled.
|
||||
|
@ -311,9 +263,7 @@ void ShibbolethCredentials::slotUserFetched(const QString &user)
|
|||
|
||||
void ShibbolethCredentials::slotBrowserHidden()
|
||||
{
|
||||
disposeBrowser();
|
||||
_ready = false;
|
||||
_shibCookie = QNetworkCookie();
|
||||
Q_EMIT fetched();
|
||||
}
|
||||
|
||||
|
@ -356,16 +306,16 @@ 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();
|
||||
addToCookieJar(_shibCookie);
|
||||
}
|
||||
// access
|
||||
job->setSettings(account->settingsWithGroup(Theme::instance()->appName(), job));
|
||||
|
||||
_ready = true;
|
||||
_stillValid = true;
|
||||
Q_EMIT newCookie(_shibCookie);
|
||||
Q_EMIT fetched();
|
||||
} else {
|
||||
showLoginWindow(account);
|
||||
|
@ -374,14 +324,13 @@ void ShibbolethCredentials::slotReadJobDone(QKeychain::Job *job)
|
|||
|
||||
void ShibbolethCredentials::showLoginWindow(Account* account)
|
||||
{
|
||||
if (_browser) {
|
||||
if (!_browser.isNull()) {
|
||||
_browser->activateWindow();
|
||||
_browser->raise();
|
||||
// FIXME On OS X this does not raise properly
|
||||
return;
|
||||
}
|
||||
ShibbolethConfigFile cfg;
|
||||
_browser = new ShibbolethWebView(account, cfg.createCookieJar());
|
||||
_browser = new ShibbolethWebView(account);
|
||||
connect(_browser, SIGNAL(shibbolethCookieReceived(QNetworkCookie, Account*)),
|
||||
this, SLOT(onShibbolethCookieReceived(QNetworkCookie, Account*)));
|
||||
connect(_browser, SIGNAL(viewHidden()),
|
||||
|
@ -392,6 +341,30 @@ void ShibbolethCredentials::showLoginWindow(Account* account)
|
|||
_browser->show();
|
||||
}
|
||||
|
||||
QList<QNetworkCookie> ShibbolethCredentials::accountCookies(Account *account)
|
||||
{
|
||||
return account->networkAccessManager()->cookieJar()->cookiesForUrl(account->url());
|
||||
}
|
||||
|
||||
QNetworkCookie ShibbolethCredentials::findShibCookie(Account *account, QList<QNetworkCookie> cookies)
|
||||
{
|
||||
if(cookies.isEmpty()) {
|
||||
cookies = accountCookies(account);
|
||||
}
|
||||
|
||||
Q_FOREACH(QNetworkCookie cookie, cookies) {
|
||||
if (cookie.name().startsWith(shibCookieNameC)) {
|
||||
return cookie;
|
||||
}
|
||||
}
|
||||
return QNetworkCookie();
|
||||
}
|
||||
|
||||
QByteArray ShibbolethCredentials::shibCookieName()
|
||||
{
|
||||
return QByteArray(shibCookieNameC);
|
||||
}
|
||||
|
||||
void ShibbolethCredentials::storeShibCookie(const QNetworkCookie &cookie, Account *account)
|
||||
{
|
||||
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
|
||||
|
@ -403,5 +376,31 @@ void ShibbolethCredentials::storeShibCookie(const QNetworkCookie &cookie, Accoun
|
|||
job->start();
|
||||
}
|
||||
|
||||
void ShibbolethCredentials::removeShibCookie(Account *account)
|
||||
{
|
||||
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
|
||||
job->setSettings(account->settingsWithGroup(Theme::instance()->appName(), job));
|
||||
job->setKey(keychainKey(account->url().toString(), "shibAssertion"));
|
||||
job->start();
|
||||
}
|
||||
|
||||
void ShibbolethCredentials::addToCookieJar(const QNetworkCookie &cookie)
|
||||
{
|
||||
QList<QNetworkCookie> cookies;
|
||||
cookies << cookie;
|
||||
Account *account = AccountManager::instance()->account();
|
||||
QNetworkCookieJar *jar = account->networkAccessManager()->cookieJar();
|
||||
jar->blockSignals(true); // otherwise we'd call ourselves
|
||||
jar->setCookiesFromUrl(cookies, account->url());
|
||||
jar->blockSignals(false);
|
||||
}
|
||||
|
||||
bool ShibbolethCredentials::removeFromCookieJar(const QNetworkCookie &cookie)
|
||||
{
|
||||
Account *account = AccountManager::instance()->account();
|
||||
CookieJar *jar = qobject_cast<CookieJar*>(account->networkAccessManager()->cookieJar());
|
||||
return jar->deleteCookie(cookie);
|
||||
}
|
||||
|
||||
|
||||
} // ns Mirall
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <QMap>
|
||||
#include <QNetworkCookie>
|
||||
#include <QUrl>
|
||||
#include <QPointer>
|
||||
|
||||
#include "creds/abstractcredentials.h"
|
||||
|
||||
|
@ -36,7 +37,6 @@ Q_OBJECT
|
|||
|
||||
public:
|
||||
ShibbolethCredentials();
|
||||
ShibbolethCredentials(const QNetworkCookie& cookie, const QMap<QUrl, QList<QNetworkCookie> >& otherCookies);
|
||||
|
||||
void syncContextPreInit(CSYNC* ctx);
|
||||
void syncContextPreStart(CSYNC* ctx);
|
||||
|
@ -50,15 +50,17 @@ public:
|
|||
void persist(Account *account);
|
||||
void invalidateToken(Account *account);
|
||||
|
||||
QNetworkCookie cookie() const;
|
||||
|
||||
void showLoginWindow(Account*);
|
||||
|
||||
static QList<QNetworkCookie> accountCookies(Account*);
|
||||
static QNetworkCookie findShibCookie(Account*, QList<QNetworkCookie> cookies = QList<QNetworkCookie>());
|
||||
static QByteArray shibCookieName();
|
||||
|
||||
public Q_SLOTS:
|
||||
void invalidateAndFetch(Account *account);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onShibbolethCookieReceived(const QNetworkCookie& cookie, Account*);
|
||||
void onShibbolethCookieReceived(const QNetworkCookie&, Account*);
|
||||
void slotBrowserHidden();
|
||||
void onFetched();
|
||||
void slotReadJobDone(QKeychain::Job*);
|
||||
|
@ -73,15 +75,16 @@ Q_SIGNALS:
|
|||
|
||||
private:
|
||||
void storeShibCookie(const QNetworkCookie &cookie, Account *account);
|
||||
void removeShibCookie(Account *account);
|
||||
void addToCookieJar(const QNetworkCookie &cookie);
|
||||
bool removeFromCookieJar(const QNetworkCookie &cookie);
|
||||
QUrl _url;
|
||||
QByteArray prepareCookieData() const;
|
||||
void disposeBrowser();
|
||||
|
||||
QNetworkCookie _shibCookie;
|
||||
bool _ready;
|
||||
bool _stillValid;
|
||||
ShibbolethWebView* _browser;
|
||||
QMap<QUrl, QList<QNetworkCookie> > _otherCookies;
|
||||
QPointer<ShibbolethWebView> _browser;
|
||||
QNetworkCookie _shibCookie;
|
||||
QString _user;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,9 +12,11 @@
|
|||
*/
|
||||
|
||||
#include "mirall/account.h"
|
||||
#include "mirall/cookiejar.h"
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/networkjobs.h"
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
#include "mirall/mirallaccessmanager.h"
|
||||
#include "mirall/quotainfo.h"
|
||||
#include "creds/abstractcredentials.h"
|
||||
#include "creds/credentialsfactory.h"
|
||||
|
@ -75,6 +77,7 @@ Account::Account(AbstractSslErrorHandler *sslErrorHandler, QObject *parent)
|
|||
|
||||
Account::~Account()
|
||||
{
|
||||
delete _am;
|
||||
}
|
||||
|
||||
void Account::save()
|
||||
|
@ -161,7 +164,11 @@ AbstractCredentials *Account::credentials() const
|
|||
void Account::setCredentials(AbstractCredentials *cred)
|
||||
{
|
||||
// set active credential manager
|
||||
QNetworkCookieJar *jar = 0;
|
||||
if (_am) {
|
||||
jar = _am->cookieJar();
|
||||
jar->setParent(0);
|
||||
|
||||
_am->deleteLater();
|
||||
}
|
||||
|
||||
|
@ -170,6 +177,9 @@ void Account::setCredentials(AbstractCredentials *cred)
|
|||
}
|
||||
_credentials = cred;
|
||||
_am = _credentials->getQNAM();
|
||||
if (jar) {
|
||||
_am->setCookieJar(jar);
|
||||
}
|
||||
connect(_am, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
SLOT(slotHandleErrors(QNetworkReply*,QList<QSslError>)));
|
||||
}
|
||||
|
@ -186,7 +196,12 @@ QList<QNetworkCookie> Account::lastAuthCookies() const
|
|||
|
||||
void Account::clearCookieJar()
|
||||
{
|
||||
_am->setCookieJar(new QNetworkCookieJar);
|
||||
_am->setCookieJar(new CookieJar);
|
||||
}
|
||||
|
||||
QNetworkAccessManager *Account::networkAccessManager()
|
||||
{
|
||||
return _am;
|
||||
}
|
||||
|
||||
QNetworkReply *Account::headRequest(const QString &relPath)
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace Mirall {
|
|||
class AbstractCredentials;
|
||||
class Account;
|
||||
class QuotaInfo;
|
||||
class MirallAccessManager;
|
||||
|
||||
class OWNCLOUDSYNC_EXPORT AccountManager : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -143,6 +144,8 @@ public:
|
|||
|
||||
void clearCookieJar();
|
||||
|
||||
QNetworkAccessManager* networkAccessManager();
|
||||
|
||||
QuotaInfo *quotaInfo();
|
||||
signals:
|
||||
void stateChanged(int state);
|
||||
|
|
|
@ -159,6 +159,7 @@ Application::Application(int &argc, char **argv) :
|
|||
|
||||
Application::~Application()
|
||||
{
|
||||
delete AccountManager::instance()->account();
|
||||
// qDebug() << "* Mirall shutdown";
|
||||
}
|
||||
|
||||
|
|
148
src/mirall/cookiejar.cpp
Normal file
148
src/mirall/cookiejar.cpp
Normal file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "cookiejar.h"
|
||||
|
||||
#include "mirall/mirallconfigfile.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
namespace {
|
||||
const unsigned int JAR_VERSION = 23;
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &stream, const QList<QNetworkCookie> &list)
|
||||
{
|
||||
stream << JAR_VERSION;
|
||||
stream << quint32(list.size());
|
||||
for (int i = 0; i < list.size(); ++i)
|
||||
stream << list.at(i).toRawForm();
|
||||
return stream;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &stream, QList<QNetworkCookie> &list)
|
||||
{
|
||||
list.clear();
|
||||
|
||||
quint32 version;
|
||||
stream >> version;
|
||||
|
||||
if (version != JAR_VERSION)
|
||||
return stream;
|
||||
|
||||
quint32 count;
|
||||
stream >> count;
|
||||
for(quint32 i = 0; i < count; ++i)
|
||||
{
|
||||
QByteArray value;
|
||||
stream >> value;
|
||||
QList<QNetworkCookie> newCookies = QNetworkCookie::parseCookies(value);
|
||||
if (newCookies.count() == 0 && value.length() != 0) {
|
||||
qWarning() << "CookieJar: Unable to parse saved cookie:" << value;
|
||||
}
|
||||
for (int j = 0; j < newCookies.count(); ++j)
|
||||
list.append(newCookies.at(j));
|
||||
if (stream.atEnd())
|
||||
break;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
CookieJar::CookieJar(QObject *parent) :
|
||||
QNetworkCookieJar(parent)
|
||||
{
|
||||
restore();
|
||||
}
|
||||
|
||||
CookieJar::~CookieJar()
|
||||
{
|
||||
save();
|
||||
}
|
||||
|
||||
bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url)
|
||||
{
|
||||
if (QNetworkCookieJar::setCookiesFromUrl(cookieList, url)) {
|
||||
Q_EMIT newCookiesForUrl(cookieList, url);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl &url)
|
||||
{
|
||||
QList<QNetworkCookie> cookies = QNetworkCookieJar::cookiesForUrl(url);
|
||||
qDebug() << url << "requests:" << cookies;
|
||||
return cookies;
|
||||
}
|
||||
|
||||
bool CookieJar::deleteCookie(const QNetworkCookie &delCookie)
|
||||
{
|
||||
QList<QNetworkCookie> cookies = allCookies();
|
||||
bool removeSucceeded = false;
|
||||
foreach(const QNetworkCookie &cookie, cookies) {
|
||||
// ### cookies are not identical in attriutes, why?
|
||||
if (cookie.name() == delCookie.name()) {
|
||||
cookies.removeOne(cookie);
|
||||
removeSucceeded = true;
|
||||
}
|
||||
}
|
||||
setAllCookies(cookies);
|
||||
return removeSucceeded;
|
||||
}
|
||||
|
||||
void CookieJar::save()
|
||||
{
|
||||
QFile file;
|
||||
file.setFileName(storagePath());
|
||||
qDebug() << storagePath();
|
||||
file.open(QIODevice::WriteOnly);
|
||||
QDataStream stream(&file);
|
||||
stream << allCookies();
|
||||
file.close();
|
||||
}
|
||||
|
||||
void CookieJar::restore()
|
||||
{
|
||||
QFile file;
|
||||
file.setFileName(storagePath());
|
||||
file.open(QIODevice::ReadOnly);
|
||||
QDataStream stream(&file);
|
||||
QList<QNetworkCookie> list;
|
||||
stream >> list;
|
||||
setAllCookies(removeExpired(list));
|
||||
file.close();
|
||||
}
|
||||
|
||||
QList<QNetworkCookie> CookieJar::removeExpired(const QList<QNetworkCookie> &cookies)
|
||||
{
|
||||
QList<QNetworkCookie> updatedList;
|
||||
foreach(const QNetworkCookie &cookie, cookies) {
|
||||
if (cookie.expirationDate() > QDateTime::currentDateTime()) {
|
||||
updatedList << cookie;
|
||||
}
|
||||
}
|
||||
return updatedList;
|
||||
}
|
||||
|
||||
QString CookieJar::storagePath() const
|
||||
{
|
||||
MirallConfigFile cfg;
|
||||
return cfg.configPath() + "/cookies.db";
|
||||
}
|
||||
|
||||
} // namespace Mirall
|
44
src/mirall/cookiejar.h
Normal file
44
src/mirall/cookiejar.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef MIRALL_COOKIEJAR_H
|
||||
#define MIRALL_COOKIEJAR_H
|
||||
|
||||
#include <QNetworkCookieJar>
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
class CookieJar : public QNetworkCookieJar
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CookieJar(QObject *parent = 0);
|
||||
~CookieJar();
|
||||
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
|
||||
QList<QNetworkCookie> cookiesForUrl(const QUrl &url);
|
||||
|
||||
virtual bool deleteCookie(const QNetworkCookie & cookie);
|
||||
|
||||
signals:
|
||||
void newCookiesForUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url);
|
||||
private:
|
||||
void save();
|
||||
void restore();
|
||||
QList<QNetworkCookie> removeExpired(const QList<QNetworkCookie> &cookies);
|
||||
QString storagePath() const;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Mirall
|
||||
|
||||
#endif // MIRALL_COOKIEJAR_H
|
|
@ -15,6 +15,7 @@
|
|||
#include <QNetworkProxy>
|
||||
#include <QAuthenticator>
|
||||
|
||||
#include "mirall/cookiejar.h"
|
||||
#include "mirall/mirallaccessmanager.h"
|
||||
#include "mirall/utility.h"
|
||||
|
||||
|
@ -30,6 +31,8 @@ MirallAccessManager::MirallAccessManager(QObject* parent)
|
|||
proxy.setHostName(" ");
|
||||
setProxy(proxy);
|
||||
#endif
|
||||
setCookieJar(new CookieJar);
|
||||
cookieJar()->setParent(0);
|
||||
QObject::connect(this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
this, SLOT(slotProxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
|
||||
}
|
||||
|
|
|
@ -26,24 +26,20 @@ namespace Mirall
|
|||
OwncloudShibbolethCredsPage::OwncloudShibbolethCredsPage()
|
||||
: AbstractCredentialsWizardPage(),
|
||||
_browser(0),
|
||||
_cookie(),
|
||||
_afterInitialSetup(false),
|
||||
_cookiesForUrl()
|
||||
_afterInitialSetup(false)
|
||||
{}
|
||||
|
||||
void OwncloudShibbolethCredsPage::setupBrowser()
|
||||
{
|
||||
if (_browser) {
|
||||
if (!_browser.isNull()) {
|
||||
return;
|
||||
}
|
||||
OwncloudWizard *ocWizard = qobject_cast<OwncloudWizard*>(wizard());
|
||||
_browser = new ShibbolethWebView(ocWizard->account());
|
||||
connect(_browser, SIGNAL(shibbolethCookieReceived(QNetworkCookie, Account*)),
|
||||
this, SLOT(slotShibbolethCookieReceived(QNetworkCookie, Account*)));
|
||||
connect(_browser, SIGNAL(shibbolethCookieReceived(const QNetworkCookie&, Account*)),
|
||||
this, SLOT(slotShibbolethCookieReceived()));
|
||||
connect(_browser, SIGNAL(viewHidden()),
|
||||
this, SLOT(slotViewHidden()));
|
||||
connect(_browser, SIGNAL(otherCookiesReceived(QList<QNetworkCookie>, QUrl)),
|
||||
this, SLOT(slotOtherCookiesReceived(QList<QNetworkCookie>, QUrl)));
|
||||
|
||||
_browser->move(ocWizard->x(), ocWizard->y());
|
||||
_browser->show();
|
||||
|
@ -60,9 +56,6 @@ void OwncloudShibbolethCredsPage::setVisible(bool visible)
|
|||
if (isVisible() == visible) {
|
||||
return;
|
||||
}
|
||||
if (_browser) {
|
||||
disposeBrowser();
|
||||
}
|
||||
if (visible) {
|
||||
setupBrowser();
|
||||
wizard()->hide();
|
||||
|
@ -74,23 +67,6 @@ void OwncloudShibbolethCredsPage::setVisible(bool visible)
|
|||
void OwncloudShibbolethCredsPage::initializePage()
|
||||
{
|
||||
_afterInitialSetup = true;
|
||||
_cookie = QNetworkCookie();
|
||||
_cookiesForUrl.clear();
|
||||
}
|
||||
|
||||
void OwncloudShibbolethCredsPage::disposeBrowser()
|
||||
{
|
||||
if (_browser) {
|
||||
disconnect(_browser, SIGNAL(otherCookiesReceived(QList<QNetworkCookie>, QUrl)),
|
||||
this, SLOT(slotOtherCookiesReceived(QList<QNetworkCookie>, QUrl)));
|
||||
disconnect(_browser, SIGNAL(viewHidden()),
|
||||
this, SLOT(slotViewHidden()));
|
||||
disconnect(_browser, SIGNAL(shibbolethCookieReceived(QNetworkCookie, Account*)),
|
||||
this, SLOT(slotShibbolethCookieReceived(QNetworkCookie, Account*)));
|
||||
_browser->hide();
|
||||
_browser->deleteLater();
|
||||
_browser = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int OwncloudShibbolethCredsPage::nextId() const
|
||||
|
@ -105,38 +81,16 @@ void OwncloudShibbolethCredsPage::setConnected()
|
|||
|
||||
AbstractCredentials* OwncloudShibbolethCredsPage::getCredentials() const
|
||||
{
|
||||
return new ShibbolethCredentials(_cookie, _cookiesForUrl);
|
||||
return new ShibbolethCredentials;
|
||||
}
|
||||
|
||||
void OwncloudShibbolethCredsPage::slotShibbolethCookieReceived(const QNetworkCookie& cookie, Account*)
|
||||
void OwncloudShibbolethCredsPage::slotShibbolethCookieReceived()
|
||||
{
|
||||
disposeBrowser();
|
||||
_cookie = cookie;
|
||||
emit connectToOCUrl(field("OCUrl").toString().simplified());
|
||||
}
|
||||
|
||||
void OwncloudShibbolethCredsPage::slotOtherCookiesReceived(const QList<QNetworkCookie>& cookieList, const QUrl& url)
|
||||
{
|
||||
QList<QNetworkCookie>& cookies(_cookiesForUrl[url]);
|
||||
QMap<QByteArray, QByteArray> uniqueCookies;
|
||||
|
||||
Q_FOREACH (const QNetworkCookie& c, cookieList) {
|
||||
if (!c.isSessionCookie()) {
|
||||
cookies << c;
|
||||
}
|
||||
}
|
||||
Q_FOREACH (const QNetworkCookie& c, cookies) {
|
||||
uniqueCookies[c.name()] = c.value();
|
||||
}
|
||||
cookies.clear();
|
||||
Q_FOREACH (const QByteArray& name, uniqueCookies.keys()) {
|
||||
cookies << QNetworkCookie(name, uniqueCookies[name]);
|
||||
}
|
||||
}
|
||||
|
||||
void OwncloudShibbolethCredsPage::slotViewHidden()
|
||||
{
|
||||
disposeBrowser();
|
||||
wizard()->back();
|
||||
wizard()->show();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <QMap>
|
||||
#include <QNetworkCookie>
|
||||
#include <QUrl>
|
||||
#include <QPointer>
|
||||
|
||||
#include "wizard/abstractcredswizardpage.h"
|
||||
|
||||
|
@ -45,18 +46,14 @@ public Q_SLOTS:
|
|||
void setVisible(bool visible);
|
||||
|
||||
private Q_SLOTS:
|
||||
void slotShibbolethCookieReceived(const QNetworkCookie& cookie, Account*);
|
||||
void slotOtherCookiesReceived(const QList<QNetworkCookie>& cookieList, const QUrl& url);
|
||||
void slotShibbolethCookieReceived();
|
||||
void slotViewHidden();
|
||||
|
||||
private:
|
||||
void setupBrowser();
|
||||
void disposeBrowser();
|
||||
|
||||
ShibbolethWebView* _browser;
|
||||
QNetworkCookie _cookie;
|
||||
QPointer<ShibbolethWebView> _browser;
|
||||
bool _afterInitialSetup;
|
||||
QMap<QUrl, QList<QNetworkCookie> > _cookiesForUrl;
|
||||
};
|
||||
|
||||
} // ns Mirall
|
||||
|
|
Loading…
Reference in a new issue