Comparar commits

...

49 Commits

Autor SHA1 Mensagem Data
Klaas Freitag 08dd9796d1 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)
2014-04-04 10:50:40 +02:00
Sandro Knauß 47274f1075 Merge remote-tracking branch 'respect-XDG_CONFIG_HOME' into 1.5 2014-03-21 17:20:15 +01:00
Markus Goetz f72e1cc837 Log: Don't override level for csync
The level shall be set from Folder or owncloudCmd only.
2014-03-21 13:52:35 +01:00
Olivier Goffart 8aace3284f owncloudcmd: Fix an error during update phase would not terminate
the QApplication::quit()  would be run before the exec() and would
be a noop,   and then exec would just wait forever.
2014-03-21 10:03:11 +01:00
Olivier Goffart 922e004fc6 Make it an error instead of a crash when dav_connect fails.
Fixes #1591
2014-03-21 09:54:26 +01:00
Klaas Freitag 9d1208baa4 Also allow http and https protocols. 2014-03-18 17:10:03 +01:00
Klaas Freitag 8e914deb99 Revert "Do not rely on the url scheme owncloud(s) any more."
This reverts commit 34dd3b207e.
It can be implemented simpler.
2014-03-18 16:57:01 +01:00
Klaas Freitag 34dd3b207e Do not rely on the url scheme owncloud(s) any more.
If it is not owncloud or ownclouds, rely on the scheme
that was given by the user.
2014-03-18 14:16:50 +01:00
Klaas Freitag 68e8d659fb Remove unused code. 2014-03-18 14:16:06 +01:00
Olivier Goffart 5c45ede4a5 Read the quota as double
The server is sending floating point number when the amount of storage
is set to a custom number (say 1.2GB)

This should fix #1374
2014-03-17 10:37:06 +01:00
Olivier Goffart cabcdd890e Only run the CheckQuota job if the account is connected
We use another job to check the connection.
And this may cause wrong password failure as we are still in the wizzard

Fixes #1567
2014-03-17 10:35:43 +01:00
Olivier Goffart 0a5e691ba3 Remove debug output that might cause a crash
The account may not be finilized when this is called while the
wizzard is still running on first connection
2014-03-17 10:22:14 +01:00
Olivier Goffart ba300c2fc1 Fix memory leak: Don't use raw pointers 2014-03-17 10:04:42 +01:00
Markus Goetz 07904e078a CSyncThread: Emit a signal for each file before propagate
This can be used to display info before the sync is happening
2014-03-14 14:08:32 +01:00
Markus Goetz d5fd6309ed CMake: Fix target_link_libraries parameters 2014-03-12 15:03:11 +01:00
Markus Goetz a2467b5dea CMake: Do options one directory above
This fixes linking when keychain was not desired.
2014-03-12 14:20:38 +01:00
Markus Goetz 0bbcee7354 CMake: Fix else 2014-03-11 17:56:29 +01:00
Markus Goetz 8a18cf811e CMake: Fix warning 2014-03-11 17:33:45 +01:00
Markus Goetz 4e7e25c569 Improve libowncloudsync
* Introduce TokenCredentials
* Introduce static compiling
* Have compile flags for smaller compile
2014-03-11 17:05:44 +01:00
Markus Goetz c24c97703a CMake: Ignore failure when working as submodule 2014-03-11 17:05:44 +01:00
Klaas Freitag aa4e90acfc Put ocsync to a private library - WIP 2014-03-11 10:18:07 +01:00
Klaas Freitag c8a8eb35fa Disable the folder if it is going to be removed. 2014-03-10 12:22:06 +01:00
Daniel Molkentin 2656cc70d1 1.5.3 final 2014-03-10 10:15:50 +01:00
Klaas Freitag 8bf2c54b56 Install include dirs app name aware. 2014-03-07 13:05:17 +01:00
Markus Goetz 630f61142a Proxy: Try to fix issue
See https://github.com/owncloud/mirall/commit/eb7074e9f088214648183a45c2ce806f65a8bf3c for discussion
2014-03-06 17:48:18 +01:00
Klaas Freitag f348499bbe For Windows, add the __USE_MINGW_ANSI_STDIO=1 switch 2014-03-05 15:39:49 +01:00
Klaas Freitag 7a3abac833 Bump version to 1.5.3rc1 2014-03-05 10:49:58 +01:00
Markus Goetz eb7074e9f0 csync: Don't free proxy settings on commit
Should fix #1502 and #1524
and #1459 and #1521
2014-03-04 18:44:52 +01:00
Klaas Freitag 66b152ac69 Remove left over member variables. 2014-03-03 18:12:12 +01:00
Olivier Goffart 6df00ad08c Only removes the password from the credidentials if it has been fetched before
Also only run the propfind job if the credidentials are readon, and fetch them
otherwise
2014-03-03 17:55:15 +01:00
Olivier Goffart 76b24ff00d Revert "Do not wipe the credentials from config for reconnect."
This reverts commit 9eb3452a71.

We need that or wrong password can never be changed
2014-03-03 17:21:20 +01:00
Olivier Goffart 60a1d50ec9 Keep the rentrency flag when asking the user for the password 2014-03-03 17:16:57 +01:00
Klaas Freitag 9eb3452a71 Do not wipe the credentials from config for reconnect.
This should fix bug #1491
2014-03-03 16:39:38 +01:00
Klaas Freitag 228de7eede Make the CheckServerJob ignoring credential fails. 2014-03-03 16:37:29 +01:00
Klaas Freitag 2164f5d9b7 Remove a superflous MessageBox. User is asked for Password instead. 2014-03-03 16:36:59 +01:00
Klaas Freitag 4240010046 Add method clearCookieJar which wipes QNAMs cookies. 2014-03-03 16:36:30 +01:00
Klaas Freitag 1eb0875518 Use the mirall config file for all Keychain jobs.
Also set the job as parent to get proper deletion of the
settings object.
2014-03-03 16:35:57 +01:00
Klaas Freitag b8e52304bd Do proper initialization of _fetchJobInProgress.
That confused win32, since this flag was true very often.
2014-03-03 16:33:59 +01:00
Olivier Goffart 0658802048 Fix layout of the network tab
Fixes #1491
2014-02-28 13:17:04 +01:00
Olivier Goffart eeb68919bf Do not erase the username and password from the config if we never connected
If we never fetched the credidentials, the _user and _password will be empty,
we should therefore not try to save them because it would just erase them.

Version 1.5.2 always try to fetch the creds at startup.  But now we only
do it if we detect an internet connection
2014-02-28 12:51:06 +01:00
Olivier Goffart 9a60732542 Do not erase the full account config if an old version of the client stored the password 2014-02-28 12:51:06 +01:00
Daniel Molkentin f8d996258e OS X: Make script more even robust 2014-02-28 11:16:25 +01:00
Daniel Molkentin c8714be1d2 mac os sign script: quote all params 2014-02-28 10:23:02 +01:00
Daniel Molkentin 36cd9d9ced Shibboleth: Move browser window to the offset of the setup wizard 2014-02-27 17:07:59 +01:00
Daniel Molkentin 9c70ee68d2 Mask password lineedit 2014-02-27 17:07:59 +01:00
Olivier Goffart e809a59049 Remove spurious error message.
Sometimes 'success' is false without apparent reason.
Just remove the message
2014-02-27 17:03:42 +01:00
Daniel Molkentin 33ae2eb19f Try to handle auth requests by a Shibboleth IdP 2014-02-27 13:18:53 +01:00
Olivier Goffart d4fa955950 Don't fetch credidentials from application.cpp
They will be fetched by the connection validator after doing
the status.php check
2014-02-27 13:06:29 +01:00
hefee 4e0496f74d respect XDG_CONFIG_HOME for getting user config dir.
Under linux the XDG Base Directory Specification define different
enviroment variables where to store what.
2013-12-31 02:10:44 +01:00
35 arquivos alterados com 879 adições e 285 exclusões
+24 -2
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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})"
-5
Ver Arquivo
@@ -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)
+6 -4
Ver Arquivo
@@ -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}
)
+7 -18
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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}
+9
Ver Arquivo
@@ -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
+40 -15
Ver Arquivo
@@ -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
+41
Ver Arquivo
@@ -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
+23 -3
Ver Arquivo
@@ -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
+1
Ver Arquivo
@@ -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);
+240
Ver Arquivo
@@ -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
+67
Ver Arquivo
@@ -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
+5
Ver Arquivo
@@ -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));
+2
Ver Arquivo
@@ -144,6 +144,8 @@ public:
int state() const;
void setState(int state);
void clearCookieJar();
QuotaInfo *quotaInfo();
signals:
void stateChanged(int state);
+8 -26
Ver Arquivo
@@ -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()));
}
-1
Ver Arquivo
@@ -100,7 +100,6 @@ private:
int _logExpire;
bool _logFlush;
bool _userTriggeredConnect;
QPointer<QMessageBox> _connectionMsgBox;
ClientProxy _proxy;
+12 -1
Ver Arquivo
@@ -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);
+2 -2
Ver Arquivo
@@ -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();
+5
Ver Arquivo
@@ -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 );
+6 -3
Ver Arquivo
@@ -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();
+4 -7
Ver Arquivo
@@ -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;
}
+14
Ver Arquivo
@@ -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
+2
Ver Arquivo
@@ -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
+13 -3
Ver Arquivo
@@ -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
Ver Arquivo
@@ -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>
+4
Ver Arquivo
@@ -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;
+3 -2
Ver Arquivo
@@ -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()));
+16 -3
Ver Arquivo
@@ -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)) {
+5 -1
Ver Arquivo
@@ -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();
+1
Ver Arquivo
@@ -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();
}