Merge pull request #2794 from FlexW/master

Remove NO_SHIBBOLETH flag and dead code
This commit is contained in:
Kevin Ottens 2021-01-05 14:17:25 +01:00 committed by GitHub
commit 0bb6dcebd8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 15 additions and 1074 deletions

View file

@ -9,7 +9,7 @@ steps:
path: /drone/build
commands:
- cd /drone/build
- cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1 -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DSANITIZE_ADDRESS=ON ../src
- cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_BUILD_TYPE=Debug -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DSANITIZE_ADDRESS=ON ../src
- name: compile
image: nextcloudci/client-5.12:client-5.12-11
volumes:
@ -53,7 +53,7 @@ steps:
path: /drone/build
commands:
- cd /drone/build
- cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1 -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DSANITIZE_ADDRESS=ON ../src
- cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_BUILD_TYPE=Debug -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DSANITIZE_ADDRESS=ON ../src
- name: compile
image: nextcloudci/client-5.12:client-5.12-11
volumes:

View file

@ -176,14 +176,6 @@ if(OWNCLOUD_5XX_NO_BLACKLIST)
add_definitions(-DOWNCLOUD_5XX_NO_BLACKLIST=1)
endif()
# Disable shibboleth.
# So the client can be built without QtWebKit
option(NO_SHIBBOLETH "Build without Shibboleth support. Allow to build the client without QtWebKit" OFF)
if(NO_SHIBBOLETH)
message("Compiling without shibboleth")
add_definitions(-DNO_SHIBBOLETH=1)
endif()
if(APPLE)
set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" )
endif()

View file

@ -33,14 +33,14 @@ $ cd build
##### Linux & Mac OS
```
$ cmake .. -DCMAKE_INSTALL_PREFIX=~/nextcloud-desktop-client -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1
$ cmake .. -DCMAKE_INSTALL_PREFIX=~/nextcloud-desktop-client -DCMAKE_BUILD_TYPE=Debug
$ make install
```
##### Windows
```
$ cmake -G "Visual Studio 15 2017 Win64" .. -DCMAKE_INSTALL_PREFIX=$USERPROFILE\nextcloud-desktop-client -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1
$ cmake -G "Visual Studio 15 2017 Win64" .. -DCMAKE_INSTALL_PREFIX=$USERPROFILE\nextcloud-desktop-client -DCMAKE_BUILD_TYPE=Debug
$ cmake --build . --config Debug --target install
```

View file

@ -37,7 +37,6 @@ cd /build
mkdir build-client
cd build-client
cmake -D CMAKE_INSTALL_PREFIX=/usr \
-D NO_SHIBBOLETH=1 \
-D BUILD_TESTING=OFF \
-D BUILD_UPDATER=ON \
-DMIRALL_VERSION_SUFFIX=PR-$DRONE_PULL_REQUEST \

View file

@ -85,7 +85,7 @@ $ git submodule update
12. Generate the build files:
```
$ cd build
$ cmake .. -DCMAKE_INSTALL_PREFIX=~/nextcloud-desktop-client -DCMAKE_BUILD_TYPE=Debug -DNO_SHIBBOLETH=1
$ cmake .. -DCMAKE_INSTALL_PREFIX=~/nextcloud-desktop-client -DCMAKE_BUILD_TYPE=Debug
```
13. Compile and install:
@ -240,7 +240,7 @@ To build the most up-to-date version of the client:
.. note:: qtkeychain must be compiled with the same prefix e.g ``CMAKE_INSTALL_PREFIX=/Users/path/to/client/install/ .``
.. note:: Example:: ``cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5 -DCMAKE_INSTALL_PREFIX=/Users/path/to/client/install/ -DNO_SHIBBOLETH=1``
.. note:: Example:: ``cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5 -DCMAKE_INSTALL_PREFIX=/Users/path/to/client/install/``
4. Call ``make``.

View file

@ -137,15 +137,6 @@ set(client_SRCS
wizard/slideshow.cpp
)
IF(NOT NO_SHIBBOLETH)
list(APPEND client_SRCS
creds/shibbolethcredentials.cpp
creds/shibboleth/shibbolethwebview.cpp
creds/shibboleth/shibbolethuserjob.cpp
wizard/owncloudshibbolethcredspage.cpp
)
endif()
IF(BUILD_UPDATER)
set(updater_SRCS
updater/ocupdater.cpp
@ -365,11 +356,6 @@ if (APPLE)
target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::MacExtras)
endif()
if (NOT NO_SHIBBOLETH)
find_package(Qt5 COMPONENTS WebKitWidgets)
target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::WebKitWidgets)
endif()
if(WITH_CRASHREPORTER)
target_link_libraries(${APPLICATION_EXECUTABLE} crashreporter-handler)
@ -436,4 +422,3 @@ if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT WIN32)
update_xdg_mimetypes( ${DATADIR}/mime/packages )
endif(SharedMimeInfo_FOUND)
endif()

View file

@ -18,9 +18,6 @@
#include "creds/credentialsfactory.h"
#include "creds/httpcredentialsgui.h"
#include "creds/dummycredentials.h"
#ifndef NO_SHIBBOLETH
#include "creds/shibbolethcredentials.h"
#endif
#include "creds/webflowcredentials.h"
namespace OCC {
@ -36,10 +33,6 @@ namespace CredentialsFactory {
return new HttpCredentialsGui;
} else if (type == "dummy") {
return new DummyCredentials;
#ifndef NO_SHIBBOLETH
} else if (type == "shibboleth") {
return new ShibbolethCredentials;
#endif
} else if (type == "webflow") {
return new WebFlowCredentials;
} else {

View file

@ -1,41 +0,0 @@
/*
* Copyright (C) by Olivier Goffart <ogoffart@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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 "shibbolethuserjob.h"
#include <account.h>
#include <QJsonDocument>
#include <QJsonObject>
#include <QLoggingCategory>
namespace OCC {
Q_DECLARE_LOGGING_CATEGORY(lcShibboleth)
ShibbolethUserJob::ShibbolethUserJob(AccountPtr account, QObject *parent)
: JsonApiJob(account, QLatin1String("ocs/v1.php/cloud/user"), parent)
{
setIgnoreCredentialFailure(true);
connect(this, &JsonApiJob::jsonReceived, this, &ShibbolethUserJob::slotJsonReceived);
}
void ShibbolethUserJob::slotJsonReceived(const QJsonDocument &json, int statusCode)
{
if (statusCode != 100) {
qCWarning(lcShibboleth) << "JSON Api call resulted in status code != 100";
}
QString user = json.object().value("ocs").toObject().value("data").toObject().value("id").toString();
emit userFetched(user);
}
}

View file

@ -1,42 +0,0 @@
/*
* Copyright (C) by Olivier Goffart <ogoffart@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; either version 2 of the License, or
* (at your option) any later version.
*
* 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.
*/
#pragma once
#include <networkjobs.h>
class QJsonDocument;
namespace OCC {
/**
* @brief Fetch the user name of the shibboleth connection
* @ingroup gui
*/
class ShibbolethUserJob : public JsonApiJob
{
Q_OBJECT
public:
explicit ShibbolethUserJob(AccountPtr account, QObject *parent = nullptr);
signals:
// is always emitted when the job is finished. user is empty in case of error.
void userFetched(const QString &user);
private slots:
void slotJsonReceived(const QJsonDocument &, int statusCode);
};
} // namespace OCC

View file

@ -1,169 +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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 <QApplication>
#include <QNetworkCookie>
#include <QNetworkCookieJar>
#include <QWebFrame>
#include <QWebPage>
#include <QMessageBox>
#include <QNetworkReply>
#include <QSettings>
#include <QMainWindow>
#include "creds/shibboleth/shibbolethwebview.h"
#include "creds/shibbolethcredentials.h"
#include "account.h"
#include "logger.h"
#include "accessmanager.h"
#include "theme.h"
#include "configfile.h"
#include "cookiejar.h"
namespace {
const char ShibbolethWebViewGeometryC[] = "ShibbolethWebView/Geometry";
}
namespace OCC {
class UserAgentWebPage : public QWebPage
{
public:
UserAgentWebPage(QObject *parent)
: QWebPage(parent)
{
if (!qEnvironmentVariableIsEmpty("OWNCLOUD_SHIBBOLETH_DEBUG")) {
settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
}
}
QString userAgentForUrl(const QUrl &url) const override
{
return QWebPage::userAgentForUrl(url) + " " + Utility::userAgentString();
}
};
ShibbolethWebView::ShibbolethWebView(AccountPtr account, QWidget *parent)
: QWebView(parent)
, _account(account)
, _accepted(false)
, _cursorOverriden(false)
{
// no minimize
setWindowFlags(Qt::Dialog);
setAttribute(Qt::WA_DeleteOnClose);
QWebPage *page = new UserAgentWebPage(this);
connect(page, &QWebPage::loadStarted,
this, &ShibbolethWebView::slotLoadStarted);
connect(page, &QWebPage::loadFinished,
this, &ShibbolethWebView::slotLoadFinished);
// Make sure to accept the same SSL certificate issues as the regular QNAM we use for syncing
QObject::connect(page->networkAccessManager(), &QNetworkAccessManager::sslErrors,
_account.data(), &Account::slotHandleSslErrors);
// The Account keeps ownership of the cookie jar, it must outlive this webview.
account->lendCookieJarTo(page->networkAccessManager());
connect(static_cast<CookieJar *>(page->networkAccessManager()->cookieJar()), &CookieJar::newCookiesForUrl,
this, &ShibbolethWebView::onNewCookiesForUrl);
page->mainFrame()->load(account->url());
this->setPage(page);
setWindowTitle(tr("%1 - Authenticate").arg(Theme::instance()->appNameGUI()));
// Debug view to display the cipher suite
if (!qEnvironmentVariableIsEmpty("OWNCLOUD_SHIBBOLETH_DEBUG")) {
// open an additional window to display some cipher debug info
QWebPage *debugPage = new UserAgentWebPage(this);
debugPage->mainFrame()->load(QUrl("https://cc.dcsec.uni-hannover.de/"));
auto *debugView = new QWebView(this);
debugView->setPage(debugPage);
auto *window = new QMainWindow(this);
window->setWindowTitle(tr("SSL Cipher Debug View"));
window->setCentralWidget(debugView);
window->show();
}
// If we have a valid cookie, it's most likely expired. We can use this as
// as a criteria to tell the user why the browser window pops up
QNetworkCookie shibCookie = ShibbolethCredentials::findShibCookie(_account.data(), ShibbolethCredentials::accountCookies(_account.data()));
if (shibCookie != QNetworkCookie()) {
Logger::instance()->postOptionalGuiLog(tr("Reauthentication required"), tr("Your session has expired. You need to re-login to continue to use the client."));
}
ConfigFile config;
QSettings settings(config.configFile());
resize(900, 700); // only effective the first time, later overridden by restoreGeometry
restoreGeometry(settings.value(ShibbolethWebViewGeometryC).toByteArray());
}
ShibbolethWebView::~ShibbolethWebView()
{
ConfigFile config;
QSettings settings(config.configFile());
settings.setValue(ShibbolethWebViewGeometryC, saveGeometry());
}
void ShibbolethWebView::onNewCookiesForUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
{
if (url.host() == _account->url().host()) {
QNetworkCookie shibCookie = ShibbolethCredentials::findShibCookie(_account.data(), cookieList);
if (shibCookie != QNetworkCookie()) {
Q_EMIT shibbolethCookieReceived(shibCookie);
accept();
close();
}
}
}
void ShibbolethWebView::closeEvent(QCloseEvent *event)
{
if (_cursorOverriden) {
QApplication::restoreOverrideCursor();
}
if (!_accepted) {
Q_EMIT rejected();
}
QWebView::closeEvent(event);
}
void ShibbolethWebView::slotLoadStarted()
{
if (!_cursorOverriden) {
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
_cursorOverriden = true;
}
}
void ShibbolethWebView::slotLoadFinished(bool success)
{
if (_cursorOverriden) {
QApplication::restoreOverrideCursor();
}
if (!title().isNull()) {
setWindowTitle(QString::fromLatin1("%1 - %2 (%3)").arg(Theme::instance()->appNameGUI(), title(), url().host()));
}
if (!success) {
qCWarning(lcShibboleth) << "Could not load Shibboleth login page to log you in.";
}
}
void ShibbolethWebView::accept()
{
_accepted = true;
}
} // namespace OCC

View file

@ -1,67 +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; either version 2 of the License, or
* (at your option) any later version.
*
* 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_WEB_VIEW_H
#define MIRALL_WIZARD_SHIBBOLETH_WEB_VIEW_H
#include "owncloudlib.h"
#include <QList>
#include <QPointer>
#include <QWebView>
#include "accountfwd.h"
class QNetworkCookie;
class QUrl;
namespace OCC {
class ShibbolethCookieJar;
/**
* @brief The ShibbolethWebView class
* @ingroup gui
*/
class ShibbolethWebView : public QWebView
{
Q_OBJECT
public:
ShibbolethWebView(AccountPtr account, QWidget *parent = nullptr);
ShibbolethWebView(AccountPtr account, ShibbolethCookieJar *jar, QWidget *parent = nullptr);
~ShibbolethWebView();
void closeEvent(QCloseEvent *event) override;
Q_SIGNALS:
void shibbolethCookieReceived(const QNetworkCookie &cookie);
void rejected();
private Q_SLOTS:
void onNewCookiesForUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
void slotLoadStarted();
void slotLoadFinished(bool success);
protected:
void accept();
private:
void setup(AccountPtr account, ShibbolethCookieJar *jar);
AccountPtr _account;
bool _accepted;
bool _cursorOverriden;
};
} // namespace OCC
#endif

View file

@ -1,391 +0,0 @@
/*
* Copyright (C) by Krzesimir Nowak <krzesimir@endocode.com>
* Copyright (C) by Klaas Freitag <freitag@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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 <QSettings>
#include <QNetworkReply>
#include <QMessageBox>
#include <QAuthenticator>
#include "creds/shibbolethcredentials.h"
#include "creds/shibboleth/shibbolethwebview.h"
#include "creds/shibbolethcredentials.h"
#include "shibboleth/shibbolethuserjob.h"
#include "creds/credentialscommon.h"
#include "creds/httpcredentialsgui.h"
#include "accessmanager.h"
#include "account.h"
#include "configfile.h"
#include "theme.h"
#include "cookiejar.h"
#include "owncloudgui.h"
#include "syncengine.h"
#include <qt5keychain/keychain.h>
using namespace QKeychain;
namespace OCC {
Q_LOGGING_CATEGORY(lcShibboleth, "nextcloud.gui.credentials.shibboleth", QtInfoMsg)
namespace {
// Not "user" because it has a special meaning for http
const char userC[] = "shib_user";
const char shibCookieNameC[] = "_shibsession_";
} // ns
ShibbolethCredentials::ShibbolethCredentials()
: AbstractCredentials()
{
}
ShibbolethCredentials::ShibbolethCredentials(const QNetworkCookie &cookie)
: _ready(true)
, _stillValid(true)
, _browser(nullptr)
, _shibCookie(cookie)
, _keychainMigration(false)
{
}
void ShibbolethCredentials::setAccount(Account *account)
{
AbstractCredentials::setAccount(account);
// This is for existing saved accounts.
if (_user.isEmpty()) {
_user = _account->credentialSetting(QLatin1String(userC)).toString();
}
// When constructed with a cookie (by the wizard), we usually don't know the
// user name yet. Request it now from the server.
if (_ready && _user.isEmpty()) {
QTimer::singleShot(1234, this, &ShibbolethCredentials::slotFetchUser);
}
}
QString ShibbolethCredentials::authType() const
{
return QString::fromLatin1("shibboleth");
}
QString ShibbolethCredentials::user() const
{
return _user;
}
QNetworkAccessManager *ShibbolethCredentials::createQNAM() const
{
QNetworkAccessManager *qnam(new AccessManager);
connect(qnam, &QNetworkAccessManager::finished,
this, &ShibbolethCredentials::slotReplyFinished);
return qnam;
}
void ShibbolethCredentials::slotReplyFinished(QNetworkReply *r)
{
if (!_browser.isNull()) {
return;
}
QVariant target = r->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (target.isValid()) {
_stillValid = false;
// The Login window will be opened in NetworkJob's finished signal
qCWarning(lcShibboleth) << "detected redirect, will open Login Window";
} else {
//_stillValid = true; // gets set when reading from keychain or getting it from browser
}
}
bool ShibbolethCredentials::ready() const
{
return _ready;
}
void ShibbolethCredentials::fetchFromKeychain()
{
_wasFetched = true;
if (_user.isEmpty()) {
_user = _account->credentialSetting(QLatin1String(userC)).toString();
}
if (_ready) {
Q_EMIT fetched();
} else {
_url = _account->url();
_keychainMigration = false;
fetchFromKeychainHelper();
}
}
void ShibbolethCredentials::fetchFromKeychainHelper()
{
auto *job = new ReadPasswordJob(Theme::instance()->appName());
job->setSettings(ConfigFile::settingsWithGroup(Theme::instance()->appName(), job).release());
job->setInsecureFallback(false);
job->setKey(keychainKey(_url.toString(), user(),
_keychainMigration ? QString() : _account->id()));
connect(job, &Job::finished, this, &ShibbolethCredentials::slotReadJobDone);
job->start();
}
void ShibbolethCredentials::askFromUser()
{
// First, we do a DetermineAuthTypeJob to make sure that the server is still using shibboleth and did not upgrade to oauth
auto *job = new DetermineAuthTypeJob(_account->sharedFromThis(), this);
connect(job, &DetermineAuthTypeJob::authType, [this, job](DetermineAuthTypeJob::AuthType type) {
if (type == DetermineAuthTypeJob::Shibboleth) {
// Normal case, still shibboleth
showLoginWindow();
} else if (type == DetermineAuthTypeJob::OAuth) {
// Hack: upgrade to oauth
auto newCred = new HttpCredentialsGui;
job->setParent(nullptr);
job->deleteLater();
auto account = this->_account;
auto user = this->_user;
account->setCredentials(newCred); // delete this
account->setCredentialSetting(QLatin1String("user"), user);
newCred->fetchUser();
newCred->askFromUser();
} else {
// Basic auth or unkown. Since it may be unkown it might be a temporary failure, don't replace the credentials here
// Still show the login window in that case not to break the flow.
showLoginWindow();
}
});
job->start();
}
bool ShibbolethCredentials::stillValid(QNetworkReply *reply)
{
Q_UNUSED(reply)
return _stillValid;
}
void ShibbolethCredentials::persist()
{
storeShibCookie(_shibCookie);
if (!_user.isEmpty()) {
_account->setCredentialSetting(QLatin1String(userC), _user);
}
}
void ShibbolethCredentials::invalidateToken()
{
_ready = false;
auto *jar = static_cast<CookieJar *>(_account->networkAccessManager()->cookieJar());
// Remove the _shibCookie
auto cookies = jar->allCookies();
for (auto it = cookies.begin(); it != cookies.end();) {
if (it->name() == _shibCookie.name()) {
it = cookies.erase(it);
} else {
++it;
}
}
jar->setAllCookies(cookies);
// Clear all other temporary cookies
jar->clearSessionCookies();
removeShibCookie();
_shibCookie = QNetworkCookie();
}
void ShibbolethCredentials::forgetSensitiveData()
{
invalidateToken();
}
void ShibbolethCredentials::onShibbolethCookieReceived(const QNetworkCookie &shibCookie)
{
storeShibCookie(shibCookie);
_shibCookie = shibCookie;
addToCookieJar(shibCookie);
slotFetchUser();
}
void ShibbolethCredentials::slotFetchUser()
{
// We must first do a request to webdav so the session is enabled.
// (because for some reason we can't access the API without that.. a bug in the server maybe?)
auto *job = new EntityExistsJob(_account->sharedFromThis(), _account->davPath(), this);
connect(job, &EntityExistsJob::exists, this, &ShibbolethCredentials::slotFetchUserHelper);
job->setIgnoreCredentialFailure(true);
job->start();
}
void ShibbolethCredentials::slotFetchUserHelper()
{
auto *job = new ShibbolethUserJob(_account->sharedFromThis(), this);
connect(job, &ShibbolethUserJob::userFetched, this, &ShibbolethCredentials::slotUserFetched);
job->start();
}
void ShibbolethCredentials::slotUserFetched(const QString &user)
{
if (_user.isEmpty()) {
if (user.isEmpty()) {
qCWarning(lcShibboleth) << "Failed to fetch the shibboleth user";
}
_user = user;
} else if (user != _user) {
qCWarning(lcShibboleth) << "Wrong user: " << user << "!=" << _user;
QMessageBox::warning(_browser, tr("Login Error"), tr("You must sign in as user %1").arg(_user));
invalidateToken();
showLoginWindow();
return;
}
_stillValid = true;
_ready = true;
Q_EMIT asked();
}
void ShibbolethCredentials::slotBrowserRejected()
{
_ready = false;
Q_EMIT asked();
}
void ShibbolethCredentials::slotReadJobDone(QKeychain::Job *job)
{
// If we can't find the credentials at the keys that include the account id,
// try to read them from the legacy locations that don't have a account id.
if (!_keychainMigration && job->error() == QKeychain::EntryNotFound) {
qCWarning(lcShibboleth)
<< "Could not find keychain entry, attempting to read from legacy location";
_keychainMigration = true;
fetchFromKeychainHelper();
return;
}
if (job->error() == QKeychain::NoError) {
auto *readJob = static_cast<ReadPasswordJob *>(job);
delete readJob->settings();
QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(readJob->textData().toUtf8());
if (cookies.count() > 0) {
_shibCookie = cookies.first();
addToCookieJar(_shibCookie);
}
// access
job->setSettings(ConfigFile::settingsWithGroup(Theme::instance()->appName(), job).release());
_ready = true;
_stillValid = true;
Q_EMIT fetched();
} else {
_ready = false;
Q_EMIT fetched();
}
// If keychain data was read from legacy location, wipe these entries and store new ones
if (_keychainMigration && _ready) {
persist();
auto *job = new DeletePasswordJob(Theme::instance()->appName());
job->setSettings(ConfigFile::settingsWithGroup(Theme::instance()->appName(), job).release());
job->setKey(keychainKey(_account->url().toString(), user(), QString()));
job->start();
qCWarning(lcShibboleth) << "Migrated old keychain entries";
}
}
void ShibbolethCredentials::showLoginWindow()
{
if (!_browser.isNull()) {
ownCloudGui::raiseDialog(_browser);
return;
}
auto *jar = static_cast<CookieJar *>(_account->networkAccessManager()->cookieJar());
// When opening a new window clear all the session cookie that might keep the user from logging in
// (or the session may already be open in the server, and there will not be redirect asking for the
// real long term cookie we want to store)
jar->clearSessionCookies();
_browser = new ShibbolethWebView(_account->sharedFromThis());
connect(_browser.data(), &ShibbolethWebView::shibbolethCookieReceived,
this, &ShibbolethCredentials::onShibbolethCookieReceived, Qt::QueuedConnection);
connect(_browser.data(), &ShibbolethWebView::rejected, this, &ShibbolethCredentials::slotBrowserRejected);
ownCloudGui::raiseDialog(_browser);
}
QList<QNetworkCookie> ShibbolethCredentials::accountCookies(Account *account)
{
return account->networkAccessManager()->cookieJar()->cookiesForUrl(account->davUrl());
}
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)
{
auto *job = new WritePasswordJob(Theme::instance()->appName());
job->setSettings(ConfigFile::settingsWithGroup(Theme::instance()->appName(), job).release());
// we don't really care if it works...
//connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotWriteJobDone(QKeychain::Job*)));
job->setKey(keychainKey(_account->url().toString(), user(), _account->id()));
job->setTextData(QString::fromUtf8(cookie.toRawForm()));
job->start();
}
void ShibbolethCredentials::removeShibCookie()
{
auto *job = new DeletePasswordJob(Theme::instance()->appName());
job->setSettings(ConfigFile::settingsWithGroup(Theme::instance()->appName(), job).release());
job->setKey(keychainKey(_account->url().toString(), user(), _account->id()));
job->start();
}
void ShibbolethCredentials::addToCookieJar(const QNetworkCookie &cookie)
{
QList<QNetworkCookie> cookies;
cookies << cookie;
QNetworkCookieJar *jar = _account->networkAccessManager()->cookieJar();
jar->blockSignals(true); // otherwise we'd call ourselves
jar->setCookiesFromUrl(cookies, _account->url());
jar->blockSignals(false);
}
} // namespace OCC

View file

@ -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; either version 2 of the License, or
* (at your option) any later version.
*
* 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_CREDENTIALS_H
#define MIRALL_CREDS_SHIBBOLETH_CREDENTIALS_H
#include <QList>
#include <QLoggingCategory>
#include <QMap>
#include <QNetworkCookie>
#include <QUrl>
#include <QPointer>
#include "creds/abstractcredentials.h"
namespace QKeychain {
class Job;
}
class QAuthenticator;
namespace OCC {
Q_DECLARE_LOGGING_CATEGORY(lcShibboleth)
class ShibbolethWebView;
/**
* @brief The ShibbolethCredentials class
* @ingroup gui
*/
class ShibbolethCredentials : public AbstractCredentials
{
Q_OBJECT
public:
ShibbolethCredentials();
/* create credentials for an already connected account */
ShibbolethCredentials(const QNetworkCookie &cookie);
void setAccount(Account *account) override;
QString authType() const override;
QString user() const override;
QNetworkAccessManager *createQNAM() const override;
bool ready() const override;
void fetchFromKeychain() override;
void askFromUser() override;
bool stillValid(QNetworkReply *reply) override;
void persist() override;
void invalidateToken() override;
void forgetSensitiveData() override;
void showLoginWindow();
static QList<QNetworkCookie> accountCookies(Account *);
static QNetworkCookie findShibCookie(Account *, QList<QNetworkCookie> cookies = QList<QNetworkCookie>());
static QByteArray shibCookieName();
private Q_SLOTS:
void onShibbolethCookieReceived(const QNetworkCookie &);
void slotBrowserRejected();
void slotReadJobDone(QKeychain::Job *);
void slotReplyFinished(QNetworkReply *);
void slotUserFetched(const QString &user);
void slotFetchUser();
void slotFetchUserHelper();
Q_SIGNALS:
void newCookie(const QNetworkCookie &cookie);
private:
void storeShibCookie(const QNetworkCookie &cookie);
void removeShibCookie();
void addToCookieJar(const QNetworkCookie &cookie);
/// Reads data from keychain, progressing to slotReadJobDone
void fetchFromKeychainHelper();
QUrl _url;
QByteArray prepareCookieData() const;
bool _ready = false;
bool _stillValid = false;
QPointer<ShibbolethWebView> _browser;
QNetworkCookie _shibCookie;
QString _user;
bool _keychainMigration = false;
};
} // namespace OCC
#endif

View file

@ -1,110 +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; either version 2 of the License, or
* (at your option) any later version.
*
* 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 <QVariant>
#include "wizard/owncloudshibbolethcredspage.h"
#include "theme.h"
#include "account.h"
#include "cookiejar.h"
#include "wizard/owncloudwizardcommon.h"
#include "wizard/owncloudwizard.h"
#include "creds/shibbolethcredentials.h"
#include "creds/shibboleth/shibbolethwebview.h"
namespace OCC {
OwncloudShibbolethCredsPage::OwncloudShibbolethCredsPage()
: AbstractCredentialsWizardPage()
{
}
void OwncloudShibbolethCredsPage::setupBrowser()
{
if (!_browser.isNull()) {
return;
}
auto *ocWizard = qobject_cast<OwncloudWizard *>(wizard());
AccountPtr account = ocWizard->account();
// we need to reset the cookie jar to drop temporary cookies (like the shib cookie)
// i.e. if someone presses "back"
QNetworkAccessManager *qnam = account->networkAccessManager();
auto *jar = new CookieJar;
jar->restore(account->cookieJarPath());
// Implicitly deletes the old cookie jar, and reparents the jar
qnam->setCookieJar(jar);
_browser = new ShibbolethWebView(account);
connect(_browser.data(), &ShibbolethWebView::shibbolethCookieReceived,
this, &OwncloudShibbolethCredsPage::slotShibbolethCookieReceived, Qt::QueuedConnection);
connect(_browser.data(), &ShibbolethWebView::rejected,
this, &OwncloudShibbolethCredsPage::slotBrowserRejected);
_browser->move(ocWizard->x(), ocWizard->y());
_browser->show();
_browser->setFocus();
}
void OwncloudShibbolethCredsPage::setVisible(bool visible)
{
if (!_afterInitialSetup) {
QWizardPage::setVisible(visible);
return;
}
if (isVisible() == visible) {
return;
}
if (visible) {
setupBrowser();
wizard()->hide();
} else {
wizard()->show();
}
}
void OwncloudShibbolethCredsPage::initializePage()
{
_afterInitialSetup = true;
}
int OwncloudShibbolethCredsPage::nextId() const
{
return WizardCommon::Page_AdvancedSetup;
}
void OwncloudShibbolethCredsPage::setConnected()
{
wizard()->show();
}
AbstractCredentials *OwncloudShibbolethCredsPage::getCredentials() const
{
return new ShibbolethCredentials(_cookie);
}
void OwncloudShibbolethCredsPage::slotShibbolethCookieReceived(const QNetworkCookie &cookie)
{
_cookie = cookie;
emit connectToOCUrl(field("OCUrl").toString().simplified());
}
void OwncloudShibbolethCredsPage::slotBrowserRejected()
{
wizard()->back();
wizard()->show();
}
} // namespace OCC

View file

@ -1,67 +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; either version 2 of the License, or
* (at your option) any later version.
*
* 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_OWNCLOUD_SHIBBOLETH_CREDS_PAGE_H
#define MIRALL_OWNCLOUD_SHIBBOLETH_CREDS_PAGE_H
#include <QList>
#include <QMap>
#include <QNetworkCookie>
#include <QUrl>
#include <QPointer>
#include "wizard/abstractcredswizardpage.h"
#include "accountfwd.h"
namespace OCC {
class ShibbolethWebView;
/**
* @brief The OwncloudShibbolethCredsPage class
* @ingroup gui
*/
class OwncloudShibbolethCredsPage : public AbstractCredentialsWizardPage
{
Q_OBJECT
public:
OwncloudShibbolethCredsPage();
AbstractCredentials *getCredentials() const override;
void initializePage() override;
int nextId() const override;
void setConnected();
Q_SIGNALS:
void connectToOCUrl(const QString &);
public Q_SLOTS:
void setVisible(bool visible) override;
private Q_SLOTS:
void slotShibbolethCookieReceived(const QNetworkCookie &);
void slotBrowserRejected();
private:
void setupBrowser();
QPointer<ShibbolethWebView> _browser;
bool _afterInitialSetup = false;
QNetworkCookie _cookie;
};
} // namespace OCC
#endif

View file

@ -23,9 +23,6 @@
#include "wizard/owncloudsetuppage.h"
#include "wizard/owncloudhttpcredspage.h"
#include "wizard/owncloudoauthcredspage.h"
#ifndef NO_SHIBBOLETH
#include "wizard/owncloudshibbolethcredspage.h"
#endif
#include "wizard/owncloudadvancedsetuppage.h"
#include "wizard/owncloudwizardresultpage.h"
#include "wizard/webviewpage.h"
@ -52,9 +49,6 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
, _setupPage(new OwncloudSetupPage(this))
, _httpCredsPage(new OwncloudHttpCredsPage(this))
, _browserCredsPage(new OwncloudOAuthCredsPage)
#ifndef NO_SHIBBOLETH
, _shibbolethCredsPage(new OwncloudShibbolethCredsPage)
#endif
, _flow2CredsPage(new Flow2AuthCredsPage)
, _advancedSetupPage(new OwncloudAdvancedSetupPage)
, _resultPage(new OwncloudWizardResultPage)
@ -67,9 +61,6 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
setPage(WizardCommon::Page_OAuthCreds, _browserCredsPage);
setPage(WizardCommon::Page_Flow2AuthCreds, _flow2CredsPage);
#ifndef NO_SHIBBOLETH
setPage(WizardCommon::Page_ShibbolethCreds, _shibbolethCredsPage);
#endif
setPage(WizardCommon::Page_AdvancedSetup, _advancedSetupPage);
setPage(WizardCommon::Page_Result, _resultPage);
setPage(WizardCommon::Page_WebView, _webViewPage);
@ -85,9 +76,6 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
connect(_httpCredsPage, &OwncloudHttpCredsPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
connect(_browserCredsPage, &OwncloudOAuthCredsPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
connect(_flow2CredsPage, &Flow2AuthCredsPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
#ifndef NO_SHIBBOLETH
connect(_shibbolethCredsPage, &OwncloudShibbolethCredsPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
#endif
connect(_webViewPage, &WebViewPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
connect(_advancedSetupPage, &OwncloudAdvancedSetupPage::createLocalAndRemoteFolders,
this, &OwncloudWizard::createLocalAndRemoteFolders);
@ -193,12 +181,6 @@ void OwncloudWizard::successfulStep()
_flow2CredsPage->setConnected();
break;
#ifndef NO_SHIBBOLETH
case WizardCommon::Page_ShibbolethCreds:
_shibbolethCredsPage->setConnected();
break;
#endif
case WizardCommon::Page_WebView:
_webViewPage->setConnected();
break;
@ -220,11 +202,7 @@ void OwncloudWizard::successfulStep()
void OwncloudWizard::setAuthType(DetermineAuthTypeJob::AuthType type)
{
_setupPage->setAuthType(type);
#ifndef NO_SHIBBOLETH
if (type == DetermineAuthTypeJob::Shibboleth) {
_credentialsPage = _shibbolethCredsPage;
} else
#endif
if (type == DetermineAuthTypeJob::OAuth) {
_credentialsPage = _browserCredsPage;
} else if (type == DetermineAuthTypeJob::LoginFlowV2) {
@ -337,8 +315,7 @@ void OwncloudWizard::askExperimentalVirtualFilesFeature(QWidget *receiver, const
const auto bestVfsMode = bestAvailableVfsMode();
QMessageBox *msgBox = nullptr;
QPushButton *acceptButton = nullptr;
switch (bestVfsMode)
{
switch (bestVfsMode) {
case Vfs::WindowsCfApi:
callback(true);
return;
@ -358,7 +335,8 @@ void OwncloudWizard::askExperimentalVirtualFilesFeature(QWidget *receiver, const
"\n\n"
"This is a new, experimental mode. If you decide to use it, please report any "
"issues that come up.")
.arg(APPLICATION_DOTVIRTUALFILE_SUFFIX), QMessageBox::NoButton, receiver);
.arg(APPLICATION_DOTVIRTUALFILE_SUFFIX),
QMessageBox::NoButton, receiver);
acceptButton = msgBox->addButton(tr("Enable experimental placeholder mode"), QMessageBox::AcceptRole);
msgBox->addButton(tr("Stay safe"), QMessageBox::RejectRole);
break;

View file

@ -32,9 +32,6 @@ Q_DECLARE_LOGGING_CATEGORY(lcWizard)
class OwncloudSetupPage;
class OwncloudHttpCredsPage;
class OwncloudOAuthCredsPage;
#ifndef NO_SHIBBOLETH
class OwncloudShibbolethCredsPage;
#endif
class OwncloudAdvancedSetupPage;
class OwncloudWizardResultPage;
class AbstractCredentials;
@ -121,9 +118,6 @@ private:
OwncloudSetupPage *_setupPage;
OwncloudHttpCredsPage *_httpCredsPage;
OwncloudOAuthCredsPage *_browserCredsPage;
#ifndef NO_SHIBBOLETH
OwncloudShibbolethCredsPage *_shibbolethCredsPage;
#endif
Flow2AuthCredsPage *_flow2CredsPage;
OwncloudAdvancedSetupPage *_advancedSetupPage;
OwncloudWizardResultPage *_resultPage;

View file

@ -920,18 +920,9 @@ void DetermineAuthTypeJob::start()
oldFlowRequired->setIgnoreCredentialFailure(true);
connect(get, &AbstractNetworkJob::redirected, this, [this, get](QNetworkReply *, const QUrl &target, int) {
#ifndef NO_SHIBBOLETH
QRegExp shibbolethyWords("SAML|wayf");
shibbolethyWords.setCaseSensitivity(Qt::CaseInsensitive);
if (target.toString().contains(shibbolethyWords)) {
_resultGet = Shibboleth;
get->setFollowRedirects(false);
}
#else
Q_UNUSED(this)
Q_UNUSED(get)
Q_UNUSED(target)
#endif
});
connect(get, &SimpleNetworkJob::finishedSignal, this, [this]() {
_getDone = true;