diff --git a/.drone.yml b/.drone.yml index 0955e5492..ee57b5a3e 100644 --- a/.drone.yml +++ b/.drone.yml @@ -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: diff --git a/CMakeLists.txt b/CMakeLists.txt index 98cf189ee..600be4e27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/README.md b/README.md index 94ee764b9..6277a35b9 100644 --- a/README.md +++ b/README.md @@ -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 ``` diff --git a/admin/linux/build-appimage.sh b/admin/linux/build-appimage.sh index 55535cf07..ac7040039 100755 --- a/admin/linux/build-appimage.sh +++ b/admin/linux/build-appimage.sh @@ -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 \ diff --git a/doc/building.rst b/doc/building.rst index 933b0a178..79c54d746 100644 --- a/doc/building.rst +++ b/doc/building.rst @@ -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``. diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 2a61590ad..c75440fe1 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -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() - diff --git a/src/gui/creds/credentialsfactory.cpp b/src/gui/creds/credentialsfactory.cpp index 6062f70eb..894eaeee6 100644 --- a/src/gui/creds/credentialsfactory.cpp +++ b/src/gui/creds/credentialsfactory.cpp @@ -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 { diff --git a/src/gui/creds/shibboleth/shibbolethuserjob.cpp b/src/gui/creds/shibboleth/shibbolethuserjob.cpp deleted file mode 100644 index 24c164b26..000000000 --- a/src/gui/creds/shibboleth/shibbolethuserjob.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) by Olivier Goffart - * - * 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 - -#include -#include -#include - -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); -} -} diff --git a/src/gui/creds/shibboleth/shibbolethuserjob.h b/src/gui/creds/shibboleth/shibbolethuserjob.h deleted file mode 100644 index 2cc13b31e..000000000 --- a/src/gui/creds/shibboleth/shibbolethuserjob.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) by Olivier Goffart - * - * 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 - -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 diff --git a/src/gui/creds/shibboleth/shibbolethwebview.cpp b/src/gui/creds/shibboleth/shibbolethwebview.cpp deleted file mode 100644 index 1fb0a7b46..000000000 --- a/src/gui/creds/shibboleth/shibbolethwebview.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) by Krzesimir Nowak - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#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(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 &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 diff --git a/src/gui/creds/shibboleth/shibbolethwebview.h b/src/gui/creds/shibboleth/shibbolethwebview.h deleted file mode 100644 index 44be80736..000000000 --- a/src/gui/creds/shibboleth/shibbolethwebview.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) by Krzesimir Nowak - * - * 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 -#include -#include -#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 &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 diff --git a/src/gui/creds/shibbolethcredentials.cpp b/src/gui/creds/shibbolethcredentials.cpp deleted file mode 100644 index e56ed8be4..000000000 --- a/src/gui/creds/shibbolethcredentials.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (C) by Krzesimir Nowak - * Copyright (C) by Klaas Freitag - * - * 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 -#include -#include -#include - -#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 - -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(_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(job); - delete readJob->settings(); - QList 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(_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 ShibbolethCredentials::accountCookies(Account *account) -{ - return account->networkAccessManager()->cookieJar()->cookiesForUrl(account->davUrl()); -} - -QNetworkCookie ShibbolethCredentials::findShibCookie(Account *account, QList 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 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 diff --git a/src/gui/creds/shibbolethcredentials.h b/src/gui/creds/shibbolethcredentials.h deleted file mode 100644 index cc9df8506..000000000 --- a/src/gui/creds/shibbolethcredentials.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) by Krzesimir Nowak - * - * 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 -#include -#include -#include -#include -#include - -#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 accountCookies(Account *); - static QNetworkCookie findShibCookie(Account *, QList cookies = QList()); - 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 _browser; - QNetworkCookie _shibCookie; - QString _user; - bool _keychainMigration = false; -}; - -} // namespace OCC - -#endif diff --git a/src/gui/wizard/owncloudshibbolethcredspage.cpp b/src/gui/wizard/owncloudshibbolethcredspage.cpp deleted file mode 100644 index f18d8891d..000000000 --- a/src/gui/wizard/owncloudshibbolethcredspage.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) by Krzesimir Nowak - * - * 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 - -#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(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 diff --git a/src/gui/wizard/owncloudshibbolethcredspage.h b/src/gui/wizard/owncloudshibbolethcredspage.h deleted file mode 100644 index cf1c48f5b..000000000 --- a/src/gui/wizard/owncloudshibbolethcredspage.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) by Krzesimir Nowak - * - * 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 -#include -#include -#include -#include - -#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 _browser; - bool _afterInitialSetup = false; - QNetworkCookie _cookie; -}; - -} // namespace OCC - -#endif diff --git a/src/gui/wizard/owncloudwizard.cpp b/src/gui/wizard/owncloudwizard.cpp index 312fc1c0d..d97b0b19f 100644 --- a/src/gui/wizard/owncloudwizard.cpp +++ b/src/gui/wizard/owncloudwizard.cpp @@ -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; diff --git a/src/gui/wizard/owncloudwizard.h b/src/gui/wizard/owncloudwizard.h index 0f02b7c65..947d5f679 100644 --- a/src/gui/wizard/owncloudwizard.h +++ b/src/gui/wizard/owncloudwizard.h @@ -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; diff --git a/src/libsync/networkjobs.cpp b/src/libsync/networkjobs.cpp index d70d28a44..ac09a6a4d 100644 --- a/src/libsync/networkjobs.cpp +++ b/src/libsync/networkjobs.cpp @@ -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;