[Pkg-owncloud-commits] [owncloud-client] 121/333: Improve libowncloudsync
Sandro Knauß
hefee-guest at moszumanska.debian.org
Thu Apr 17 23:16:42 UTC 2014
This is an automated email from the git hooks/post-receive script.
hefee-guest pushed a commit to branch master
in repository owncloud-client.
commit 4e7e25c5698c88637764d63a47c886bbf59a3a11
Author: Markus Goetz <markus at woboq.com>
Date: Tue Mar 11 16:55:53 2014 +0100
Improve libowncloudsync
* Introduce TokenCredentials
* Introduce static compiling
* Have compile flags for smaller compile
---
csync/src/CMakeLists.txt | 1 +
src/CMakeLists.txt | 128 ++++++++++++++-------
src/creds/credentialsfactory.cpp | 9 ++
src/creds/tokencredentials.cpp | 240 +++++++++++++++++++++++++++++++++++++++
src/creds/tokencredentials.h | 67 +++++++++++
5 files changed, 405 insertions(+), 40 deletions(-)
diff --git a/csync/src/CMakeLists.txt b/csync/src/CMakeLists.txt
index 6d47425..899d52d 100644
--- a/csync/src/CMakeLists.txt
+++ b/csync/src/CMakeLists.txt
@@ -100,6 +100,7 @@ include_directories(
)
add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
+add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS})
target_link_libraries(${CSYNC_LINK_LIBRARIES})
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6213e2c..c2467ea 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,5 +1,16 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
+# this option removes Http authentication, keychain, shibboleth etc and is intended for
+# external authentication mechanisms
+option(TOKEN_AUTH_ONLY "TOKEN_AUTH_ONLY" OFF)
+if(TOKEN_AUTH_ONLY)
+ message("Compiling with token authentication")
+ add_definitions(-DTOKEN_AUTH_ONLY=1)
+endif()
+
+# this option creates only libocsync and libowncloudsync
+option(BUILD_LIBRARIES_ONLY "BUILD_LIBRARIES_ONLY" OFF)
+
qt_add_resources(MIRALL_RC_SRC ../mirall.qrc)
if ( IS_DIRECTORY ${OEM_THEME_DIR} )
qt_add_resources(MIRALL_RC_SRC ${OEM_THEME_DIR}/theme.qrc)
@@ -85,19 +96,30 @@ set(libsync_SRCS
mirall/clientproxy.cpp
creds/dummycredentials.cpp
creds/abstractcredentials.cpp
- creds/httpcredentials.cpp
creds/credentialsfactory.cpp
creds/http/httpconfigfile.cpp
- creds/shibbolethcredentials.cpp
- creds/shibboleth/shibbolethaccessmanager.cpp
- creds/shibboleth/shibbolethcookiejar.cpp
- creds/shibboleth/shibbolethwebview.cpp
- creds/shibboleth/shibbolethrefresher.cpp
- creds/shibboleth/shibbolethconfigfile.cpp
- creds/shibboleth/authenticationdialog.cpp
creds/credentialscommon.cpp
3rdparty/qjson/json.cpp
)
+if(TOKEN_AUTH_ONLY)
+ set (libsync_SRCS
+ ${libsync_SRCS}
+ creds/tokencredentials.cpp
+ )
+ else()
+ set (libsync_SRCS
+ ${libsync_SRCS}
+ creds/httpcredentials.cpp
+ creds/shibbolethcredentials.cpp
+ creds/shibboleth/shibbolethaccessmanager.cpp
+ creds/shibboleth/shibbolethcookiejar.cpp
+ creds/shibboleth/shibbolethwebview.cpp
+ creds/shibboleth/shibbolethrefresher.cpp
+ creds/shibboleth/shibbolethconfigfile.cpp
+ creds/shibboleth/authenticationdialog.cpp
+ )
+endif()
+
set(libsync_HEADERS
mirall/folderman.h
@@ -119,19 +141,30 @@ set(libsync_HEADERS
mirall/clientproxy.h
creds/abstractcredentials.h
creds/dummycredentials.h
- creds/httpcredentials.h
creds/credentialsfactory.h
creds/http/httpconfigfile.h
- creds/shibbolethcredentials.h
- creds/shibboleth/shibbolethaccessmanager.h
- creds/shibboleth/shibbolethcookiejar.h
- creds/shibboleth/shibbolethwebview.h
- creds/shibboleth/shibbolethrefresher.h
- creds/shibboleth/shibbolethconfigfile.h
- creds/shibboleth/authenticationdialog.h
creds/credentialscommon.h
3rdparty/qjson/json.h
)
+if(TOKEN_AUTH_ONLY)
+ set (libsync_HEADERS
+ ${libsync_HEADERS}
+ creds/tokencredentials.h
+ )
+else()
+ set (libsync_HEADERS
+ ${libsync_HEADERS}
+ creds/httpcredentials.h
+ creds/shibbolethcredentials.h
+ creds/shibboleth/shibbolethaccessmanager.h
+ creds/shibboleth/shibbolethcookiejar.h
+ creds/shibboleth/shibbolethwebview.h
+ creds/shibboleth/shibbolethrefresher.h
+ creds/shibboleth/shibbolethconfigfile.h
+ creds/shibboleth/authenticationdialog.h
+ )
+endif()
+
IF( NOT WIN32 AND NOT APPLE )
set(libsync_SRCS ${libsync_SRCS} mirall/folderwatcher_linux.cpp)
@@ -201,15 +234,22 @@ if(NEON_FOUND)
endif()
add_library(${synclib_NAME} SHARED ${libsync_SRCS} ${syncMoc})
+add_library(${synclib_NAME}_static STATIC ${libsync_SRCS} ${syncMoc})
qt5_use_modules(${synclib_NAME} Widgets Network Xml WebKitWidgets Sql)
+qt5_use_modules(${synclib_NAME}_static Widgets Network Xml WebKitWidgets Sql)
set_target_properties( ${synclib_NAME} PROPERTIES
VERSION ${MIRALL_VERSION}
SOVERSION ${MIRALL_SOVERSION}
)
+set_target_properties( ${synclib_NAME}_static PROPERTIES
+ VERSION ${MIRALL_VERSION}
+ SOVERSION ${MIRALL_SOVERSION}
+)
target_link_libraries(${synclib_NAME} ${libsync_LINK_TARGETS} )
+target_link_libraries(${synclib_NAME}_static ${libsync_LINK_TARGETS} )
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
install(TARGETS ${synclib_NAME}
@@ -276,6 +316,8 @@ set(mirall_SRCS
mirall/sslbutton.cpp
)
+
+
set(mirall_HEADERS
mirall/application.h
mirall/systray.h
@@ -370,7 +412,7 @@ endif(WITH_DBUS)
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE)
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
-if(NOT WIN32)
+if(NOT WIN32 AND NOT BUILD_LIBRARIES_ONLY)
file( GLOB _icons "${theme_dir}/colored/${ICON_APP_NAME}-icon-*.png" )
foreach( _file ${_icons} )
string( REPLACE "${theme_dir}/colored/${ICON_APP_NAME}-icon-" "" _res ${_file} )
@@ -386,7 +428,7 @@ endif(NOT WIN32)
# add_executable( ${APPLICATION_EXECUTABLE} main.cpp ${final_src})
add_executable( ${APPLICATION_EXECUTABLE} WIN32 main.cpp ${final_src})
qt5_use_modules(${APPLICATION_EXECUTABLE} Widgets Network Xml WebKitWidgets Sql ${ADDITIONAL_APP_MODULES})
-else()
+elif(NOT BUILD_LIBRARIES_ONLY)
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
include(DeployQt4)
@@ -409,25 +451,28 @@ add_library(updater STATIC ${updater_SRCS} ${updaterMoc})
target_link_libraries(updater ${synclib_NAME})
qt5_use_modules(updater Widgets Network Xml)
-set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}
-)
-target_link_libraries( ${APPLICATION_EXECUTABLE} ${QT_LIBRARIES} )
-target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} )
-target_link_libraries( ${APPLICATION_EXECUTABLE} updater )
-target_link_libraries( ${APPLICATION_EXECUTABLE} ${OS_SPECIFIC_LINK_LIBRARIES} )
-
-install(TARGETS ${APPLICATION_EXECUTABLE}
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib
- ARCHIVE DESTINATION lib
- BUNDLE DESTINATION "."
-)
+if(NOT BUILD_LIBRARIES_ONLY)
+ set_target_properties( ${APPLICATION_EXECUTABLE} PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY}
+ )
+ target_link_libraries( ${APPLICATION_EXECUTABLE} ${QT_LIBRARIES} )
+ target_link_libraries( ${APPLICATION_EXECUTABLE} ${synclib_NAME} )
+ target_link_libraries( ${APPLICATION_EXECUTABLE} updater )
+ target_link_libraries( ${APPLICATION_EXECUTABLE} ${OS_SPECIFIC_LINK_LIBRARIES} )
+
+ install(TARGETS ${APPLICATION_EXECUTABLE}
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+ BUNDLE DESTINATION "."
+ )
+endif()
+
#FIXME: find a nice solution to make the second if(BUILD_OWNCLOUD_OSX_BUNDLE) unnecessary
# currently it needs to be done because the code right above needs to be executed no matter
# if building a bundle or not and the install_qt4_executable needs to be called afterwards
-if(BUILD_OWNCLOUD_OSX_BUNDLE)
+if(BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY)
install_qt4_executable(${OWNCLOUD_OSX_BUNDLE} "qtaccessiblewidgets;qsqlite")
endif()
@@ -443,13 +488,16 @@ endif()
set(owncloudcmd_NAME ${APPLICATION_EXECUTABLE}cmd)
set(OWNCLOUDCMD_SRC owncloudcmd/owncloudcmd.cpp)
-add_executable(${owncloudcmd_NAME} ${OWNCLOUDCMD_SRC})
-qt5_use_modules(${owncloudcmd_NAME} Network Sql)
-set_target_properties(${owncloudcmd_NAME} PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} )
-target_link_libraries(${owncloudcmd_NAME} ${synclib_NAME})
+if(NOT BUILD_LIBRARIES_ONLY)
+ add_executable(${owncloudcmd_NAME} ${OWNCLOUDCMD_SRC})
+ qt5_use_modules(${owncloudcmd_NAME} Network Sql)
+ set_target_properties(${owncloudcmd_NAME} PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${BIN_OUTPUT_DIRECTORY} )
+ target_link_libraries(${owncloudcmd_NAME} ${synclib_NAME})
+endif()
+
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/mirall)
-if(BUILD_OWNCLOUD_OSX_BUNDLE)
+if(BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY)
install(TARGETS ${owncloudcmd_NAME} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
if (SPARKLE_FOUND)
install(FILES ${CMAKE_SOURCE_DIR}/admin/osx/deny_autoupdate_com.owncloud.desktopclient.plist
@@ -457,7 +505,7 @@ if(BUILD_OWNCLOUD_OSX_BUNDLE)
install(FILES ${CMAKE_SOURCE_DIR}/admin/osx/sparkle/dsa_pub.pem
DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources)
endif()
-else()
+elsif(NOT BUILD_LIBRARIES_ONLY)
install(TARGETS ${owncloudcmd_NAME}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
diff --git a/src/creds/credentialsfactory.cpp b/src/creds/credentialsfactory.cpp
index 72cc252..41eccae 100644
--- a/src/creds/credentialsfactory.cpp
+++ b/src/creds/credentialsfactory.cpp
@@ -13,9 +13,13 @@
#include <QString>
+#ifdef TOKEN_AUTH_ONLY
+#include "creds/tokencredentials.h"
+#else
#include "creds/httpcredentials.h"
#include "creds/dummycredentials.h"
#include "creds/shibbolethcredentials.h"
+#endif
namespace Mirall
{
@@ -25,6 +29,10 @@ namespace CredentialsFactory
AbstractCredentials* create(const QString& type)
{
+#ifdef TOKEN_AUTH_ONLY
+ return new TokenCredentials;
+#else
+
// empty string might happen for old version of configuration
if (type == "http" || type == "") {
return new HttpCredentials;
@@ -36,6 +44,7 @@ AbstractCredentials* create(const QString& type)
qWarning("Unknown credentials type: %s", qPrintable(type));
return new DummyCredentials;
}
+#endif
}
} // ns CredentialsFactory
diff --git a/src/creds/tokencredentials.cpp b/src/creds/tokencredentials.cpp
new file mode 100644
index 0000000..52a891e
--- /dev/null
+++ b/src/creds/tokencredentials.cpp
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) by Klaas Freitag <freitag at kde.org>
+ * Copyright (c) by Markus Goetz <guruz at 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 <QMutex>
+#include <QDebug>
+#include <QNetworkReply>
+#include <QSettings>
+#include <QInputDialog>
+
+
+#include "mirall/account.h"
+#include "mirall/mirallaccessmanager.h"
+#include "mirall/utility.h"
+#include "mirall/theme.h"
+#include "creds/credentialscommon.h"
+#include "creds/tokencredentials.h"
+
+
+namespace Mirall
+{
+
+namespace
+{
+
+int getauth(const char *prompt,
+ char *buf,
+ size_t len,
+ int echo,
+ int verify,
+ void *userdata)
+{
+ int re = 0;
+ QMutex mutex;
+ // ### safe?
+ TokenCredentials* http_credentials = qobject_cast<TokenCredentials*>(AccountManager::instance()->account()->credentials());
+
+ if (!http_credentials) {
+ qDebug() << "Not a HTTP creds instance!";
+ return -1;
+ }
+
+ QString qPrompt = QString::fromLatin1( prompt ).trimmed();
+ QString user = http_credentials->user();
+ QString pwd = http_credentials->password();
+
+ if( qPrompt == QLatin1String("Enter your username:") ) {
+ // qDebug() << "OOO Username requested!";
+ QMutexLocker locker( &mutex );
+ qstrncpy( buf, user.toUtf8().constData(), len );
+ } else if( qPrompt == QLatin1String("Enter your password:") ) {
+ QMutexLocker locker( &mutex );
+ // qDebug() << "OOO Password requested!";
+ qstrncpy( buf, pwd.toUtf8().constData(), len );
+ } else {
+ re = handleNeonSSLProblems(prompt, buf, len, echo, verify, userdata);
+ }
+ return re;
+}
+
+const char userC[] = "user";
+
+} // ns
+
+class TokenCredentialsAccessManager : public MirallAccessManager {
+public:
+ TokenCredentialsAccessManager(const TokenCredentials *cred, QObject* parent = 0)
+ : MirallAccessManager(parent), _cred(cred) {}
+protected:
+ QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) {
+ QByteArray credHash = QByteArray(_cred->user().toUtf8()+":"+_cred->password().toUtf8()).toBase64();
+ QNetworkRequest req(request);
+ req.setRawHeader(QByteArray("Authorization"), QByteArray("Basic ") + credHash);
+ //qDebug() << "Request for " << req.url() << "with authorization" << QByteArray::fromBase64(credHash);
+ return MirallAccessManager::createRequest(op, req, outgoingData);
+ }
+private:
+ const TokenCredentials *_cred;
+};
+
+TokenCredentials::TokenCredentials()
+ : _user(),
+ _password(),
+ _ready(false)
+{
+}
+
+TokenCredentials::TokenCredentials(const QString& user, const QString& password)
+ : _user(user),
+ _password(password),
+ _ready(true)
+{
+}
+
+void TokenCredentials::syncContextPreInit (CSYNC* ctx)
+{
+ csync_set_auth_callback (ctx, getauth);
+}
+
+void TokenCredentials::syncContextPreStart (CSYNC* ctx)
+{
+ // TODO: This should not be a part of this method, but we don't have
+ // any way to get "session_key" module property from csync. Had we
+ // have it, then we could remove this code and keep it in
+ // csyncthread code (or folder code, git remembers).
+ QList<QNetworkCookie> cookies(AccountManager::instance()->account()->lastAuthCookies());
+ QString cookiesAsString;
+
+ // Stuff cookies inside csync, then we can avoid the intermediate HTTP 401 reply
+ // when https://github.com/owncloud/core/pull/4042 is merged.
+ foreach(QNetworkCookie c, cookies) {
+ cookiesAsString += c.name();
+ cookiesAsString += '=';
+ cookiesAsString += c.value();
+ cookiesAsString += "; ";
+ }
+
+ csync_set_module_property(ctx, "session_key", cookiesAsString.toLatin1().data());
+}
+
+bool TokenCredentials::changed(AbstractCredentials* credentials) const
+{
+ TokenCredentials* other(dynamic_cast< TokenCredentials* >(credentials));
+
+ if (!other || (other->user() != this->user())) {
+ return true;
+ }
+
+ return false;
+}
+
+QString TokenCredentials::authType() const
+{
+ return QString::fromLatin1("http");
+}
+
+QString TokenCredentials::user() const
+{
+ return _user;
+}
+
+QString TokenCredentials::password() const
+{
+ return _password;
+}
+
+QNetworkAccessManager* TokenCredentials::getQNAM() const
+{
+ MirallAccessManager* qnam = new TokenCredentialsAccessManager(this);
+
+ connect( qnam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)),
+ this, SLOT(slotAuthentication(QNetworkReply*,QAuthenticator*)));
+
+ return qnam;
+}
+
+bool TokenCredentials::ready() const
+{
+ return _ready;
+}
+
+QString TokenCredentials::fetchUser(Account* account)
+{
+ _user = account->credentialSetting(QLatin1String(userC)).toString();
+ return _user;
+}
+
+void TokenCredentials::fetch(Account *account)
+{
+ if( !account ) {
+ return;
+ }
+ Q_EMIT fetched();
+}
+bool TokenCredentials::stillValid(QNetworkReply *reply)
+{
+ return ((reply->error() != QNetworkReply::AuthenticationRequiredError)
+ // returned if user or password is incorrect
+ && (reply->error() != QNetworkReply::OperationCanceledError));
+}
+
+QString TokenCredentials::queryPassword(bool *ok)
+{
+ qDebug() << AccountManager::instance()->account()->state();
+ if (ok) {
+ QString str = QInputDialog::getText(0, tr("Enter Password"),
+ tr("Please enter %1 password for user '%2':")
+ .arg(Theme::instance()->appNameGUI(), _user),
+ QLineEdit::Password, QString(), ok);
+ qDebug() << AccountManager::instance()->account()->state();
+ return str;
+ } else {
+ return QString();
+ }
+}
+
+void TokenCredentials::invalidateToken(Account *account)
+{
+ _password = QString();
+ _ready = false;
+
+ // User must be fetched from config file to generate a valid key
+ fetchUser(account);
+
+ const QString kck = keychainKey(account->url().toString(), _user);
+ if( kck.isEmpty() ) {
+ qDebug() << "InvalidateToken: User is empty, bailing out!";
+ return;
+ }
+
+ account->clearCookieJar();
+}
+
+void TokenCredentials::persist(Account *account)
+{
+}
+
+
+void TokenCredentials::slotAuthentication(QNetworkReply* reply, QAuthenticator* authenticator)
+{
+ Q_UNUSED(authenticator)
+ // we cannot use QAuthenticator, because it sends username and passwords with latin1
+ // instead of utf8 encoding. Instead, we send it manually. Thus, if we reach this signal,
+ // those credentials were invalid and we terminate.
+ qDebug() << "Stop request: Authentication failed for " << reply->url().toString();
+ reply->close();
+}
+
+} // ns Mirall
diff --git a/src/creds/tokencredentials.h b/src/creds/tokencredentials.h
new file mode 100644
index 0000000..c2a272f
--- /dev/null
+++ b/src/creds/tokencredentials.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) by Klaas Freitag <freitag at kde.org>
+ * Copyright (c) by Markus Goetz <guruz at 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.
+ */
+
+#ifndef MIRALL_CREDS_HTTP_CREDENTIALS_H
+#define MIRALL_CREDS_HTTP_CREDENTIALS_H
+
+#include <QMap>
+
+#include "creds/abstractcredentials.h"
+
+class QNetworkReply;
+class QAuthenticator;
+
+namespace QKeychain {
+class Job;
+}
+
+namespace Mirall
+{
+
+class TokenCredentials : public AbstractCredentials
+{
+ Q_OBJECT
+
+public:
+ TokenCredentials();
+ TokenCredentials(const QString& user, const QString& password);
+
+ void syncContextPreInit(CSYNC* ctx);
+ void syncContextPreStart(CSYNC* ctx);
+ bool changed(AbstractCredentials* credentials) const;
+ QString authType() const;
+ QNetworkAccessManager* getQNAM() const;
+ bool ready() const;
+ void fetch(Account *account);
+ bool stillValid(QNetworkReply *reply);
+ void persist(Account *account);
+ QString user() const;
+ QString password() const;
+ QString queryPassword(bool *ok);
+ void invalidateToken(Account *account);
+ QString fetchUser(Account *account);
+
+private Q_SLOTS:
+ void slotAuthentication(QNetworkReply*, QAuthenticator*);
+
+private:
+ QString _user;
+ QString _password;
+ bool _ready;
+};
+
+} // ns Mirall
+
+#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git
More information about the Pkg-owncloud-commits
mailing list