Comparar commits
49 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 08dd9796d1 | |||
| 47274f1075 | |||
| f72e1cc837 | |||
| 8aace3284f | |||
| 922e004fc6 | |||
| 9d1208baa4 | |||
| 8e914deb99 | |||
| 34dd3b207e | |||
| 68e8d659fb | |||
| 5c45ede4a5 | |||
| cabcdd890e | |||
| 0a5e691ba3 | |||
| ba300c2fc1 | |||
| 07904e078a | |||
| d5fd6309ed | |||
| a2467b5dea | |||
| 0bbcee7354 | |||
| 8a18cf811e | |||
| 4e7e25c569 | |||
| c24c97703a | |||
| aa4e90acfc | |||
| c8a8eb35fa | |||
| 2656cc70d1 | |||
| 8bf2c54b56 | |||
| 630f61142a | |||
| f348499bbe | |||
| 7a3abac833 | |||
| eb7074e9f0 | |||
| 66b152ac69 | |||
| 6df00ad08c | |||
| 76b24ff00d | |||
| 60a1d50ec9 | |||
| 9eb3452a71 | |||
| 228de7eede | |||
| 2164f5d9b7 | |||
| 4240010046 | |||
| 1eb0875518 | |||
| b8e52304bd | |||
| 0658802048 | |||
| eeb68919bf | |||
| 9a60732542 | |||
| f8d996258e | |||
| c8714be1d2 | |||
| 36cd9d9ced | |||
| 9c70ee68d2 | |||
| e809a59049 | |||
| 33ae2eb19f | |||
| d4fa955950 | |||
| 4e0496f74d |
+24
-2
@@ -41,6 +41,7 @@ get_git_head_revision(GIT_REFSPEC GIT_SHA1)
|
||||
# if we cannot get it from git, directly try .tag (packages)
|
||||
# this will work if the tar balls have been properly created
|
||||
# via git-archive.
|
||||
if (GIT_SHA1)
|
||||
if (${GIT_SHA1} STREQUAL "GITDIR-NOTFOUND")
|
||||
file(READ ${CMAKE_SOURCE_DIR}/.tag sha1_candidate)
|
||||
string(REPLACE "\n" "" sha1_candidate ${sha1_candidate})
|
||||
@@ -49,6 +50,7 @@ if (${GIT_SHA1} STREQUAL "GITDIR-NOTFOUND")
|
||||
set (GIT_SHA1 "${sha1_candidate}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||
set(DATADIR ${DATA_INSTALL_DIR})
|
||||
@@ -72,13 +74,30 @@ else()
|
||||
endif()
|
||||
#####
|
||||
|
||||
# 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)
|
||||
|
||||
#### find libs
|
||||
#find_package(Qt4 4.7.0 COMPONENTS QtCore QtGui QtXml QtNetwork QtTest QtWebkit REQUIRED )
|
||||
#if( UNIX AND NOT APPLE ) # Fdo notifications
|
||||
# find_package(Qt4 4.7.0 COMPONENTS QtDBus REQUIRED )
|
||||
#endif()
|
||||
find_package(Neon REQUIRED)
|
||||
find_package(QtKeychain REQUIRED)
|
||||
|
||||
if(NOT TOKEN_AUTH_ONLY)
|
||||
find_package(QtKeychain REQUIRED)
|
||||
set(WITH_QTKEYCHAIN ${QTKEYCHAIN_FOUND})
|
||||
else()
|
||||
endif()
|
||||
|
||||
Find_package(Sparkle)
|
||||
if(UNIX)
|
||||
find_package(INotify REQUIRED)
|
||||
@@ -88,7 +107,7 @@ endif()
|
||||
find_package(Sphinx)
|
||||
find_package(PdfLatex)
|
||||
|
||||
set(WITH_QTKEYCHAIN ${QTKEYCHAIN_FOUND})
|
||||
|
||||
|
||||
configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
@@ -96,6 +115,9 @@ include(OwnCloudCPack.cmake)
|
||||
|
||||
add_definitions(-DUNICODE)
|
||||
add_definitions(-D_UNICODE)
|
||||
if( WIN32 )
|
||||
add_definitions( -D__USE_MINGW_ANSI_STDIO=1 )
|
||||
endif( WIN32 )
|
||||
|
||||
# Handle Translations, pick all mirall_* files from trans directory.
|
||||
file( GLOB TRANS_FILES ${CMAKE_SOURCE_DIR}/translations/mirall_*.ts)
|
||||
|
||||
+13
-5
@@ -1,8 +1,20 @@
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
version 1.5.2 (release 2014-02-26 )
|
||||
version 1.5.3 (release 2014-03-10 )
|
||||
* Fix usage of proxies after first sync run (#1502, #1524, #1459, #1521)
|
||||
* Do not wipe the credentials from config for reconnect (#1499, #1503)
|
||||
* Do not erase the full account config if an old version of the client stored
|
||||
the password (related to above)
|
||||
* Fix layout of the network tab (fixes #1491)
|
||||
* Handle authentication requests by a Shibboleth IdP
|
||||
* Shibboleth: If no connection is available, don't open the login window
|
||||
* [Packaging] Debian/Ubuntu: ship sync-exclude.lst
|
||||
* [Packaging] Fix issues with access to gnome keychain in Fedora and RHEL6
|
||||
* [Packaging] Ensure all sub packages get updated
|
||||
* [Packaging] Fix incorrect path in desktop file (RHEL6/CentOS6)
|
||||
|
||||
version 1.5.2 (release 2014-02-26 )
|
||||
* Fix behavior when attempting to rename Shared folder
|
||||
* Fix potential endless sync loops on Mac OS (#1463)
|
||||
* Fix potential crash when pausing during update phase (#1442)
|
||||
@@ -20,9 +32,6 @@ version 1.5.2 (release 2014-02-26 )
|
||||
* Shibboleth: Avoid auth on restart by storing cookies in the wallet
|
||||
* Fix license headers
|
||||
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
version 1.5.1 (release 2014-02-13 )
|
||||
* Added an auto updater that updates the client if a
|
||||
more recent version was found automatically (Windows, Mac OS X)
|
||||
@@ -90,7 +99,6 @@ version 1.5.0 (release 2013-12-12 ), csync 0.91.4 required
|
||||
* Windows: Fix move file operation
|
||||
|
||||
version 1.4.2 (release 2013-10-18 ), csync 0.90.4 required
|
||||
|
||||
* Do not show the warning icon in the tray (#944)
|
||||
* Fix manual proxy support when switching (#1016)
|
||||
* Add folder column to detailed sync protocol (#1037)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
set( MIRALL_VERSION_MAJOR 1 )
|
||||
set( MIRALL_VERSION_MINOR 5 )
|
||||
set( MIRALL_VERSION_PATCH 2 )
|
||||
set( MIRALL_VERSION_PATCH 3 )
|
||||
set( MIRALL_SOVERSION 0 )
|
||||
|
||||
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
|
||||
|
||||
+13
-14
@@ -2,18 +2,17 @@
|
||||
|
||||
[ "$#" -lt 2 ] && echo "Usage: sign_dmg.sh <dmg> <identity>" && exit
|
||||
|
||||
src_dmg=$1
|
||||
tmp_dmg=writable_$1
|
||||
signed_dmg=signed_$1
|
||||
identity=$2
|
||||
mount="/Volumes/$(basename $src_dmg|cut -d"-" -f1)"
|
||||
|
||||
test -e $tmp_dmg && rm -rf $tmp_dmg
|
||||
hdiutil convert $src_dmg -format UDRW -o $tmp_dmg
|
||||
hdiutil attach $tmp_dmg
|
||||
pushd $mount
|
||||
codesign -s "$identity" $mount/*.app
|
||||
src_dmg="$1"
|
||||
tmp_dmg="writable_$1"
|
||||
signed_dmg="signed_$1"
|
||||
identity="$2"
|
||||
mount="/Volumes/$(basename "$src_dmg"|sed 's,-\([0-9]\)\(.*\),,')"
|
||||
test -e "$tmp_dmg" && rm -rf "$tmp_dmg"
|
||||
hdiutil convert "$src_dmg" -format UDRW -o "$tmp_dmg"
|
||||
hdiutil attach "$tmp_dmg"
|
||||
pushd "$mount"
|
||||
codesign -s "$identity" "$mount"/*.app
|
||||
popd
|
||||
diskutil eject $mount
|
||||
test -e $signed_dmg && rm -rf $signed_dmg
|
||||
hdiutil convert $tmp_dmg -format UDBZ -o $signed_dmg
|
||||
diskutil eject "$mount"
|
||||
test -e "$signed_dmg" && rm -rf "$signed_dmg"
|
||||
hdiutil convert "$tmp_dmg" -format UDBZ -o "$signed_dmg"
|
||||
|
||||
@@ -33,6 +33,10 @@ if (UNIX)
|
||||
"${EXEC_INSTALL_PREFIX}/libexec"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is prefix/libexec)"
|
||||
)
|
||||
SET(LIB_PRIVATE_INSTALL_DIR
|
||||
"${LIB_INSTALL_DIR}/${APPLICATION_SHORT_NAME}"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where private libs are installed"
|
||||
)
|
||||
SET(PLUGIN_INSTALL_DIR
|
||||
"${LIB_INSTALL_DIR}/${APPLICATION_SHORT_NAME}"
|
||||
CACHE PATH "The subdirectory relative to the install prefix where plugins will be installed (default is prefix/lib/${APPLICATION_SHORT_NAME})"
|
||||
|
||||
@@ -37,11 +37,6 @@ if (HAVE_LIBDL)
|
||||
endif (HAVE_LIBDL)
|
||||
|
||||
check_function_exists(asprintf HAVE_ASPRINTF)
|
||||
if(NOT HAVE_ASPRINTF)
|
||||
if(MINGW)
|
||||
add_definitions( -D__USE_MINGW_ANSI_STDIO=1 )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_function_exists(fnmatch HAVE_FNMATCH)
|
||||
if(NOT HAVE_FNMATCH AND WIN32)
|
||||
|
||||
@@ -32,7 +32,6 @@ set(CSYNC_LIBRARY
|
||||
)
|
||||
|
||||
set(CSYNC_LINK_LIBRARIES
|
||||
${CSYNC_LIBRARY}
|
||||
${CSTDLIB_LIBRARY}
|
||||
${CSYNC_REQUIRED_LIBRARIES}
|
||||
${SQLITE3_LIBRARIES}
|
||||
@@ -100,8 +99,11 @@ include_directories(
|
||||
)
|
||||
|
||||
add_library(${CSYNC_LIBRARY} SHARED ${csync_SRCS})
|
||||
add_library(${CSYNC_LIBRARY}_static STATIC ${csync_SRCS})
|
||||
|
||||
target_link_libraries(${CSYNC_LIBRARY} ${CSYNC_LINK_LIBRARIES})
|
||||
target_link_libraries(${CSYNC_LIBRARY}_static ${CSYNC_LINK_LIBRARIES})
|
||||
|
||||
target_link_libraries(${CSYNC_LINK_LIBRARIES})
|
||||
|
||||
set_target_properties(
|
||||
${CSYNC_LIBRARY}
|
||||
@@ -116,9 +118,9 @@ INSTALL(
|
||||
TARGETS
|
||||
${CSYNC_LIBRARY}
|
||||
LIBRARY DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
${PLUGIN_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION
|
||||
${LIB_INSTALL_DIR}
|
||||
${PLUGIN_INSTALL_DIR}
|
||||
RUNTIME DESTINATION
|
||||
${BIN_INSTALL_DIR}
|
||||
)
|
||||
|
||||
@@ -480,13 +480,13 @@ static int dav_connect(const char *base_url) {
|
||||
DEBUG_WEBDAV("* port %u", port );
|
||||
DEBUG_WEBDAV("* path %s", path );
|
||||
|
||||
if( strcmp( scheme, "owncloud" ) == 0 ) {
|
||||
if( strcmp( scheme, "owncloud" ) == 0 || strcmp( scheme, "http" ) == 0 ) {
|
||||
strcpy( protocol, "http");
|
||||
} else if( strcmp( scheme, "ownclouds" ) == 0 ) {
|
||||
} else if( strcmp( scheme, "ownclouds" ) == 0 || strcmp( scheme, "https") == 0 ) {
|
||||
strcpy( protocol, "https");
|
||||
useSSL = 1;
|
||||
} else {
|
||||
DEBUG_WEBDAV("Invalid scheme %s, go outa here!", scheme );
|
||||
DEBUG_WEBDAV("Invalid scheme %s, go out here!", scheme );
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
@@ -497,15 +497,6 @@ static int dav_connect(const char *base_url) {
|
||||
port = ne_uri_defaultport(protocol);
|
||||
}
|
||||
|
||||
#if 0
|
||||
rc = ne_sock_init();
|
||||
DEBUG_WEBDAV("ne_sock_init: %d", rc );
|
||||
if (rc < 0) {
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
dav_session.ctx = ne_session_create( protocol, host, port);
|
||||
|
||||
if (dav_session.ctx == NULL) {
|
||||
@@ -979,7 +970,10 @@ static csync_vio_method_handle_t *owncloud_opendir(const char *uri) {
|
||||
|
||||
DEBUG_WEBDAV("opendir method called on %s", uri );
|
||||
|
||||
dav_connect( uri );
|
||||
if (dav_connect( uri ) < 0) {
|
||||
DEBUG_WEBDAV("connection failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
curi = _cleanPath( uri );
|
||||
if (is_first_propfind && !dav_session.no_recursive_propfind) {
|
||||
@@ -1081,11 +1075,6 @@ static int owncloud_commit() {
|
||||
SAFE_FREE( dav_session.session_key);
|
||||
SAFE_FREE( dav_session.error_string );
|
||||
|
||||
SAFE_FREE( dav_session.proxy_type );
|
||||
SAFE_FREE( dav_session.proxy_host );
|
||||
SAFE_FREE( dav_session.proxy_user );
|
||||
SAFE_FREE( dav_session.proxy_pwd );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+79
-40
@@ -85,18 +85,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/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
|
||||
@@ -118,18 +130,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/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)
|
||||
@@ -168,11 +192,11 @@ set(creds_HEADERS
|
||||
IF (NOT APPLE)
|
||||
INSTALL(
|
||||
FILES ${owncloudsync_HEADERS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/owncloudsync/mirall
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/${synclib_NAME}/mirall
|
||||
)
|
||||
INSTALL(
|
||||
FILES ${creds_HEADERS}
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/owncloudsync/creds
|
||||
DESTINATION ${INCLUDE_INSTALL_DIR}/${synclib_NAME}/creds
|
||||
)
|
||||
ENDIF(NOT APPLE)
|
||||
|
||||
@@ -199,15 +223,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}
|
||||
@@ -274,6 +305,8 @@ set(mirall_SRCS
|
||||
mirall/sslbutton.cpp
|
||||
)
|
||||
|
||||
|
||||
|
||||
set(mirall_HEADERS
|
||||
mirall/application.h
|
||||
mirall/systray.h
|
||||
@@ -368,14 +401,14 @@ 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} )
|
||||
string( REPLACE ".png" "" _res ${_res} )
|
||||
install( FILES ${_file} RENAME ${ICON_APP_NAME}.png DESTINATION ${DATADIR}/icons/hicolor/${_res}x${_res}/apps )
|
||||
endforeach( _file )
|
||||
endif(NOT WIN32)
|
||||
endif(NOT WIN32 AND NOT BUILD_LIBRARIES_ONLY)
|
||||
|
||||
install(FILES ${mirall_I18N} DESTINATION share/${APPLICATION_EXECUTABLE}/i18n)
|
||||
|
||||
@@ -384,7 +417,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()
|
||||
elseif(NOT BUILD_LIBRARIES_ONLY)
|
||||
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
include(DeployQt4)
|
||||
|
||||
@@ -407,25 +440,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} )
|
||||
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()
|
||||
|
||||
install(TARGETS ${APPLICATION_EXECUTABLE}
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
BUNDLE DESTINATION "."
|
||||
)
|
||||
|
||||
#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()
|
||||
|
||||
@@ -441,13 +477,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
|
||||
@@ -455,7 +494,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()
|
||||
elseif(NOT BUILD_LIBRARIES_ONLY)
|
||||
install(TARGETS ${owncloudcmd_NAME}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -94,8 +94,10 @@ private:
|
||||
HttpCredentials::HttpCredentials()
|
||||
: _user(),
|
||||
_password(),
|
||||
_ready(false)
|
||||
{}
|
||||
_ready(false),
|
||||
_fetchJobInProgress(false)
|
||||
{
|
||||
}
|
||||
|
||||
HttpCredentials::HttpCredentials(const QString& user, const QString& password)
|
||||
: _user(user),
|
||||
@@ -188,10 +190,11 @@ void HttpCredentials::fetch(Account *account)
|
||||
return;
|
||||
}
|
||||
|
||||
// User must be fetched from config file
|
||||
fetchUser(account);
|
||||
|
||||
QSettings *settings = account->settingsWithGroup(Theme::instance()->appName());
|
||||
QString kck = keychainKey(account->url().toString(), _user );
|
||||
const QString kck = keychainKey(account->url().toString(), _user );
|
||||
|
||||
QString key = QString::fromLatin1( "%1/data" ).arg( kck );
|
||||
if( settings && settings->contains(key) ) {
|
||||
@@ -199,7 +202,7 @@ void HttpCredentials::fetch(Account *account)
|
||||
// we do not want a security problem.
|
||||
settings->remove(key);
|
||||
key = QString::fromLatin1( "%1/type" ).arg( kck );
|
||||
settings->remove(kck);
|
||||
settings->remove(key);
|
||||
settings->sync();
|
||||
}
|
||||
|
||||
@@ -207,8 +210,11 @@ void HttpCredentials::fetch(Account *account)
|
||||
Q_EMIT fetched();
|
||||
} else {
|
||||
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
|
||||
settings->setParent(job); // make the job parent to make setting deleted properly
|
||||
job->setSettings(settings);
|
||||
|
||||
job->setInsecureFallback(false);
|
||||
job->setKey(keychainKey(account->url().toString(), _user));
|
||||
job->setKey(kck);
|
||||
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotReadJobDone(QKeychain::Job*)));
|
||||
job->setProperty("account", QVariant::fromValue(account));
|
||||
job->start();
|
||||
@@ -225,7 +231,6 @@ bool HttpCredentials::stillValid(QNetworkReply *reply)
|
||||
void HttpCredentials::slotReadJobDone(QKeychain::Job *job)
|
||||
{
|
||||
ReadPasswordJob *readJob = static_cast<ReadPasswordJob*>(job);
|
||||
delete readJob->settings();
|
||||
_password = readJob->textData();
|
||||
Account *account = qvariant_cast<Account*>(readJob->property("account"));
|
||||
|
||||
@@ -236,11 +241,12 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *job)
|
||||
QKeychain::Error error = job->error();
|
||||
|
||||
if( !_password.isEmpty() && error == NoError ) {
|
||||
_fetchJobInProgress = false;
|
||||
|
||||
// All cool, the keychain did not come back with error.
|
||||
// Still, the password can be empty which indicates a problem and
|
||||
// the password dialog has to be opened.
|
||||
_ready = true;
|
||||
_fetchJobInProgress = false;
|
||||
emit fetched();
|
||||
} else {
|
||||
if( error != NoError ) {
|
||||
@@ -260,13 +266,11 @@ void HttpCredentials::slotReadJobDone(QKeychain::Job *job)
|
||||
|
||||
QString HttpCredentials::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();
|
||||
@@ -276,19 +280,40 @@ QString HttpCredentials::queryPassword(bool *ok)
|
||||
void HttpCredentials::invalidateToken(Account *account)
|
||||
{
|
||||
_password = QString();
|
||||
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
|
||||
job->setSettings(account->settingsWithGroup(Theme::instance()->appName()));
|
||||
job->setInsecureFallback(true);
|
||||
connect(job, SIGNAL(destroyed(QObject*)), job->settings(), SLOT(deleteLater()));
|
||||
job->setKey(keychainKey(account->url().toString(), _user));
|
||||
job->start();
|
||||
_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;
|
||||
}
|
||||
|
||||
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
|
||||
QSettings *settings = account->settingsWithGroup(Theme::instance()->appName());
|
||||
settings->setParent(job); // make the job parent to make setting deleted properly
|
||||
job->setSettings(settings);
|
||||
job->setInsecureFallback(true);
|
||||
job->setKey(kck);
|
||||
job->start();
|
||||
|
||||
account->clearCookieJar();
|
||||
}
|
||||
|
||||
void HttpCredentials::persist(Account *account)
|
||||
{
|
||||
if (_user.isEmpty()) {
|
||||
// We never connected or fetched the user, there is nothing to save.
|
||||
return;
|
||||
}
|
||||
account->setCredentialSetting(QLatin1String(userC), _user);
|
||||
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
|
||||
QSettings *settings = account->settingsWithGroup(Theme::instance()->appName());
|
||||
settings->setParent(job); // make the job parent to make setting deleted properly
|
||||
job->setSettings(settings);
|
||||
|
||||
job->setInsecureFallback(false);
|
||||
connect(job, SIGNAL(finished(QKeychain::Job*)), SLOT(slotWriteJobDone(QKeychain::Job*)));
|
||||
job->setKey(keychainKey(account->url().toString(), _user));
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2014 by Daniel Molkentin <danimo@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; version 2 of the License.
|
||||
*
|
||||
* 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 "authenticationdialog.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QVBoxLayout>
|
||||
#include <QFormLayout>
|
||||
#include <QDialogButtonBox>
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
AuthenticationDialog::AuthenticationDialog(const QString &realm, const QString &domain, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, _user(new QLineEdit)
|
||||
, _password(new QLineEdit)
|
||||
{
|
||||
setWindowTitle(tr("Authentication Required"));
|
||||
QVBoxLayout *lay = new QVBoxLayout(this);
|
||||
QLabel *label = new QLabel(tr("Enter username and password for '%1' at %2.").arg(realm, domain));
|
||||
lay->addWidget(label);
|
||||
|
||||
QFormLayout *form = new QFormLayout;
|
||||
form->addRow(tr("&User:"), _user);
|
||||
form->addRow(tr("&Password:"), _password);
|
||||
lay->addLayout(form);
|
||||
_password->setEchoMode(QLineEdit::Password);
|
||||
|
||||
QDialogButtonBox *box = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel, Qt::Horizontal);
|
||||
connect(box, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(box, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
lay->addWidget(box);
|
||||
}
|
||||
|
||||
QString AuthenticationDialog::user() const
|
||||
{
|
||||
return _user->text();
|
||||
}
|
||||
|
||||
QString AuthenticationDialog::password() const
|
||||
{
|
||||
return _password->text();
|
||||
}
|
||||
|
||||
} // namespace Mirall
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2014 by Daniel Molkentin <danimo@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; version 2 of the License.
|
||||
*
|
||||
* 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_AUTHENTICATIONDIALOG_H
|
||||
#define MIRALL_AUTHENTICATIONDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
/** @brief Authenticate a user for a specific credential given his credentials */
|
||||
class AuthenticationDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AuthenticationDialog(const QString &realm, const QString &domain, QWidget *parent = 0);
|
||||
|
||||
QString user() const;
|
||||
QString password() const;
|
||||
|
||||
private:
|
||||
QLineEdit *_user;
|
||||
QLineEdit *_password;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace Mirall
|
||||
|
||||
#endif // MIRALL_AUTHENTICATIONDIALOG_H
|
||||
@@ -17,9 +17,12 @@
|
||||
#include <QWebFrame>
|
||||
#include <QWebPage>
|
||||
#include <QMessageBox>
|
||||
#include <QAuthenticator>
|
||||
#include <QNetworkReply>
|
||||
|
||||
#include "creds/shibboleth/shibbolethcookiejar.h"
|
||||
#include "creds/shibboleth/shibbolethwebview.h"
|
||||
#include "creds/shibboleth/authenticationdialog.h"
|
||||
#include "mirall/account.h"
|
||||
#include "mirall/mirallaccessmanager.h"
|
||||
#include "mirall/theme.h"
|
||||
@@ -35,6 +38,8 @@ void ShibbolethWebView::setup(Account *account, ShibbolethCookieJar* jar)
|
||||
// the account object, which already can do this
|
||||
connect(nm, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
|
||||
account, SLOT(slotHandleErrors(QNetworkReply*,QList<QSslError>)));
|
||||
connect(nm, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
|
||||
SLOT(slotHandleAuthentication(QNetworkReply*,QAuthenticator*)));
|
||||
|
||||
QWebPage* page = new QWebPage(this);
|
||||
|
||||
@@ -115,11 +120,26 @@ void ShibbolethWebView::slotLoadFinished(bool success)
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
QMessageBox::critical(this, tr("Error loading IdP login page"),
|
||||
tr("Could not load Shibboleth login page to log you in.\n"
|
||||
"Please ensure that your network connection is working."));
|
||||
qDebug() << Q_FUNC_INFO << "Could not load Shibboleth login page to log you in.";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ShibbolethWebView::slotHandleAuthentication(QNetworkReply *reply, QAuthenticator *authenticator)
|
||||
{
|
||||
Q_UNUSED(reply)
|
||||
QUrl url = reply->url();
|
||||
// show only scheme, host and port
|
||||
QUrl reducedUrl;
|
||||
reducedUrl.setScheme(url.scheme());
|
||||
reducedUrl.setHost(url.host());
|
||||
reducedUrl.setPort(url.port());
|
||||
|
||||
AuthenticationDialog dialog(authenticator->realm(), reducedUrl.toString(), this);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
authenticator->setUser(dialog.user());
|
||||
authenticator->setPassword(dialog.password());
|
||||
}
|
||||
}
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
@@ -48,6 +48,7 @@ private Q_SLOTS:
|
||||
void onNewCookiesForUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url);
|
||||
void slotLoadStarted();
|
||||
void slotLoadFinished(bool success = true);
|
||||
void slotHandleAuthentication(QNetworkReply*,QAuthenticator*);
|
||||
|
||||
private:
|
||||
void setup(Account *account, ShibbolethCookieJar* jar);
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (C) by Klaas Freitag <freitag@kde.org>
|
||||
* Copyright (c) by Markus Goetz <guruz@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
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) by Klaas Freitag <freitag@kde.org>
|
||||
* Copyright (c) by Markus Goetz <guruz@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
|
||||
@@ -183,6 +183,11 @@ QList<QNetworkCookie> Account::lastAuthCookies() const
|
||||
return _am->cookieJar()->cookiesForUrl(_url);
|
||||
}
|
||||
|
||||
void Account::clearCookieJar()
|
||||
{
|
||||
_am->setCookieJar(new QNetworkCookieJar);
|
||||
}
|
||||
|
||||
QNetworkReply *Account::headRequest(const QString &relPath)
|
||||
{
|
||||
return headRequest(concatUrlPath(url(), relPath));
|
||||
|
||||
@@ -144,6 +144,8 @@ public:
|
||||
int state() const;
|
||||
void setState(int state);
|
||||
|
||||
void clearCookieJar();
|
||||
|
||||
QuotaInfo *quotaInfo();
|
||||
signals:
|
||||
void stateChanged(int state);
|
||||
|
||||
@@ -232,15 +232,13 @@ void Application::slotCheckConnection()
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractCredentials* credentials(account->credentials());
|
||||
if (_conValidator)
|
||||
_conValidator->deleteLater();
|
||||
_conValidator = new ConnectionValidator(account);
|
||||
connect( _conValidator, SIGNAL(connectionResult(ConnectionValidator::Status)),
|
||||
this, SLOT(slotConnectionValidatorResult(ConnectionValidator::Status)) );
|
||||
_conValidator->checkConnection();
|
||||
|
||||
if (! credentials->ready()) {
|
||||
connect( credentials, SIGNAL(fetched()),
|
||||
this, SLOT(slotCredentialsFetched()), Qt::UniqueConnection);
|
||||
credentials->fetch(account);
|
||||
} else {
|
||||
slotCredentialsFetched();
|
||||
}
|
||||
} else {
|
||||
// let gui open the setup wizard
|
||||
_gui->slotOpenSettingsDialog( true );
|
||||
@@ -261,13 +259,7 @@ void Application::slotCredentialsFetched()
|
||||
// Then we ask again for the credidentials if they are wrong again
|
||||
account->setState(Account::Disconnected);
|
||||
}
|
||||
|
||||
if (_conValidator)
|
||||
_conValidator->deleteLater();
|
||||
_conValidator = new ConnectionValidator(account);
|
||||
connect( _conValidator, SIGNAL(connectionResult(ConnectionValidator::Status)),
|
||||
this, SLOT(slotConnectionValidatorResult(ConnectionValidator::Status)) );
|
||||
_conValidator->checkConnection();
|
||||
slotCheckConnection();
|
||||
}
|
||||
|
||||
void Application::slotToggleFolderman(int state)
|
||||
@@ -299,10 +291,6 @@ void Application::slotConnectionValidatorResult(ConnectionValidator::Status stat
|
||||
folderMan->setSyncEnabled(true);
|
||||
// queue up the sync for all folders.
|
||||
folderMan->slotScheduleAllFolders();
|
||||
if(!_connectionMsgBox.isNull()) {
|
||||
_connectionMsgBox->close();
|
||||
}
|
||||
|
||||
} else {
|
||||
// if we have problems here, it's unlikely that syncing will work.
|
||||
FolderMan::instance()->setSyncEnabled(false);
|
||||
@@ -310,13 +298,7 @@ void Application::slotConnectionValidatorResult(ConnectionValidator::Status stat
|
||||
startupFails = _conValidator->errors();
|
||||
_startupNetworkError = _conValidator->networkError();
|
||||
if (_userTriggeredConnect) {
|
||||
if(_connectionMsgBox.isNull()) {
|
||||
_connectionMsgBox = new QMessageBox(QMessageBox::Warning, tr("Connection failed"),
|
||||
_conValidator->errors().join(". ").append('.'), QMessageBox::Ok, 0);
|
||||
_connectionMsgBox->setAttribute(Qt::WA_DeleteOnClose);
|
||||
_connectionMsgBox->open();
|
||||
_userTriggeredConnect = false;
|
||||
}
|
||||
_userTriggeredConnect = false;
|
||||
}
|
||||
QTimer::singleShot(30*1000, this, SLOT(slotCheckConnection()));
|
||||
}
|
||||
|
||||
@@ -100,7 +100,6 @@ private:
|
||||
int _logExpire;
|
||||
bool _logFlush;
|
||||
bool _userTriggeredConnect;
|
||||
QPointer<QMessageBox> _connectionMsgBox;
|
||||
|
||||
ClientProxy _proxy;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "mirall/theme.h"
|
||||
#include "mirall/account.h"
|
||||
#include "mirall/networkjobs.h"
|
||||
#include <creds/abstractcredentials.h>
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
@@ -108,7 +109,14 @@ void ConnectionValidator::slotStatusFound(const QUrl&url, const QVariantMap &inf
|
||||
return;
|
||||
}
|
||||
|
||||
QTimer::singleShot( 0, this, SLOT( slotCheckAuthentication() ));
|
||||
AbstractCredentials *creds = _account->credentials();
|
||||
if (creds->ready()) {
|
||||
QTimer::singleShot( 0, this, SLOT( slotCheckAuthentication() ));
|
||||
} else {
|
||||
connect( creds, SIGNAL(fetched()),
|
||||
this, SLOT(slotCheckAuthentication()), Qt::UniqueConnection);
|
||||
creds->fetch(_account);
|
||||
}
|
||||
}
|
||||
|
||||
// status.php could not be loaded.
|
||||
@@ -126,6 +134,9 @@ void ConnectionValidator::slotNoStatusFound(QNetworkReply *reply)
|
||||
|
||||
void ConnectionValidator::slotCheckAuthentication()
|
||||
{
|
||||
AbstractCredentials *creds = _account->credentials();
|
||||
disconnect( creds, SIGNAL(fetched()),
|
||||
this, SLOT(slotCheckAuthentication()));
|
||||
// simply GET the webdav root, will fail if credentials are wrong.
|
||||
// continue in slotAuthCheck here :-)
|
||||
PropfindJob *job = new PropfindJob(_account, "/", this);
|
||||
|
||||
@@ -335,6 +335,7 @@ int CSyncThread::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
// No need to do anything.
|
||||
_hasFiles = true;
|
||||
|
||||
emit syncItemDisconvered(item);
|
||||
return re;
|
||||
}
|
||||
break;
|
||||
@@ -375,6 +376,7 @@ int CSyncThread::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||
}
|
||||
_syncedItems.append(item);
|
||||
|
||||
emit syncItemDisconvered(item);
|
||||
return re;
|
||||
}
|
||||
|
||||
@@ -488,8 +490,6 @@ void CSyncThread::startSync()
|
||||
// }
|
||||
|
||||
// csync_set_auth_callback( _csync_ctx, getauth );
|
||||
csync_set_log_callback( csyncLogCatcher );
|
||||
csync_set_log_level( 11 );
|
||||
|
||||
_syncTime.start();
|
||||
|
||||
|
||||
@@ -62,6 +62,11 @@ signals:
|
||||
void csyncError( const QString& );
|
||||
void csyncWarning( const QString& );
|
||||
void csyncUnavailable();
|
||||
|
||||
// before actual syncing (after update+reconcile)
|
||||
void syncItemDisconvered(const SyncFileItem&);
|
||||
|
||||
// after sync is done
|
||||
void treeWalkResult(const SyncFileItemVector&);
|
||||
|
||||
void transmissionProgress( const Progress::Info& progress );
|
||||
|
||||
@@ -537,14 +537,17 @@ void FolderMan::removeFolder( const QString& alias )
|
||||
if( _folderMap.contains( alias )) {
|
||||
qDebug() << "Removing " << alias;
|
||||
f = _folderMap.take( alias );
|
||||
if(f) {
|
||||
f->wipe();
|
||||
}
|
||||
} else {
|
||||
qDebug() << "!! Can not remove " << alias << ", not in folderMap.";
|
||||
}
|
||||
|
||||
if( f ) {
|
||||
f->wipe();
|
||||
|
||||
// can be removed if we are able to delete the folder object.
|
||||
f->setSyncEnabled(false);
|
||||
|
||||
// remove the folder configuration
|
||||
QFile file( _folderConfigPath + QLatin1Char('/') + f->configFile() );
|
||||
if( file.exists() ) {
|
||||
qDebug() << "Remove folder config file " << file.fileName();
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
#include <QObject>
|
||||
#include <QVarLengthArray>
|
||||
|
||||
namespace Mirall {
|
||||
|
||||
@@ -129,13 +130,10 @@ void FolderWatcherPrivate::slotReceivedNotification(int fd)
|
||||
struct inotify_event* event;
|
||||
int i;
|
||||
int error;
|
||||
char *buffer = NULL;
|
||||
int buf_size = 2048;
|
||||
|
||||
buffer = (char*) malloc(buf_size);
|
||||
QVarLengthArray<char, 2048> buffer(2048);
|
||||
|
||||
do {
|
||||
len = read(fd, buffer, buf_size);
|
||||
len = read(fd, buffer.data(), buffer.size());
|
||||
error = errno;
|
||||
/**
|
||||
* From inotify documentation:
|
||||
@@ -149,8 +147,7 @@ void FolderWatcherPrivate::slotReceivedNotification(int fd)
|
||||
if (len < 0 && error == EINVAL)
|
||||
{
|
||||
// double the buffer size
|
||||
buf_size *= 2;
|
||||
buffer = (char *) realloc(buffer, buf_size);
|
||||
buffer.resize(buffer.size() * 2);
|
||||
/* and try again ... */
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkProxy>
|
||||
#include <QAuthenticator>
|
||||
|
||||
#include "mirall/mirallaccessmanager.h"
|
||||
#include "mirall/utility.h"
|
||||
@@ -29,6 +30,8 @@ MirallAccessManager::MirallAccessManager(QObject* parent)
|
||||
proxy.setHostName(" ");
|
||||
setProxy(proxy);
|
||||
#endif
|
||||
QObject::connect(this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
|
||||
this, SLOT(slotProxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
|
||||
}
|
||||
|
||||
QNetworkReply* MirallAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest& request, QIODevice* outgoingData)
|
||||
@@ -44,4 +47,15 @@ QNetworkReply* MirallAccessManager::createRequest(QNetworkAccessManager::Operati
|
||||
return QNetworkAccessManager::createRequest(op, newRequest, outgoingData);
|
||||
}
|
||||
|
||||
void MirallAccessManager::slotProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
|
||||
{
|
||||
Q_UNUSED(authenticator);
|
||||
qDebug() << Q_FUNC_INFO << proxy.type();
|
||||
// We put in the password here and in ClientProxy in the proxy itself.
|
||||
if (!proxy.user().isEmpty() || !proxy.password().isEmpty()) {
|
||||
authenticator->setUser(proxy.user());
|
||||
authenticator->setPassword(proxy.password());
|
||||
}
|
||||
}
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
@@ -28,6 +28,8 @@ public:
|
||||
|
||||
protected:
|
||||
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest& request, QIODevice* outgoingData = 0);
|
||||
protected slots:
|
||||
void slotProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
|
||||
};
|
||||
|
||||
} // ns Mirall
|
||||
|
||||
@@ -139,6 +139,9 @@ void AbstractNetworkJob::slotFinished()
|
||||
{
|
||||
if( _reply->error() != QNetworkReply::NoError ) {
|
||||
qDebug() << Q_FUNC_INFO << _reply->error() << _reply->errorString();
|
||||
if (_reply->error() == QNetworkReply::ProxyAuthenticationRequiredError) {
|
||||
qDebug() << Q_FUNC_INFO << _reply->rawHeader("Proxy-Authenticate");
|
||||
}
|
||||
emit networkError(_reply);
|
||||
}
|
||||
finished();
|
||||
@@ -151,7 +154,11 @@ void AbstractNetworkJob::slotFinished()
|
||||
// but try to re-sign in.
|
||||
connect( creds, SIGNAL(fetched()),
|
||||
qApp, SLOT(slotCredentialsFetched()), Qt::UniqueConnection);
|
||||
creds->invalidateAndFetch(_account); // this triggers Application::runValidator when the credidentials are fetched
|
||||
if (creds->ready()) {
|
||||
creds->invalidateAndFetch(_account);
|
||||
} else {
|
||||
creds->fetch(_account);
|
||||
}
|
||||
}
|
||||
deleteLater();
|
||||
}
|
||||
@@ -307,6 +314,7 @@ CheckServerJob::CheckServerJob(Account *account, bool followRedirect, QObject *p
|
||||
, _followRedirects(followRedirect)
|
||||
, _redirectCount(0)
|
||||
{
|
||||
setIgnoreCredentialFailure(true);
|
||||
}
|
||||
|
||||
void CheckServerJob::start()
|
||||
@@ -523,9 +531,11 @@ void CheckQuotaJob::finished()
|
||||
reader.namespaceUri() == QLatin1String("DAV:")) {
|
||||
QString name = reader.name().toString();
|
||||
if (name == QLatin1String("quota-available-bytes")) {
|
||||
quotaAvailableBytes = reader.readElementText().toLongLong();
|
||||
// I have seen the server returning frational bytes:
|
||||
// <d:quota-available-bytes>1374532061.2</d:quota-available-bytes>
|
||||
quotaAvailableBytes = reader.readElementText().toDouble();
|
||||
} else if (name == QLatin1String("quota-used-bytes")) {
|
||||
quotaUsedBytes = reader.readElementText().toLongLong();
|
||||
quotaUsedBytes = reader.readElementText().toDouble();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+153
-129
@@ -14,7 +14,7 @@
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="proxyGroupBox">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
@@ -177,151 +177,175 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Download Bandwidth</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="downloadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>Limit to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="downloadSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>80</number>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Download Bandwidth</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="downloadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>Limit to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="downloadSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>80</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>KBytes/s</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="noDownloadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>KBytes/s</string>
|
||||
<string>No limit</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>147</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>147</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="noDownloadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>No limit</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Upload Bandwidth</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="noUploadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>No limit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="autoUploadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>Limit automatically</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="uploadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>Limit to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="uploadSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Upload Bandwidth</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="uploadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>Limit to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="autoUploadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>KBytes/s</string>
|
||||
<string>Limit automatically</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="noUploadLimitRadioButton">
|
||||
<property name="text">
|
||||
<string>No limit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="uploadSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>KBytes/s</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>autoUploadLimitRadioButton</zorder>
|
||||
<zorder>uploadLimitRadioButton</zorder>
|
||||
<zorder>noUploadLimitRadioButton</zorder>
|
||||
</widget>
|
||||
<zorder>autoUploadLimitRadioButton</zorder>
|
||||
<zorder>uploadLimitRadioButton</zorder>
|
||||
<zorder>noUploadLimitRadioButton</zorder>
|
||||
<zorder>horizontalSpacer_2</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="2" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
|
||||
@@ -122,6 +122,10 @@ bool PropagateItemJob::checkForProblemsWithShared(const QString& msg)
|
||||
} else if (downloadItem._instruction == CSYNC_INSTRUCTION_SYNC) {
|
||||
// we modified the file locally, jsut create a conflict then
|
||||
downloadItem._instruction = CSYNC_INSTRUCTION_CONFLICT;
|
||||
|
||||
// HACK to avoid continuation: See task #1448: We do not know the _modtime from the
|
||||
// server, at this point, so just set the current one. (rather than the one locally)
|
||||
downloadItem._modtime = Utility::qDateTimeToTime_t(QDateTime::currentDateTime());
|
||||
} else {
|
||||
// the file was removed or renamed, just recover the old one
|
||||
downloadItem._instruction = CSYNC_INSTRUCTION_SYNC;
|
||||
|
||||
@@ -52,10 +52,10 @@ void QuotaInfo::slotAccountStateChanged(int state)
|
||||
switch (state) {
|
||||
case Account::SignedOut: // fall through
|
||||
case Account::InvalidCredidential:
|
||||
case Account::Disconnected:
|
||||
_jobRestartTimer->stop();
|
||||
break;
|
||||
case Account::Connected: // fall through
|
||||
case Account::Disconnected:
|
||||
slotCheckQuota();
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,8 @@ void QuotaInfo::slotRequestFailed()
|
||||
|
||||
void QuotaInfo::slotCheckQuota()
|
||||
{
|
||||
if (!_account.isNull() && _account->credentials() && _account->credentials()->ready()) {
|
||||
if (!_account.isNull() && _account->state() == Account::Connected
|
||||
&& _account->credentials() && _account->credentials()->ready()) {
|
||||
CheckQuotaJob *job = new CheckQuotaJob(_account, "/", this);
|
||||
connect(job, SIGNAL(quotaRetrieved(qint64,qint64)), SLOT(slotUpdateLastQuota(qint64,qint64)));
|
||||
connect(job, SIGNAL(networkError(QNetworkReply*)), SLOT(slotRequestFailed()));
|
||||
|
||||
@@ -26,17 +26,30 @@ static void setupFavLink_private(const QString &folder) {
|
||||
}
|
||||
}
|
||||
|
||||
// returns the autostart directory the linux way
|
||||
// and respects the XDG_CONFIG_HOME env variable
|
||||
// can be replaces for qt5 with QStandardPaths
|
||||
QString getUserAutostartDir_private()
|
||||
{
|
||||
QString config = QLatin1String(qgetenv("XDG_CONFIG_HOME"));
|
||||
|
||||
if (config.isEmpty()) {
|
||||
config = QDir::homePath()+QLatin1String("/.config");
|
||||
}
|
||||
config += QLatin1String("/autostart/");
|
||||
return config;
|
||||
}
|
||||
|
||||
bool hasLaunchOnStartup_private(const QString &appName)
|
||||
{
|
||||
QString userAutoStartPath = QDir::homePath()+QLatin1String("/.config/autostart/");
|
||||
QString desktopFileLocation = userAutoStartPath+appName+QLatin1String(".desktop");
|
||||
QString desktopFileLocation = getUserAutostartDir_private()+appName+QLatin1String(".desktop");
|
||||
return QFile::exists(desktopFileLocation);
|
||||
}
|
||||
|
||||
|
||||
void setLaunchOnStartup_private(const QString &appName, const QString& guiName, bool enable)
|
||||
{
|
||||
QString userAutoStartPath = QDir::homePath()+QLatin1String("/.config/autostart/");
|
||||
QString userAutoStartPath = getUserAutostartDir_private();
|
||||
QString desktopFileLocation = userAutoStartPath+appName+QLatin1String(".desktop");
|
||||
if (enable) {
|
||||
if (!QDir().exists(userAutoStartPath) && !QDir().mkdir(userAutoStartPath)) {
|
||||
|
||||
@@ -126,6 +126,7 @@ int main(int argc, char **argv) {
|
||||
qFatal("ne_sock_init failed!");
|
||||
}
|
||||
|
||||
csync_set_log_callback( csyncLogCatcher );
|
||||
csync_set_log_level(11);
|
||||
csync_enable_conflictcopys(_csync_ctx);
|
||||
Logger::instance()->setLogFile("-");
|
||||
@@ -177,7 +178,10 @@ int main(int argc, char **argv) {
|
||||
SyncJournalDb db(options.source_dir);
|
||||
CSyncThread csyncthread(_csync_ctx, options.source_dir, QUrl(options.target_url).path(), &db);
|
||||
QObject::connect(&csyncthread, SIGNAL(finished()), &app, SLOT(quit()));
|
||||
csyncthread.startSync();
|
||||
|
||||
// Have to be done async, else, an error while updating does not terminate the event loop.
|
||||
QMetaObject::invokeMethod(&csyncthread, "startSync", Qt::QueuedConnection);
|
||||
|
||||
|
||||
app.exec();
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ void OwncloudShibbolethCredsPage::setupBrowser()
|
||||
connect(_browser, SIGNAL(otherCookiesReceived(QList<QNetworkCookie>, QUrl)),
|
||||
this, SLOT(slotOtherCookiesReceived(QList<QNetworkCookie>, QUrl)));
|
||||
|
||||
_browser->move(ocWizard->x(), ocWizard->y());
|
||||
_browser->show();
|
||||
_browser->setFocus();
|
||||
}
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário