mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-27 09:30:13 +03:00
Merge pull request #2794 from FlexW/master
Remove NO_SHIBBOLETH flag and dead code
This commit is contained in:
commit
0bb6dcebd8
18 changed files with 15 additions and 1074 deletions
|
@ -9,7 +9,7 @@ steps:
|
||||||
path: /drone/build
|
path: /drone/build
|
||||||
commands:
|
commands:
|
||||||
- cd /drone/build
|
- 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
|
- name: compile
|
||||||
image: nextcloudci/client-5.12:client-5.12-11
|
image: nextcloudci/client-5.12:client-5.12-11
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -53,7 +53,7 @@ steps:
|
||||||
path: /drone/build
|
path: /drone/build
|
||||||
commands:
|
commands:
|
||||||
- cd /drone/build
|
- 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
|
- name: compile
|
||||||
image: nextcloudci/client-5.12:client-5.12-11
|
image: nextcloudci/client-5.12:client-5.12-11
|
||||||
volumes:
|
volumes:
|
||||||
|
|
|
@ -176,14 +176,6 @@ if(OWNCLOUD_5XX_NO_BLACKLIST)
|
||||||
add_definitions(-DOWNCLOUD_5XX_NO_BLACKLIST=1)
|
add_definitions(-DOWNCLOUD_5XX_NO_BLACKLIST=1)
|
||||||
endif()
|
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)
|
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" )
|
set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" )
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -33,14 +33,14 @@ $ cd build
|
||||||
##### Linux & Mac OS
|
##### 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
|
$ make install
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Windows
|
##### 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
|
$ cmake --build . --config Debug --target install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ cd /build
|
||||||
mkdir build-client
|
mkdir build-client
|
||||||
cd build-client
|
cd build-client
|
||||||
cmake -D CMAKE_INSTALL_PREFIX=/usr \
|
cmake -D CMAKE_INSTALL_PREFIX=/usr \
|
||||||
-D NO_SHIBBOLETH=1 \
|
|
||||||
-D BUILD_TESTING=OFF \
|
-D BUILD_TESTING=OFF \
|
||||||
-D BUILD_UPDATER=ON \
|
-D BUILD_UPDATER=ON \
|
||||||
-DMIRALL_VERSION_SUFFIX=PR-$DRONE_PULL_REQUEST \
|
-DMIRALL_VERSION_SUFFIX=PR-$DRONE_PULL_REQUEST \
|
||||||
|
|
|
@ -85,7 +85,7 @@ $ git submodule update
|
||||||
12. Generate the build files:
|
12. Generate the build files:
|
||||||
```
|
```
|
||||||
$ cd build
|
$ 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:
|
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:: 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``.
|
4. Call ``make``.
|
||||||
|
|
||||||
|
|
|
@ -137,15 +137,6 @@ set(client_SRCS
|
||||||
wizard/slideshow.cpp
|
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)
|
IF(BUILD_UPDATER)
|
||||||
set(updater_SRCS
|
set(updater_SRCS
|
||||||
updater/ocupdater.cpp
|
updater/ocupdater.cpp
|
||||||
|
@ -365,11 +356,6 @@ if (APPLE)
|
||||||
target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::MacExtras)
|
target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::MacExtras)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT NO_SHIBBOLETH)
|
|
||||||
find_package(Qt5 COMPONENTS WebKitWidgets)
|
|
||||||
target_link_libraries( ${APPLICATION_EXECUTABLE} Qt5::WebKitWidgets)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_CRASHREPORTER)
|
if(WITH_CRASHREPORTER)
|
||||||
target_link_libraries(${APPLICATION_EXECUTABLE} crashreporter-handler)
|
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 )
|
update_xdg_mimetypes( ${DATADIR}/mime/packages )
|
||||||
endif(SharedMimeInfo_FOUND)
|
endif(SharedMimeInfo_FOUND)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,6 @@
|
||||||
#include "creds/credentialsfactory.h"
|
#include "creds/credentialsfactory.h"
|
||||||
#include "creds/httpcredentialsgui.h"
|
#include "creds/httpcredentialsgui.h"
|
||||||
#include "creds/dummycredentials.h"
|
#include "creds/dummycredentials.h"
|
||||||
#ifndef NO_SHIBBOLETH
|
|
||||||
#include "creds/shibbolethcredentials.h"
|
|
||||||
#endif
|
|
||||||
#include "creds/webflowcredentials.h"
|
#include "creds/webflowcredentials.h"
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
@ -36,10 +33,6 @@ namespace CredentialsFactory {
|
||||||
return new HttpCredentialsGui;
|
return new HttpCredentialsGui;
|
||||||
} else if (type == "dummy") {
|
} else if (type == "dummy") {
|
||||||
return new DummyCredentials;
|
return new DummyCredentials;
|
||||||
#ifndef NO_SHIBBOLETH
|
|
||||||
} else if (type == "shibboleth") {
|
|
||||||
return new ShibbolethCredentials;
|
|
||||||
#endif
|
|
||||||
} else if (type == "webflow") {
|
} else if (type == "webflow") {
|
||||||
return new WebFlowCredentials;
|
return new WebFlowCredentials;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -23,9 +23,6 @@
|
||||||
#include "wizard/owncloudsetuppage.h"
|
#include "wizard/owncloudsetuppage.h"
|
||||||
#include "wizard/owncloudhttpcredspage.h"
|
#include "wizard/owncloudhttpcredspage.h"
|
||||||
#include "wizard/owncloudoauthcredspage.h"
|
#include "wizard/owncloudoauthcredspage.h"
|
||||||
#ifndef NO_SHIBBOLETH
|
|
||||||
#include "wizard/owncloudshibbolethcredspage.h"
|
|
||||||
#endif
|
|
||||||
#include "wizard/owncloudadvancedsetuppage.h"
|
#include "wizard/owncloudadvancedsetuppage.h"
|
||||||
#include "wizard/owncloudwizardresultpage.h"
|
#include "wizard/owncloudwizardresultpage.h"
|
||||||
#include "wizard/webviewpage.h"
|
#include "wizard/webviewpage.h"
|
||||||
|
@ -52,9 +49,6 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
||||||
, _setupPage(new OwncloudSetupPage(this))
|
, _setupPage(new OwncloudSetupPage(this))
|
||||||
, _httpCredsPage(new OwncloudHttpCredsPage(this))
|
, _httpCredsPage(new OwncloudHttpCredsPage(this))
|
||||||
, _browserCredsPage(new OwncloudOAuthCredsPage)
|
, _browserCredsPage(new OwncloudOAuthCredsPage)
|
||||||
#ifndef NO_SHIBBOLETH
|
|
||||||
, _shibbolethCredsPage(new OwncloudShibbolethCredsPage)
|
|
||||||
#endif
|
|
||||||
, _flow2CredsPage(new Flow2AuthCredsPage)
|
, _flow2CredsPage(new Flow2AuthCredsPage)
|
||||||
, _advancedSetupPage(new OwncloudAdvancedSetupPage)
|
, _advancedSetupPage(new OwncloudAdvancedSetupPage)
|
||||||
, _resultPage(new OwncloudWizardResultPage)
|
, _resultPage(new OwncloudWizardResultPage)
|
||||||
|
@ -67,9 +61,6 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
||||||
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
|
setPage(WizardCommon::Page_HttpCreds, _httpCredsPage);
|
||||||
setPage(WizardCommon::Page_OAuthCreds, _browserCredsPage);
|
setPage(WizardCommon::Page_OAuthCreds, _browserCredsPage);
|
||||||
setPage(WizardCommon::Page_Flow2AuthCreds, _flow2CredsPage);
|
setPage(WizardCommon::Page_Flow2AuthCreds, _flow2CredsPage);
|
||||||
#ifndef NO_SHIBBOLETH
|
|
||||||
setPage(WizardCommon::Page_ShibbolethCreds, _shibbolethCredsPage);
|
|
||||||
#endif
|
|
||||||
setPage(WizardCommon::Page_AdvancedSetup, _advancedSetupPage);
|
setPage(WizardCommon::Page_AdvancedSetup, _advancedSetupPage);
|
||||||
setPage(WizardCommon::Page_Result, _resultPage);
|
setPage(WizardCommon::Page_Result, _resultPage);
|
||||||
setPage(WizardCommon::Page_WebView, _webViewPage);
|
setPage(WizardCommon::Page_WebView, _webViewPage);
|
||||||
|
@ -85,9 +76,6 @@ OwncloudWizard::OwncloudWizard(QWidget *parent)
|
||||||
connect(_httpCredsPage, &OwncloudHttpCredsPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
|
connect(_httpCredsPage, &OwncloudHttpCredsPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
|
||||||
connect(_browserCredsPage, &OwncloudOAuthCredsPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
|
connect(_browserCredsPage, &OwncloudOAuthCredsPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
|
||||||
connect(_flow2CredsPage, &Flow2AuthCredsPage::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(_webViewPage, &WebViewPage::connectToOCUrl, this, &OwncloudWizard::connectToOCUrl);
|
||||||
connect(_advancedSetupPage, &OwncloudAdvancedSetupPage::createLocalAndRemoteFolders,
|
connect(_advancedSetupPage, &OwncloudAdvancedSetupPage::createLocalAndRemoteFolders,
|
||||||
this, &OwncloudWizard::createLocalAndRemoteFolders);
|
this, &OwncloudWizard::createLocalAndRemoteFolders);
|
||||||
|
@ -193,12 +181,6 @@ void OwncloudWizard::successfulStep()
|
||||||
_flow2CredsPage->setConnected();
|
_flow2CredsPage->setConnected();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifndef NO_SHIBBOLETH
|
|
||||||
case WizardCommon::Page_ShibbolethCreds:
|
|
||||||
_shibbolethCredsPage->setConnected();
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case WizardCommon::Page_WebView:
|
case WizardCommon::Page_WebView:
|
||||||
_webViewPage->setConnected();
|
_webViewPage->setConnected();
|
||||||
break;
|
break;
|
||||||
|
@ -220,11 +202,7 @@ void OwncloudWizard::successfulStep()
|
||||||
void OwncloudWizard::setAuthType(DetermineAuthTypeJob::AuthType type)
|
void OwncloudWizard::setAuthType(DetermineAuthTypeJob::AuthType type)
|
||||||
{
|
{
|
||||||
_setupPage->setAuthType(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;
|
_credentialsPage = _browserCredsPage;
|
||||||
} else if (type == DetermineAuthTypeJob::LoginFlowV2) {
|
} else if (type == DetermineAuthTypeJob::LoginFlowV2) {
|
||||||
|
@ -311,7 +289,7 @@ void OwncloudWizard::changeEvent(QEvent *e)
|
||||||
emit styleChanged();
|
emit styleChanged();
|
||||||
break;
|
break;
|
||||||
case QEvent::ActivationChange:
|
case QEvent::ActivationChange:
|
||||||
if(isActiveWindow())
|
if (isActiveWindow())
|
||||||
emit onActivate();
|
emit onActivate();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -337,8 +315,7 @@ void OwncloudWizard::askExperimentalVirtualFilesFeature(QWidget *receiver, const
|
||||||
const auto bestVfsMode = bestAvailableVfsMode();
|
const auto bestVfsMode = bestAvailableVfsMode();
|
||||||
QMessageBox *msgBox = nullptr;
|
QMessageBox *msgBox = nullptr;
|
||||||
QPushButton *acceptButton = nullptr;
|
QPushButton *acceptButton = nullptr;
|
||||||
switch (bestVfsMode)
|
switch (bestVfsMode) {
|
||||||
{
|
|
||||||
case Vfs::WindowsCfApi:
|
case Vfs::WindowsCfApi:
|
||||||
callback(true);
|
callback(true);
|
||||||
return;
|
return;
|
||||||
|
@ -358,7 +335,8 @@ void OwncloudWizard::askExperimentalVirtualFilesFeature(QWidget *receiver, const
|
||||||
"\n\n"
|
"\n\n"
|
||||||
"This is a new, experimental mode. If you decide to use it, please report any "
|
"This is a new, experimental mode. If you decide to use it, please report any "
|
||||||
"issues that come up.")
|
"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);
|
acceptButton = msgBox->addButton(tr("Enable experimental placeholder mode"), QMessageBox::AcceptRole);
|
||||||
msgBox->addButton(tr("Stay safe"), QMessageBox::RejectRole);
|
msgBox->addButton(tr("Stay safe"), QMessageBox::RejectRole);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -32,9 +32,6 @@ Q_DECLARE_LOGGING_CATEGORY(lcWizard)
|
||||||
class OwncloudSetupPage;
|
class OwncloudSetupPage;
|
||||||
class OwncloudHttpCredsPage;
|
class OwncloudHttpCredsPage;
|
||||||
class OwncloudOAuthCredsPage;
|
class OwncloudOAuthCredsPage;
|
||||||
#ifndef NO_SHIBBOLETH
|
|
||||||
class OwncloudShibbolethCredsPage;
|
|
||||||
#endif
|
|
||||||
class OwncloudAdvancedSetupPage;
|
class OwncloudAdvancedSetupPage;
|
||||||
class OwncloudWizardResultPage;
|
class OwncloudWizardResultPage;
|
||||||
class AbstractCredentials;
|
class AbstractCredentials;
|
||||||
|
@ -121,9 +118,6 @@ private:
|
||||||
OwncloudSetupPage *_setupPage;
|
OwncloudSetupPage *_setupPage;
|
||||||
OwncloudHttpCredsPage *_httpCredsPage;
|
OwncloudHttpCredsPage *_httpCredsPage;
|
||||||
OwncloudOAuthCredsPage *_browserCredsPage;
|
OwncloudOAuthCredsPage *_browserCredsPage;
|
||||||
#ifndef NO_SHIBBOLETH
|
|
||||||
OwncloudShibbolethCredsPage *_shibbolethCredsPage;
|
|
||||||
#endif
|
|
||||||
Flow2AuthCredsPage *_flow2CredsPage;
|
Flow2AuthCredsPage *_flow2CredsPage;
|
||||||
OwncloudAdvancedSetupPage *_advancedSetupPage;
|
OwncloudAdvancedSetupPage *_advancedSetupPage;
|
||||||
OwncloudWizardResultPage *_resultPage;
|
OwncloudWizardResultPage *_resultPage;
|
||||||
|
|
|
@ -920,18 +920,9 @@ void DetermineAuthTypeJob::start()
|
||||||
oldFlowRequired->setIgnoreCredentialFailure(true);
|
oldFlowRequired->setIgnoreCredentialFailure(true);
|
||||||
|
|
||||||
connect(get, &AbstractNetworkJob::redirected, this, [this, get](QNetworkReply *, const QUrl &target, int) {
|
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(this)
|
||||||
Q_UNUSED(get)
|
Q_UNUSED(get)
|
||||||
Q_UNUSED(target)
|
Q_UNUSED(target)
|
||||||
#endif
|
|
||||||
});
|
});
|
||||||
connect(get, &SimpleNetworkJob::finishedSignal, this, [this]() {
|
connect(get, &SimpleNetworkJob::finishedSignal, this, [this]() {
|
||||||
_getDone = true;
|
_getDone = true;
|
||||||
|
|
Loading…
Reference in a new issue