Remove NO_SHIBBOLETH flag and dead code

Signed-off-by: Felix Weilbach <felix.weilbach@t-online.de>
This commit is contained in:
Felix Weilbach 2021-01-05 12:25:58 +01:00
parent 0b5f42f832
commit db0f1e245d
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

@ -13,13 +13,13 @@ desktop client.
These instructions are updated to work with version |version| of the Nextcloud Client.
You have two possibilities to clone the repo.
You have two possibilities to clone the repo.
First option is As [remote URL](https://help.github.com/en/articles/which-remote-url-should-i-use) you can choose between cloning with HTTPS URL's, which is recommended or cloning with SSH URL's.
First option is As [remote URL](https://help.github.com/en/articles/which-remote-url-should-i-use) you can choose between cloning with HTTPS URL's, which is recommended or cloning with SSH URL's.
[https://github.com/nextcloud/desktop.git](https://github.com/nextcloud/desktop.git)
When you don't have SSH key added to your GitHub account, than use HTTPS.
When you don't have SSH key added to your GitHub account, than use HTTPS.
When you no part of the nextcloud organisation, clone with HTTPS:
@ -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,12 +202,8 @@ 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) {
if (type == DetermineAuthTypeJob::OAuth) {
_credentialsPage = _browserCredsPage;
} else if (type == DetermineAuthTypeJob::LoginFlowV2) {
_credentialsPage = _flow2CredsPage;
@ -311,7 +289,7 @@ void OwncloudWizard::changeEvent(QEvent *e)
emit styleChanged();
break;
case QEvent::ActivationChange:
if(isActiveWindow())
if (isActiveWindow())
emit onActivate();
break;
default:
@ -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;