Comparar commits

...

58 Commits
il ... 1.6

Autor SHA1 Mensagem Data
Daniel Molkentin 1c92d68fe1 Merge branch '1.6' of https://github.com/owncloud/mirall into 1.6 2014-12-02 15:14:04 +01:00
Olivier Goffart d983f45eab compile 2014-11-27 16:19:36 +01:00
Olivier Goffart 944de6a3d5 Shibboleth: Fix our implemtnation of CookieJar::deleteCookie
It was deleting too many cookies.
That function is virtual in Qt5 and is used when adding cookie.
But some Shibboleth have several cookies with the same name, and we need to keep them.

Our implementaiton was meant to delete all the shiboleth cookies when we want to log out

(cherry picked from commit 1f9d02e7fa)

Conflicts:
	src/mirall/cookiejar.h
2014-11-27 13:00:00 +01:00
Klaas Freitag ebb9cc786f tests: exit t5.pl if running against ownCloud 6
t5.pl checks the environment variable SERVER_VERSION and if that equals
"owncloud6" it bails out after a check of the sharing ocs api.

Conflicts:
	csync/tests/ownCloud/t5.pl
2014-11-21 17:10:34 +01:00
Klaas Freitag f01788ae78 tests: Never stumble over an already existing test share dir.
Conflicts:
	csync/tests/ownCloud/t5.pl
2014-11-21 17:10:34 +01:00
Klaas Freitag 4de09e85e3 Add call to removeRemoteDir 2014-11-21 17:10:34 +01:00
Klaas Freitag cc11833d8d tests: only do the sharing test with ownCloud6
set the environment variable SERVER_VERION=owncloud6 to have the full
test running. Fix required to make Jenkins go green.
2014-10-29 15:59:43 +01:00
Klaas Freitag c4a9e524e6 Set version to 1.6.4 final. 2014-10-22 11:33:26 +02:00
Daniel Molkentin 1ad23e6ab0 NSIS: Fix copying of qtbase translations 2014-10-17 16:44:16 +02:00
Daniel Molkentin f1dbba9e5a Second part of #1661
- QT_INSTALL_TRANSLATIONS was not defined in Qt5
- Some languages have been split up in multiple qm's. We only need qtbase for now
2014-10-15 17:10:41 +02:00
Daniel Molkentin 8d7408bb0c Correct lookup logic for Qt translations
Fixes #1661
2014-10-15 09:33:56 +02:00
Klaas Freitag 18f1b3c5ff Bumped version to 1.6.4 rc2 2014-10-10 11:53:13 +02:00
Daniel Molkentin 7dcbbb0046 Make sign_dmg.sh script fix frameworks correctly, resize disk image 2014-10-09 18:39:16 +02:00
Daniel Molkentin 0f58431746 Make sign_dmg.sh script fix frameworks correctly, resize disk image 2014-10-09 18:38:25 +02:00
Klaas Freitag cc8408be8f Bumped version to 1.6.4rc1 2014-10-09 15:03:27 +02:00
Klaas Freitag 4902271b19 Updated Changelog for 1.6.4 2014-10-09 15:02:40 +02:00
Christian Kamm b881b6db4e NetworkJobs: Propagator jobs keep others from expiring. #2155
In some owncloud server setups multiple concurrent connections for the
same session are not supported: owncloud/core#11153

This causes issues with multiple uploads and downloads. A usual symptom
is the quota job failing and the sync aborting.

This workaround lets activity on the propagator's GET and PUT jobs
reset the timeout of all network jobs. That way, queries like the quota
job would not time out while a large up/download is in progress.

(cherry picked from commit 2eec85a97c)
2014-10-09 11:29:12 +02:00
Christian Kamm 421177bfaf Download: Don't store message body if status != 2xx #2280
(cherry picked from commit 705cd571a5)
2014-10-09 11:23:39 +02:00
Christian Kamm 395ae1d4ed GET: Retry if bad range header used. #2280
* If a 416 is returned and we used a Range header, try again
  from scratch.
* The direct URL logic was also inconsistent for resumed downloads:
  it sent the Range header but didn't check the returned
  Content-Range header correctly. Now resuming is disabled for
  direct URL downloads.

(cherry picked from commit 48d3c75745)
2014-10-09 11:21:29 +02:00
Jürgen Weigert c0bb4cd938 Fixed https://github.com/owncloud/mirall/issues/1699
Added missing copyright headers.
2014-09-18 12:32:57 +02:00
Christian Kamm 06bcb8f3c8 Propagator: Use csync to get the modification time.
See owncloud/core#9781

(cherry picked from commit 2630a73a1c)

Conflict: Move modtime comparison from socketapi.cpp to folder.cpp.
2014-09-17 07:33:19 +02:00
Olivier Goffart 8711a3ea6c csync_vio_local on windows: fix overflow when computing the size of file > 4GiB
MAXDWORD is 0xFFFFFFFF, so if we add one, it overflows and is 0.
We need to cast it to 64 bits before
2014-09-10 12:12:07 +02:00
Daniel Molkentin 984be698b4 raiseDialog: Actually send the XEvent
Amendment to 25c274a0bd
2014-09-05 22:21:05 +02:00
Christian Kamm 4566ca3127 FolderMan: Fix startFromScratch logic. #1989 2014-09-05 10:13:00 +02:00
Christian Kamm cc1121ef00 Account: Fix cert save/restore from settings. #2160 2014-09-04 15:24:46 +02:00
Markus Goetz 6f9938a2b2 ownCloudTheme: Fix casing in appName()
Without this fix, the section in the config file uses the wrong name,
leading to re-configuration of the client needed.
2014-09-03 16:07:05 +02:00
Daniel Molkentin a650dce17f 1.6.3 final 2014-09-03 15:03:23 +02:00
Daniel Molkentin 7ddd3a36c7 Update ChangeLog 2014-09-02 16:41:41 +02:00
Markus Goetz c46f1aba89 Sparkle: Keep permissions from bundle
(cherry picked from commit 0be4b59cff)
2014-09-02 16:38:45 +02:00
Daniel Molkentin 2ab19b23d7 Make Settings Window close on Ctrl+W
Fixes #2141
2014-09-02 13:58:55 +02:00
Daniel Molkentin d770f9cc1a Account Migrator: Switch to string comparison for URLs.
QUrl does not normalize trailing slashes, so there is no benefit
of using QUrl here.
2014-08-31 19:50:20 +02:00
Daniel Molkentin 9d3b09159e Edit ChangeLog 2014-08-31 19:13:57 +02:00
Klaas Freitag 819cb74cc3 Changelog bumped for 1.6.3 2014-08-30 19:07:59 +02:00
Klaas Freitag 2407469104 Bump version to 1.6.3 beta1. 2014-08-30 18:18:53 +02:00
Klaas Freitag c1faff513e Merge remote-tracking branch 'origin/reuse_oc_config' into 1.6 2014-08-29 20:07:27 +02:00
Daniel Molkentin e5b4438d5c X11: Bring Settings window to front when launched
(cherry picked from commit 25c274a0bd)

Conflicts:
	src/mirall/owncloudgui.cpp
2014-08-28 18:14:27 +02:00
Olivier Goffart 7ec43e9f36 uploading: make sure to cast to uint64 to avoid integer overflow
(cherry picked from commit 302499b483)
2014-08-26 16:36:35 +02:00
Olivier Goffart c4dabe7ed2 SSLButton: fix memleak
(cherry picked from commit 9b88c7d3c1)
2014-08-26 16:36:35 +02:00
Daniel Molkentin 6b4f11f4aa Fix backporting glitch the broke compilation 2014-08-14 16:36:03 +02:00
Daniel Molkentin 1edf3dd503 Always handle 401 requests, except for network jobs
It is not enough to only implement it for the QNAM returned
by the ShibbolethCredentials, because we sometimes need it
when we have no valid credentials set (and are using dummy
credentials in the course).  The main use case is the
Webview opened by Shibboleth for FBA.

But as a side-effect, we can use it to handle auth requests
from the updater and other places.

(cherry picked from commit 1544606bf0)

Conflicts:
	src/CMakeLists.txt
	src/creds/shibbolethcredentials.h
2014-08-13 15:04:31 +02:00
Markus Goetz 1daf9bc80b Tests: Give a more random name to test directories 2014-08-12 16:25:04 +02:00
Markus Goetz b7a91a6998 Fix compile and adapt code to be similar to 1.7/master 2014-08-12 15:24:42 +02:00
Markus Goetz 69dffc8882 OS X: Finally(?) fix stay-on-top behaviour of settings dialog
Fixes #1795

Conflicts:
	.gitmodules
	src/mirall/owncloudgui.cpp
2014-08-12 14:54:59 +02:00
Klaas Freitag 753aa9132e Merge pull request #2013 from owncloud/fix-man-dir-16
Fix issue#2004 -- mandir must be man1, not man
2014-07-30 17:38:25 +02:00
Olivier Goffart cfdfd6a860 wizard: don't call initializePage
It is called automatically by QWizard and do not need to be called explicitly

But setVisibla(false) don't really have an effect there since show() is going
to be called on the page
2014-07-30 12:36:30 +02:00
Jürgen Weigert 0c9d57228d Fix issue#2004 -- mandir must be man1, not man 2014-07-29 18:29:55 +02:00
Olivier Goffart 5254c9785c shibboleth: Fix connection when the URL do not have a path
When the url do not have a path (for example: "http://example.com" as
opposed to "http://example.com/"),  its path is not a prefix of the
root path of the cookie (usually '/')

By adding the dav path, we make sure the URL has a path.

This made a bug when the owncloud url was just a domain name and did not
have a path
2014-07-28 13:50:24 +02:00
Klaas Freitag 0f37484b8a Bumped the release number to 1.6.2, Changelog additions. 2014-07-28 11:44:10 +02:00
Klaas Freitag e17243bc1f AccountMigrator: Read path from QDir::fromNativeSeperators(), add debug. 2014-06-25 11:38:08 +02:00
Klaas Freitag 0e45dd7a3d AccountMigrator: Do not inherit from QObject as it is not needed yet.
As requested by Danimos review.
2014-06-25 11:38:08 +02:00
Klaas Freitag 65f313f1b4 Account: Added missing include statement. 2014-06-25 11:38:08 +02:00
Klaas Freitag da4958c716 Account: Read settings from ownCloud config if no branded exists.
If there is not yet a config for a branded client, but one for the
"normal" client targetting the same URL, it will be migrated.
2014-06-25 11:38:08 +02:00
Klaas Freitag 653b8494f5 FolderMan: Migrate folderlist if no folder definitions can be found
and the account indicates that it was migrated. In that case,
read the folder definitions from the ownCloud config directory.
2014-06-25 11:38:08 +02:00
Klaas Freitag 6ed6f84f6e Account: Add a wasMigrated flag.
If an account in a branded client was migrated from a former ownCloud
configuration, the method wasMigrated() will return true.
2014-06-25 11:38:08 +02:00
Klaas Freitag ff0ba56bc3 ownCloud Theme: Implement appName() and appNameGUI(). 2014-06-25 11:38:08 +02:00
Klaas Freitag e795d04f30 cfg migration: Add a account migrator class. 2014-06-25 11:38:08 +02:00
Klaas Freitag 8d3806b080 folderman: make escapeAlias public as its now used in accountmigrator. 2014-06-25 11:38:08 +02:00
Klaas Freitag 5597ebe455 Account: Add a scoped pointer to the ownCloud theme. 2014-06-25 11:38:07 +02:00
59 arquivos alterados com 665 adições e 152 exclusões
+1 -1
Ver Arquivo
@@ -3,4 +3,4 @@
url = https://github.com/owncloud/documentation
[submodule "src/3rdparty/qtmacgoodies"]
path = src/3rdparty/qtmacgoodies
url = git://github.com/shadone/qtmacgoodies.git
url = git://github.com/guruz/qtmacgoodies.git
+23 -1
Ver Arquivo
@@ -1,6 +1,28 @@
ChangeLog
=========
version 1.6.2 (release 2014-07-x )
version 1.6.4 (release 2014-10-xx)
* Fix startup logic, fixes bug #1989
* Fix raise dialog on X11
* Win32: fix overflow when computing the size of file > 4GiB
* Use a fixed function to get files modification time, the
original one was broken for certain timezone issues, see
core bug #9781 for details
* Added some missing copyright headers
* Avoid data corruption due to wrong error handling, bug #2280
* Do improved request timeout handling to reduce the number of
timed out jobs, bug #2155
version 1.6.3 (release 2014-09-03)
* Fixed updater on OS X
* Fixed memory leak in SSL button that could lead to quick memory draining
* Fixed upload problem with files >4 GB
* MacOSX, Linux: Bring Settings window to front properly
* Branded clients: If no configuration is detected, try to import the data
from a previously configured community edition.
version 1.6.2 (release 2014-07-28 )
* Limit the HTTP buffer size when downloading to limit memory consumption.
* Another small mem leak fixed in HTTP Credentials.
* Fix local file name clash detection for MacOSX.
* Limit maximum wait time to ten seconds in network limiting.
+2 -2
Ver Arquivo
@@ -1,10 +1,10 @@
set( MIRALL_VERSION_MAJOR 1 )
set( MIRALL_VERSION_MINOR 6 )
set( MIRALL_VERSION_PATCH 2 )
set( MIRALL_VERSION_PATCH 4 )
set( MIRALL_SOVERSION 0 )
if ( NOT DEFINED MIRALL_VERSION_SUFFIX )
set( MIRALL_VERSION_SUFFIX "rc2") #e.g. beta1, beta2, rc1
set( MIRALL_VERSION_SUFFIX "") #e.g. beta1, beta2, rc1
endif( NOT DEFINED MIRALL_VERSION_SUFFIX )
if( NOT DEFINED MIRALL_VERSION_BUILD )
+5
Ver Arquivo
@@ -23,6 +23,8 @@ fix_frameworks() {
mkdir -p "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources/"
cp -avf "${QT_FMWK_PATH}/${FMWK}/Contents/Info.plist" "${FMWK_PATH}/Versions/${QT_FMWK_VERSION}/Resources"
(cd "${FMWK_PATH}" && ln -sf "Versions/${QT_FMWK_VERSION}/Resources" "Resources")
(cd "${FMWK_PATH}" && ln -sf "Versions/${QT_FMWK_VERSION}/${FMWK_NAME}")
(cd "${FMWK_PATH}/Versions" && ln -sf "${QT_FMWK_VERSION}" "Current")
perl -pi -e "s/${FMWK_NAME}_debug/${FMWK_NAME}/" "${FMWK_PATH}/Resources/Info.plist"
done
}
@@ -30,6 +32,9 @@ fix_frameworks() {
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"
#signing adds data, add a bit of space
sectors=$(hdiutil resize -limits "$tmp_dmg" |grep -v cur|cut -f2)
hdiutil resize -sectors $(($sectors+(51200))) "$tmp_dmg"
hdiutil attach "$tmp_dmg"
pushd "$mount"
fix_frameworks "$mount"/*.app `qmake -query QT_INSTALL_LIBS` "$mount"/*.app/Contents/Frameworks
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# Always include srcdir and builddir in include path
# This saves typing ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY} in
# about every subdir
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# define system dependent compiler flags
include(CheckCCompilerFlag)
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
if (UNIX)
# Suffix for Linux
SET(LIB_SUFFIX
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# Set system vars
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# This module defines
# INOTIFY_INCLUDE_DIR, where to find inotify.h, etc.
# INOTIFY_FOUND, If false, do not try to use inotify.
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# FIND_PACKAGE_VERSION_CHECK(NAME (DEFAULT_MSG|"Custom failure message"))
# This function is intended to be used in FindXXX.cmake modules files.
# It handles NAME_FIND_VERSION and NAME_VERSION variables in a Module.
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
find_program(PDFLATEX_EXECUTABLE NAMES pdflatex
HINTS
$ENV{PDFLATEX_DIR}
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# - Try to find QtKeychain
# Once done this will define
# QTKEYCHAIN_FOUND - System has QtKeychain
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# - Try to find QtKeychain
# Once done this will define
# QTKEYCHAIN_FOUND - System has QtKeychain
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
find_program(SPHINX_EXECUTABLE NAMES sphinx-build
HINTS
$ENV{SPHINX_DIR}
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# - macro_copy_file(_src _dst)
# Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst}
#
+1
Ver Arquivo
@@ -378,6 +378,7 @@ Section "${APPLICATION_NAME}" SEC_APPLICATION
; Make sure only to copy qt, not qt_help, etc
File "${MING_SHARE}\qt5\translations\qt_??.qm"
File "${MING_SHARE}\qt5\translations\qt_??_??.qm"
File "${MING_SHARE}\qt5\translations\qtbase_*.qm"
File "${MING_SHARE}\qt5\translations\qtkeychain_*.qm"
SetOutPath "$INSTDIR\platforms"
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
include (MacroOptionalFindPackage)
include (MacroLogFeature)
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
# -helper macro to add a "doc" target with CMake build system.
# and configure doxy.config.in to doxy.config
#
+4
Ver Arquivo
@@ -1,3 +1,7 @@
# (c) 2014 Copyright ownCloud, Inc.
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING* file.
if(CMAKE_COMPILER_IS_GNUCXX)
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
+1 -1
Ver Arquivo
@@ -240,7 +240,7 @@ int csync_vio_local_stat(const char *uri, csync_vio_file_stat_t *buf) {
/* printf("Index: %I64i\n", FileIndex.QuadPart); */
buf->inode = FileIndex.QuadPart;
buf->size = (fileInfo.nFileSizeHigh * (int64_t)(MAXDWORD+1)) + fileInfo.nFileSizeLow;
buf->size = (fileInfo.nFileSizeHigh * ((int64_t)(MAXDWORD)+1)) + fileInfo.nFileSizeLow;
buf->fields |= CSYNC_VIO_FILE_STAT_FIELDS_SIZE;
/* Get the file time with a win32 call rather than through stat. See
+32 -4
Ver Arquivo
@@ -34,6 +34,7 @@ use LWP::UserAgent;
use LWP::Protocol::https;
use HTTP::Request::Common qw( POST GET DELETE );
use File::Basename;
use POSIX qw/strftime/;
use Encode qw(from_to);
use utf8;
@@ -60,7 +61,7 @@ our $infoCnt = 1;
our %config;
@ISA = qw(Exporter);
@EXPORT = qw( initTesting createRemoteDir createLocalDir cleanup csync
@EXPORT = qw( initTesting createRemoteDir removeRemoteDir createLocalDir cleanup csync
assertLocalDirs assertLocalAndRemoteDir glob_put put_to_dir
putToDirLWP localDir remoteDir localCleanup createLocalFile md5OfFile
remoteCleanup server initLocalDir initRemoteDir moveRemoteFile
@@ -128,8 +129,9 @@ sub initTesting(;$)
# $d->DebugLevel(3);
$prefix = "t1" unless( defined $prefix );
my $dirId = sprintf("%#.3o", rand(1000));
my $dir = sprintf( "%s-%s/", $prefix, $dirId );
my $dirId = sprintf("%02d", rand(100));
my $dateTime = strftime('%Y%m%d%H%M%S',localtime);
my $dir = sprintf( "%s-%s-%s/", $prefix, $dateTime, $dirId );
$localDir = $dir;
$localDir .= "/" unless( $localDir =~ /\/$/ );
@@ -179,6 +181,32 @@ sub initLocalDir
mkdir ($localDir, 0777 );
}
sub removeRemoteDir($;$)
{
my ($dir, $optionsRef) = @_;
my $url = testDirUrl() . $dir;
if( $optionsRef && $optionsRef->{user} && $optionsRef->{passwd} ) {
$d->credentials( -url=> $owncloud, -realm=>"ownCloud",
-user=> $optionsRef->{user},
-pass=> $optionsRef->{passwd} );
if( $optionsRef->{url} ) {
$url = $optionsRef->{url} . $dir;
}
}
$d->open( $owncloud );
print $d->message . "\n";
my $re = $d->delete( $url );
if( $re == 0 ) {
print "Failed to remove directory <$url>:" . $d->message() ."\n";
}
return $re;
}
sub createRemoteDir(;$$)
{
my ($dir, $optionsRef) = @_;
@@ -199,7 +227,7 @@ sub createRemoteDir(;$$)
my $re = $d->mkcol( $url );
if( $re == 0 ) {
print "Failed to create directory <$url>: $d->message() \n";
print "Failed to create directory <$url>: " . $d->message() ."\n";
exit 1;
}
$d->open( $url );
+24 -14
Ver Arquivo
@@ -35,6 +35,13 @@ print "Hello, this is t5, a tester for syncing of files in Shares\n";
initTesting();
my $share_dir = "share_source";
my $sharee = { user => configValue('share_user'),
passwd => configValue('share_passwd'),
url => server() };
# first remove a possibly left over share dir.
printInfo( "Remove possibly left over share dir" );
removeRemoteDir( $share_dir, $sharee );
printInfo( "Create a share." );
my $shareId = createShare( $share_dir, 31 );
@@ -42,25 +49,28 @@ print "Created share with id <$shareId>\n";
assert( $shareId > 0 );
my $sharee = { user => configValue('share_user'),
passwd => configValue('share_passwd'),
url => server() };
if( $ENV{SERVER_VERSION} eq "owncloud7" ) {
print "This test does not make sense for ownCloud7, leaving for good!\n\n";
exit;
}
# put a couple of files into the shared directory in the sharer account
glob_put( 'sharing/*', $share_dir, $sharee);
# now user kf has a new directory in shared.
if( $ENV{SERVER_VERSION} eq "owncloud6" ) {
# now user kf has a new directory in shared.
# call csync, sync local t1 to remote t1
printInfo("Initial sync, sync stuff down.");
csync( server()."Shared" );
assertLocalAndRemoteDir( 'Shared', 0, server() );
# Local file to a read/write share should be synced up
printInfo("Put a file into the share.");
createLocalFile( localDir(). $share_dir . "/foobar.txt", 8094 );
csync( server()."Shared" );
assertLocalAndRemoteDir( 'Shared', 0, server() );
# call csync, sync local t1 to remote t1
printInfo("Initial sync, sync stuff down.");
csync( server()."Shared" );
assertLocalAndRemoteDir( 'Shared', 0, server() );
# Local file to a read/write share should be synced up
printInfo("Put a file into the share.");
createLocalFile( localDir(). $share_dir . "/foobar.txt", 8094 );
csync( server()."Shared" );
assertLocalAndRemoteDir( 'Shared', 0, server() );
}
printInfo("Remove a Share.");
removeShare($shareId, $share_dir);
+1 -1
Ver Arquivo
@@ -4,7 +4,7 @@ if(SPHINX_FOUND)
set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees")
# HTML output directory
set(SPHINX_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/html")
set(SPHINX_MAN_DIR "${CMAKE_CURRENT_BINARY_DIR}/man")
set(SPHINX_MAN_DIR "${CMAKE_CURRENT_BINARY_DIR}/man1")
set(SPHINX_PDF_DIR "${CMAKE_CURRENT_BINARY_DIR}/latex")
set(SPHINX_QCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/qthelp")
set(SPHINX_HTMLHELP_DIR "${CMAKE_CURRENT_BINARY_DIR}/htmlhelp")
+11 -3
Ver Arquivo
@@ -45,6 +45,7 @@ if (APPLE)
list(APPEND 3rdparty_SRC
3rdparty/qtmacgoodies/src/macpreferenceswindow.mm
3rdparty/qtmacgoodies/src/macstandardicon.mm
3rdparty/qtmacgoodies/src/macwindow.mm
)
endif()
@@ -82,6 +83,7 @@ set(libsync_SRCS
mirall/folderman.cpp
mirall/folder.cpp
mirall/folderwatcher.cpp
mirall/authenticationdialog.cpp
mirall/syncresult.cpp
mirall/mirallconfigfile.cpp
mirall/syncengine.cpp
@@ -105,6 +107,7 @@ set(libsync_SRCS
mirall/clientproxy.cpp
mirall/syncrunfilelog.cpp
mirall/cookiejar.cpp
mirall/accountmigrator.cpp
creds/dummycredentials.cpp
creds/abstractcredentials.cpp
creds/credentialsfactory.cpp
@@ -124,7 +127,6 @@ else()
creds/shibbolethcredentials.cpp
creds/shibboleth/shibbolethwebview.cpp
creds/shibboleth/shibbolethrefresher.cpp
creds/shibboleth/authenticationdialog.cpp
creds/shibboleth/shibbolethuserjob.cpp
)
endif()
@@ -246,7 +248,7 @@ else()
install(TARGETS ${synclib_NAME} DESTINATION ${OWNCLOUD_OSX_BUNDLE}/Contents/MacOS)
if (SPARKLE_FOUND)
install(DIRECTORY "${SPARKLE_LIBRARY}"
DESTINATION "${OWNCLOUD_OSX_BUNDLE}/Contents/Frameworks")
DESTINATION "${OWNCLOUD_OSX_BUNDLE}/Contents/Frameworks" USE_SOURCE_PERMISSIONS)
endif (SPARKLE_FOUND)
endif()
@@ -388,7 +390,6 @@ set(ownCloud ${ownCloud_old})
if (WITH_DBUS)
set(ADDITIONAL_APP_MODULES DBus)
endif(WITH_DBUS)
if(NOT BUILD_OWNCLOUD_OSX_BUNDLE AND NOT BUILD_LIBRARIES_ONLY)
set(BIN_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
@@ -425,8 +426,15 @@ elseif(NOT BUILD_LIBRARIES_ONLY)
set (QM_DIR ${OWNCLOUD_OSX_BUNDLE}/Contents/Resources/Translations)
install(FILES ${mirall_I18N} DESTINATION ${QM_DIR})
get_target_property(_qmake Qt5::qmake LOCATION)
execute_process(COMMAND ${_qmake} -query QT_INSTALL_TRANSLATIONS
OUTPUT_VARIABLE QT_TRANSLATIONS_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
file(GLOB qt_I18N ${QT_TRANSLATIONS_DIR}/qt_??.qm ${QT_TRANSLATIONS_DIR}/qt_??_??.qm)
install(FILES ${qt_I18N} DESTINATION ${QM_DIR})
file(GLOB qtbase_I18N ${QT_TRANSLATIONS_DIR}/qtbase_??.qm ${QT_TRANSLATIONS_DIR}/qt_??_??.qm)
install(FILES ${qtbase_I18N} DESTINATION ${QM_DIR})
file(GLOB qtkeychain_I18N ${QT_TRANSLATIONS_DIR}/qtkeychain*.qm)
install(FILES ${qtkeychain_I18N} DESTINATION ${QM_DIR})
endif()
+14 -22
Ver Arquivo
@@ -20,7 +20,6 @@
#include <QDebug>
#include "creds/shibbolethcredentials.h"
#include "creds/shibboleth/authenticationdialog.h"
#include "creds/shibboleth/shibbolethwebview.h"
#include "creds/shibboleth/shibbolethrefresher.h"
#include "creds/shibbolethcredentials.h"
@@ -173,8 +172,6 @@ QNetworkAccessManager* ShibbolethCredentials::getQNAM() const
QNetworkAccessManager* qnam(new MirallAccessManager);
connect(qnam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(slotReplyFinished(QNetworkReply*)));
connect(qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
SLOT(slotHandleAuthentication(QNetworkReply*,QAuthenticator*)));
return qnam;
}
@@ -244,7 +241,19 @@ void ShibbolethCredentials::persist(Account* account)
void ShibbolethCredentials::invalidateToken(Account *account)
{
CookieJar *jar = static_cast<CookieJar*>(account->networkAccessManager()->cookieJar());
jar->deleteCookie(_shibCookie);
// Remove the _shibCookie
QList<QNetworkCookie> cookies = jar->allCookies();
for (QList<QNetworkCookie>::iterator it = cookies.begin(); it != cookies.end(); ) {
if (it->name() == _shibCookie.name()) {
it = cookies.erase(it);
} else {
++it;
}
}
jar->setAllCookies(cookies);
// Clear all other temporary cookies
jar->clearSessionCookies();
removeShibCookie(account);
_shibCookie = QNetworkCookie();
@@ -319,23 +328,6 @@ void ShibbolethCredentials::invalidateAndFetch(Account* account)
job->start();
}
void ShibbolethCredentials::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());
if (dialog.exec() == QDialog::Accepted) {
authenticator->setUser(dialog.user());
authenticator->setPassword(dialog.password());
}
}
void ShibbolethCredentials::slotInvalidateAndFetchInvalidateDone(QKeychain::Job* job)
{
Account *account = qvariant_cast<Account*>(job->property("account"));
@@ -405,7 +397,7 @@ void ShibbolethCredentials::showLoginWindow(Account* account)
QList<QNetworkCookie> ShibbolethCredentials::accountCookies(Account *account)
{
return account->networkAccessManager()->cookieJar()->cookiesForUrl(account->url());
return account->networkAccessManager()->cookieJar()->cookiesForUrl(account->davUrl());
}
QNetworkCookie ShibbolethCredentials::findShibCookie(Account *account, QList<QNetworkCookie> cookies)
-1
Ver Arquivo
@@ -63,7 +63,6 @@ public:
public Q_SLOTS:
void invalidateAndFetch(Account *account);
void slotHandleAuthentication(QNetworkReply*,QAuthenticator*);
private Q_SLOTS:
void onShibbolethCookieReceived(const QNetworkCookie&, Account*);
+67 -6
Ver Arquivo
@@ -18,6 +18,7 @@
#include "mirall/mirallconfigfile.h"
#include "mirall/mirallaccessmanager.h"
#include "mirall/quotainfo.h"
#include "mirall/owncloudtheme.h"
#include "creds/abstractcredentials.h"
#include "creds/credentialsfactory.h"
@@ -27,6 +28,8 @@
#include <QNetworkAccessManager>
#include <QSslSocket>
#include <QNetworkCookieJar>
#include <QFileInfo>
#include <QDir>
#include <QDebug>
@@ -36,6 +39,7 @@ static const char urlC[] = "url";
static const char authTypeC[] = "authType";
static const char userC[] = "user";
static const char httpUserC[] = "http_user";
static const char caCertsKeyC[] = "CaCertificates";
AccountManager *AccountManager::_instance = 0;
@@ -71,6 +75,7 @@ Account::Account(AbstractSslErrorHandler *sslErrorHandler, QObject *parent)
, _treatSslErrorsAsFailure(false)
, _state(Account::Disconnected)
, _davPath("remote.php/webdav/")
, _wasMigrated(false)
{
qRegisterMetaType<Account*>("Account*");
}
@@ -98,25 +103,66 @@ void Account::save()
}
settings->sync();
// ### TODO port away from MirallConfigFile
MirallConfigFile cfg;
// Save accepted certificates.
settings->beginGroup(QLatin1String("General"));
qDebug() << "Saving " << approvedCerts().count() << " unknown certs.";
QByteArray certs;
Q_FOREACH( const QSslCertificate& cert, approvedCerts() ) {
certs += cert.toPem() + '\n';
}
if (!certs.isEmpty()) {
cfg.setCaCerts( certs );
settings->setValue( QLatin1String(caCertsKeyC), certs );
}
}
Account* Account::restore()
{
// try to open the correctly themed settings
QScopedPointer<QSettings> settings(settingsWithGroup(Theme::instance()->appName()));
Account *acc = 0;
bool migratedCreds = false;
// if the settings file could not be opened, the childKeys list is empty
if( settings->childKeys().isEmpty() ) {
// Now try to open the original ownCloud settings to see if they exist.
QString oCCfgFile = QDir::fromNativeSeparators( settings->fileName() );
// replace the last two segments with ownCloud/owncloud.cfg
oCCfgFile = oCCfgFile.left( oCCfgFile.lastIndexOf('/'));
oCCfgFile = oCCfgFile.left( oCCfgFile.lastIndexOf('/'));
oCCfgFile += QLatin1String("/ownCloud/owncloud.cfg");
qDebug() << "Migrate: checking old config " << oCCfgFile;
QFileInfo fi( oCCfgFile );
if( fi.isReadable() ) {
QSettings *oCSettings = new QSettings(oCCfgFile, QSettings::IniFormat);
oCSettings->beginGroup(QLatin1String("ownCloud"));
// Check the theme url to see if it is the same url that the oC config was for
QString overrideUrl = Theme::instance()->overrideServerUrl();
if( !overrideUrl.isEmpty() ) {
if (overrideUrl.endsWith('/')) { overrideUrl.chop(1); }
QString oCUrl = oCSettings->value(QLatin1String(urlC)).toString();
if (oCUrl.endsWith('/')) { oCUrl.chop(1); }
// in case the urls are equal reset the settings object to read from
// the ownCloud settings object
qDebug() << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
<< (oCUrl == overrideUrl ? "Yes" : "No");
if( oCUrl == overrideUrl ) {
migratedCreds = true;
settings.reset( oCSettings );
} else {
delete oCSettings;
}
}
}
}
if (!settings->childKeys().isEmpty()) {
Account *acc = new Account;
MirallConfigFile cfg;
acc->setApprovedCerts(QSslCertificate::fromData(cfg.caCerts()));
acc = new Account;
acc->setUrl(settings->value(QLatin1String(urlC)).toUrl());
acc->setCredentials(CredentialsFactory::create(settings->value(QLatin1String(authTypeC)).toString()));
@@ -128,6 +174,11 @@ Account* Account::restore()
continue;
acc->_settingsMap.insert(key, settings->value(key));
}
// now the cert, it is in the general group
settings->beginGroup(QLatin1String("General"));
acc->setApprovedCerts(QSslCertificate::fromData(settings->value(caCertsKeyC).toByteArray()));
acc->setMigrated(migratedCreds);
return acc;
}
return 0;
@@ -364,4 +415,14 @@ void Account::slotHandleErrors(QNetworkReply *reply , QList<QSslError> errors)
}
}
bool Account::wasMigrated()
{
return _wasMigrated;
}
void Account::setMigrated(bool mig)
{
_wasMigrated = mig;
}
} // namespace Mirall
+10
Ver Arquivo
@@ -108,6 +108,13 @@ public:
/** Returns webdav entry URL, based on url() */
QUrl davUrl() const;
/** set and retrieve the migration flag: if an account of a branded
* client was migrated from a former ownCloud Account, this is true
*/
void setMigrated(bool mig);
bool wasMigrated();
QList<QNetworkCookie> lastAuthCookies() const;
QNetworkReply* headRequest(const QString &relPath);
@@ -147,8 +154,10 @@ public:
QNetworkAccessManager* networkAccessManager();
QuotaInfo *quotaInfo();
signals:
void stateChanged(int state);
void propagatorNetworkActivity();
protected Q_SLOTS:
void slotHandleErrors(QNetworkReply*,QList<QSslError>);
@@ -166,6 +175,7 @@ private:
int _state;
static QString _configFileName;
QString _davPath; // default "remote.php/webdav/";
bool _wasMigrated;
};
}
+89
Ver Arquivo
@@ -0,0 +1,89 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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 "mirall/accountmigrator.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/folderman.h"
#include "mirall/theme.h"
#include <QSettings>
#include <QStringList>
#include <QDir>
#include <QFileInfo>
#include <QDebug>
namespace Mirall {
// The purpose of this class is to migrate an existing account that
// was set up with an unbranded client to an branded one.
// The usecase is: Usually people try first with the community client,
// later they maybe switch to a branded client. When they install the
// branded client first, it should automatically pick the information
// from the already configured account.
AccountMigrator::AccountMigrator()
{
}
// the list of folder definitions which are files in the directory "folders"
// underneath the ownCloud configPath (with ownCloud as a last segment)
// need to be copied to the themed path and adjusted.
QStringList AccountMigrator::migrateFolderDefinitons()
{
MirallConfigFile cfg;
QStringList re;
QString themePath = cfg.configPath();
// create the original ownCloud config path out of the theme path
// by removing the theme folder and append ownCloud.
QString oCPath = themePath;
if( oCPath.endsWith(QLatin1Char('/')) ) {
oCPath.truncate( oCPath.length()-1 );
}
oCPath = oCPath.left( oCPath.lastIndexOf('/'));
themePath += QLatin1String( "folders");
oCPath += QLatin1String( "/ownCloud/folders" );
qDebug() << "Migrator: theme-path: " << themePath;
qDebug() << "Migrator: ownCloud path: " << oCPath;
// get a dir listing of the ownCloud folder definitions and copy
// them over to the theme dir
QDir oCDir(oCPath);
oCDir.setFilter( QDir::Files );
QStringList files = oCDir.entryList();
foreach( const QString& file, files ) {
QString escapedAlias = FolderMan::instance()->escapeAlias(file);
QString themeFile = themePath + QDir::separator() + file;
QString oCFile = oCPath+QDir::separator()+file;
if( QFile::copy( oCFile, themeFile ) ) {
re.append(file);
qDebug() << "Migrator: Folder definition migrated: " << file;
// fix the connection entry of the folder definition
QSettings settings(themeFile, QSettings::IniFormat);
settings.beginGroup( escapedAlias );
settings.setValue(QLatin1String("connection"), Theme::instance()->appName());
settings.sync();
}
}
return re;
}
}
+38
Ver Arquivo
@@ -0,0 +1,38 @@
/*
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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 ACCOUNTMIGRATOR_H
#define ACCOUNTMIGRATOR_H
#include <QStringList>
namespace Mirall {
class AccountMigrator {
public:
explicit AccountMigrator();
/**
* @brief migrateFolderDefinitons - migrate the folder definition files
* @return the list of migrated folder definitions
*/
QStringList migrateFolderDefinitons();
signals:
public slots:
};
}
#endif // ACCOUNTMIGRATOR_H
+1 -1
Ver Arquivo
@@ -713,7 +713,7 @@ void AccountSettings::slotIgnoreFilesEditor()
_ignoreEditor->setAttribute( Qt::WA_DeleteOnClose, true );
_ignoreEditor->open();
} else {
Utility::raiseDialog(_ignoreEditor);
ownCloudGui::raiseDialog(_ignoreEditor);
}
}
+8 -5
Ver Arquivo
@@ -532,12 +532,15 @@ void Application::setupTranslations()
setProperty("ui_lang", lang);
const QString qtTrPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
const QString qtTrFile = QLatin1String("qt_") + lang;
if (qtTranslator->load(qtTrFile, qtTrPath)) {
qtTranslator->load(qtTrFile, trPath);
const QString qtBaseTrFile = QLatin1String("qtbase_") + lang;
if (!qtTranslator->load(qtTrFile, qtTrPath)) {
if (!qtTranslator->load(qtTrFile, trPath)) {
qtTranslator->load(qtBaseTrFile, trPath);
}
}
const QString qtkeychainFile = QLatin1String("qt_") + lang;
if (!qtkeychainTranslator->load(qtkeychainFile, qtTrPath)) {
qtkeychainTranslator->load(qtkeychainFile, trPath);
const QString qtkeychainTrFile = QLatin1String("qtkeychain_") + lang;
if (!qtkeychainTranslator->load(qtkeychainTrFile, qtTrPath)) {
qtkeychainTranslator->load(qtkeychainTrFile, trPath);
}
if (!translator->isEmpty())
installTranslator(translator);
-16
Ver Arquivo
@@ -91,27 +91,11 @@ QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl &url) const
return cookies;
}
bool CookieJar::deleteCookie(const QNetworkCookie &delCookie)
{
QList<QNetworkCookie> cookies = allCookies();
bool removeSucceeded = false;
foreach(const QNetworkCookie &cookie, cookies) {
// ### cookies are not identical in attriutes, why?
if (cookie.name() == delCookie.name()) {
cookies.removeOne(cookie);
removeSucceeded = true;
}
}
setAllCookies(cookies);
return removeSucceeded;
}
void CookieJar::clearSessionCookies()
{
setAllCookies(removeExpired(allCookies()));
}
void CookieJar::save()
{
QFile file;
+3 -1
Ver Arquivo
@@ -29,9 +29,11 @@ public:
bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url);
QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const;
virtual bool deleteCookie(const QNetworkCookie & cookie);
void clearSessionCookies();
using QNetworkCookieJar::setAllCookies;
using QNetworkCookieJar::allCookies;
signals:
void newCookiesForUrl(const QList<QNetworkCookie>& cookieList, const QUrl& url);
private:
+28 -1
Ver Arquivo
@@ -12,7 +12,10 @@
*/
#include "filesystem.h"
#include "utility.h"
#include <QFile>
#include <QFileInfo>
#include <QDebug>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
@@ -24,11 +27,16 @@
#include <winbase.h>
#endif
// We use some internals of csync:
extern "C" int c_utimes(const char *, const struct timeval *);
extern "C" void csync_win32_set_file_hidden( const char *file, bool h );
extern "C" {
#include "vio/csync_vio_handle.h"
#include "vio/csync_vio_file_stat.h"
#include "vio/csync_vio_local.h"
}
namespace Mirall {
bool FileSystem::fileEquals(const QString& fn1, const QString& fn2)
@@ -69,6 +77,25 @@ void FileSystem::setFileHidden(const QString& filename, bool hidden)
return csync_win32_set_file_hidden(filename.toUtf8().constData(), hidden);
}
time_t FileSystem::getModTime(const QString &filename)
{
csync_vio_file_stat_t* stat = csync_vio_file_stat_new();
qint64 result = -1;
if (csync_vio_local_stat(filename.toUtf8().data(), stat) != -1
&& (stat->fields & CSYNC_VIO_FILE_STAT_FIELDS_MTIME))
{
result = stat->mtime;
}
else
{
qDebug() << "Could not get modification time for" << filename
<< "with csync, using QFileInfo";
result = Utility::qDateTimeToTime_t(QFileInfo(filename).lastModified());
}
csync_vio_file_stat_destroy(stat);
return result;
}
void FileSystem::setModTime(const QString& filename, time_t modTime)
{
struct timeval times[2];
+8
Ver Arquivo
@@ -30,6 +30,14 @@ bool fileEquals(const QString &fn1, const QString &fn2);
/** Mark the file as hidden (only has effects on windows) */
void setFileHidden(const QString& filename, bool hidden);
/** Get the mtime for a filepath.
*
* Use this over QFileInfo::lastModified() to avoid timezone related bugs. See
* owncloud/core#9781 for details.
*/
time_t getModTime(const QString &filename);
void setModTime(const QString &filename, time_t modTime);
/**
+4 -1
Ver Arquivo
@@ -27,6 +27,7 @@
#include "mirall/clientproxy.h"
#include "mirall/syncengine.h"
#include "mirall/syncrunfilelog.h"
#include "mirall/filesystem.h"
#include "creds/abstractcredentials.h"
@@ -776,7 +777,9 @@ SyncFileStatus Folder::fileStatus( const QString& fileName )
}
// file was locally modified.
if( stat == FILE_STATUS_NONE && fi.lastModified() != rec._modtime ) {
if( stat == FILE_STATUS_NONE &&
FileSystem::getModTime(fi.absoluteFilePath())
!= Utility::qDateTimeToTime_t(rec._modtime) ) {
stat = FILE_STATUS_EVAL;
}
+39 -13
Ver Arquivo
@@ -13,10 +13,13 @@
*/
#include "mirall/folderman.h"
#include "mirall/account.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/folder.h"
#include "mirall/syncresult.h"
#include "mirall/theme.h"
#include "mirall/accountmigrator.h"
#include <neon/ne_socket.h>
@@ -147,6 +150,15 @@ int FolderMan::setupFolders()
dir.setFilter(QDir::Files | QDir::Hidden);
QStringList list = dir.entryList();
if( list.count() == 0 ) {
// maybe the account was just migrated.
Account *acc = AccountManager::instance()->account();
if ( acc && acc->wasMigrated() ) {
AccountMigrator accMig;
list = accMig.migrateFolderDefinitons();
}
}
foreach ( const QString& alias, list ) {
Folder *f = setupFolderFromConfigFile( alias );
if( f ) {
@@ -588,27 +600,41 @@ QString FolderMan::getBackupName( const QString& fullPathName ) const
bool FolderMan::startFromScratch( const QString& localFolder )
{
if( localFolder.isEmpty() ) return false;
if( localFolder.isEmpty() ) {
return false;
}
QFileInfo fi( localFolder );
if( fi.exists() && fi.isDir() ) {
QDir file = fi.dir();
QDir parentDir( fi.dir() );
QString folderName = fi.fileName();
// check if there are files in the directory.
if( file.count() == 0 ) {
// directory is existing, but its empty. Use it.
// Adjust for case where localFolder ends with a /
if ( fi.isDir() ) {
folderName = parentDir.dirName();
parentDir.cdUp();
}
if( fi.exists() ) {
// It exists, but is empty -> just reuse it.
if( fi.isDir() && fi.dir().count() == 0 ) {
qDebug() << "startFromScratch: Directory is empty!";
return true;
}
QString newName = getBackupName( fi.absoluteFilePath() );
if( file.rename( fi.absoluteFilePath(), newName )) {
if( file.mkdir( fi.absoluteFilePath() ) ) {
return true;
}
// Make a backup of the folder/file.
QString newName = getBackupName( parentDir.absoluteFilePath( folderName ) );
if( !parentDir.rename( fi.absoluteFilePath(), newName ) ) {
qDebug() << "startFromScratch: Could not rename" << fi.absoluteFilePath()
<< "to" << newName;
return false;
}
}
return false;
if( !parentDir.mkdir( fi.absoluteFilePath() ) ) {
qDebug() << "startFromScratch: Could not mkdir" << fi.absoluteFilePath();
return false;
}
return true;
}
void FolderMan::setDirtyProxy(bool value)
+2 -1
Ver Arquivo
@@ -83,6 +83,8 @@ public:
void removeMonitorPath( const QString& alias, const QString& path );
void addMonitorPath( const QString& alias, const QString& path );
QString escapeAlias( const QString& ) const;
signals:
/**
* signal to indicate a folder named by alias has changed its sync state.
@@ -130,7 +132,6 @@ private:
// Escaping of the alias which is used in QSettings AND the file
// system, thus need to be escaped.
QString escapeAlias( const QString& ) const;
QString unescapeAlias( const QString& ) const;
void removeFolder( const QString& );
+30 -2
Ver Arquivo
@@ -12,6 +12,7 @@
*/
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkProxy>
#include <QAuthenticator>
#include <QSslConfiguration>
@@ -19,6 +20,8 @@
#include "mirall/cookiejar.h"
#include "mirall/mirallaccessmanager.h"
#include "mirall/utility.h"
#include "mirall/authenticationdialog.h"
namespace Mirall
{
@@ -33,8 +36,11 @@ MirallAccessManager::MirallAccessManager(QObject* parent)
setProxy(proxy);
#endif
setCookieJar(new CookieJar);
QObject::connect(this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
this, SLOT(slotProxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
connect(this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
this, SLOT(slotProxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
connect(this, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
}
QNetworkReply* MirallAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest& request, QIODevice* outgoingData)
@@ -60,5 +66,27 @@ void MirallAccessManager::slotProxyAuthenticationRequired(const QNetworkProxy &p
authenticator->setPassword(proxy.password());
}
}
void MirallAccessManager::slotAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator)
{
// do not handle 401 created by the networkjobs. We may want
// to eventually exempt some, but for now we need
// it only for other things, e.g. the browser. Would we handle
// network jobs, this would break the wizard logic
if (reply->property("doNotHandleAuth").toBool()) {
return;
}
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());
if (dialog.exec() == QDialog::Accepted) {
authenticator->setUser(dialog.user());
authenticator->setPassword(dialog.password());
}
}
} // ns Mirall
+2
Ver Arquivo
@@ -31,6 +31,8 @@ protected:
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest& request, QIODevice* outgoingData = 0);
protected slots:
void slotProxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator);
void slotAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator);
};
} // ns Mirall
+17 -7
Ver Arquivo
@@ -50,6 +50,15 @@ AbstractNetworkJob::AbstractNetworkJob(Account *account, const QString &path, QO
_timer.setSingleShot(true);
_timer.setInterval(10*1000); // default to 10 seconds.
connect(&_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
connect(this, SIGNAL(networkActivity()), SLOT(resetTimeout()));
// Network activity on the propagator jobs (GET/PUT) keeps all requests alive.
// This is a workaround for OC instances which only support one
// parallel up and download
if (_account) {
connect(_account, SIGNAL(propagatorNetworkActivity()), SLOT(resetTimeout()));
}
}
void AbstractNetworkJob::setReply(QNetworkReply *reply)
@@ -57,6 +66,7 @@ void AbstractNetworkJob::setReply(QNetworkReply *reply)
if (_reply) {
_reply->deleteLater();
}
reply->setProperty("doNotHandleAuth", true);
_reply = reply;
}
@@ -79,11 +89,6 @@ void AbstractNetworkJob::setIgnoreCredentialFailure(bool ignore)
_ignoreCredentialFailure = ignore;
}
void AbstractNetworkJob::setAccount(Account *account)
{
_account = account;
}
void AbstractNetworkJob::setPath(const QString &path)
{
_path = path;
@@ -92,6 +97,8 @@ void AbstractNetworkJob::setPath(const QString &path)
void AbstractNetworkJob::setupConnections(QNetworkReply *reply)
{
connect(reply, SIGNAL(finished()), SLOT(slotFinished()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(networkActivity()));
connect(reply, SIGNAL(uploadProgress(qint64,qint64)), SIGNAL(networkActivity()));
}
QNetworkReply* AbstractNetworkJob::addTimer(QNetworkReply *reply)
@@ -178,8 +185,11 @@ QString AbstractNetworkJob::responseTimestamp()
return _responseTimestamp;
}
AbstractNetworkJob::~AbstractNetworkJob() {
_reply->deleteLater();
AbstractNetworkJob::~AbstractNetworkJob()
{
if (_reply) {
_reply->deleteLater();
}
}
void AbstractNetworkJob::start()
+2 -2
Ver Arquivo
@@ -55,15 +55,14 @@ public:
virtual void start();
void setAccount(Account *account);
Account* account() const { return _account; }
void setPath(const QString &path);
QString path() const { return _path; }
void setReply(QNetworkReply *reply);
QNetworkReply* reply() const { return _reply; }
void setIgnoreCredentialFailure(bool ignore);
bool ignoreCredentialFailure() const { return _ignoreCredentialFailure; }
@@ -75,6 +74,7 @@ public slots:
void resetTimeout();
signals:
void networkError(QNetworkReply *reply);
void networkActivity();
protected:
void setupConnections(QNetworkReply *reply);
QNetworkReply* davRequest(const QByteArray& verb, const QString &relPath,
+52 -2
Ver Arquivo
@@ -21,6 +21,7 @@
#include "mirall/owncloudsetupwizard.h"
#if defined(Q_OS_MAC)
# include "mirall/settingsdialogmac.h"
# include "macwindow.h" // qtmacgoodies
#else
# include "mirall/settingsdialog.h"
#endif
@@ -33,6 +34,10 @@
#include <QMessageBox>
#include <QSignalMapper>
#if defined(Q_OS_X11)
#include <QX11Info>
#endif
namespace Mirall {
ownCloudGui::ownCloudGui(Application *parent) :
@@ -111,6 +116,14 @@ void ownCloudGui::slotTrayClicked( QSystemTrayIcon::ActivationReason reason )
if( reason == QSystemTrayIcon::Trigger ) {
slotOpenSettingsDialog(true); // start settings if config is existing.
}
#else
// On Mac, if the settings dialog is already visible but hidden
// by other applications, this will bring it to the front.
if( reason == QSystemTrayIcon::Trigger ) {
if (!_settingsDialog.isNull() && _settingsDialog->isVisible()) {
slotShowSettings();
}
}
#endif
}
@@ -475,7 +488,7 @@ void ownCloudGui::slotShowSettings()
_settingsDialog->show();
}
_settingsDialog->setGeneralErrors( _startupFails );
Utility::raiseDialog(_settingsDialog.data());
ownCloudGui::raiseDialog(_settingsDialog.data());
}
void ownCloudGui::slotShowSyncProtocol()
@@ -503,7 +516,7 @@ void ownCloudGui::slotToggleLogBrowser()
if (_logBrowser->isVisible() ) {
_logBrowser->hide();
} else {
Utility::raiseDialog(_logBrowser);
ownCloudGui::raiseDialog(_logBrowser);
}
}
@@ -519,5 +532,42 @@ void ownCloudGui::slotHelp()
QDesktopServices::openUrl(QUrl(Theme::instance()->helpUrl()));
}
void ownCloudGui::raiseDialog( QWidget *raiseWidget )
{
if( raiseWidget && raiseWidget->parentWidget() == 0) {
// Qt has a bug which causes parent-less dialogs to pop-under.
raiseWidget->showNormal();
raiseWidget->raise();
raiseWidget->activateWindow();
}
#if defined(Q_OS_MAC)
// viel hilft viel ;-)
MacWindow::bringToFront(raiseWidget);
#endif
#if defined(Q_OS_X11)
WId wid = widget->winId();
NETWM::init();
XEvent e;
e.xclient.type = ClientMessage;
e.xclient.message_type = NETWM::NET_ACTIVE_WINDOW;
e.xclient.display = QX11Info::display();
e.xclient.window = wid;
e.xclient.format = 32;
e.xclient.data.l[0] = 2;
e.xclient.data.l[1] = QX11Info::appTime();
e.xclient.data.l[2] = 0;
e.xclient.data.l[3] = 0l;
e.xclient.data.l[4] = 0l;
Display *display = QX11Info::display();
XSendEvent(display,
RootWindow(display, DefaultScreen(display)),
False, // propagate
SubstructureRedirectMask|SubstructureNotifyMask,
&e);
#endif
}
} // end namespace
+2
Ver Arquivo
@@ -43,6 +43,8 @@ public:
bool checkAccountExists(bool openSettings);
static void raiseDialog( QWidget *raiseWidget );
signals:
void setupProxy();
+10
Ver Arquivo
@@ -124,6 +124,16 @@ QPixmap ownCloudTheme::wizardHeaderLogo() const
}
#endif
QString ownCloudTheme::appName() const
{
return QLatin1String("ownCloud");
}
QString ownCloudTheme::appNameGUI() const
{
return QLatin1String("ownCloud");
}
}
+3
Ver Arquivo
@@ -33,6 +33,9 @@ public:
QIcon trayFolderIcon( const QString& ) const;
QIcon folderDisabledIcon() const;
QIcon applicationIcon() const;
QString appName() const;
QString appNameGUI() const;
QVariant customMedia(CustomMediaType type);
QString helpUrl() const;
+53 -26
Ver Arquivo
@@ -27,7 +27,7 @@
namespace Mirall {
static uint chunkSize() {
static qint64 chunkSize() {
static uint chunkSize;
if (!chunkSize) {
chunkSize = qgetenv("OWNCLOUD_CHUNK_SIZE").toUInt();
@@ -73,7 +73,7 @@ void PUTFileJob::start() {
}
connect(reply(), SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(uploadProgress(qint64,qint64)));
connect(reply(), SIGNAL(uploadProgress(qint64,qint64)), this, SLOT(resetTimeout()));
connect(this, SIGNAL(networkActivity()), account(), SIGNAL(propagatorNetworkActivity()));
AbstractNetworkJob::start();
}
@@ -229,7 +229,7 @@ void PropagateUploadFileQNAM::startNextChunk()
currentChunkSize = chunkSize();
}
}
device = new ChunkDevice(_file, chunkSize() * sendingChunk, currentChunkSize);
device = new ChunkDevice(_file, chunkSize() * quint64(sendingChunk), currentChunkSize);
} else {
device = _file;
}
@@ -302,8 +302,10 @@ void PropagateUploadFileQNAM::slotPutFinished()
return;
}
if (Utility::qDateTimeToTime_t(fi.lastModified()) != _item._modtime) {
qDebug() << "The local file has changed during upload:" << _item._modtime << "!=" << Utility::qDateTimeToTime_t(fi.lastModified()) << fi.lastModified();
const time_t new_mtime = FileSystem::getModTime(fi.absoluteFilePath());
if (new_mtime != _item._modtime) {
qDebug() << "The local file has changed during upload:" << _item._modtime << "!=" << new_mtime
<< ", QFileInfo: " << Utility::qDateTimeToTime_t(fi.lastModified()) << fi.lastModified();
_propagator->_activeJobs--;
done(SyncFileItem::SoftError, tr("Local file changed during sync."));
// FIXME: the legacy code was retrying for a few seconds.
@@ -395,6 +397,12 @@ void PropagateUploadFileQNAM::abort()
///////////////////////////////////////////////////////////////////////////////////////////////////
void GETFileJob::start() {
if (_resumeStart > 0) {
_headers["Range"] = "bytes=" + QByteArray::number(_resumeStart) +'-';
_headers["Accept-Ranges"] = "bytes";
qDebug() << "Retry with range " << _headers["Range"];
}
QNetworkRequest req;
for(QMap<QByteArray, QByteArray>::const_iterator it = _headers.begin(); it != _headers.end(); ++it) {
req.setRawHeader(it.key(), it.value());
@@ -411,15 +419,22 @@ void GETFileJob::start() {
connect(reply(), SIGNAL(metaDataChanged()), this, SLOT(slotMetaDataChanged()));
connect(reply(), SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
connect(reply(), SIGNAL(downloadProgress(qint64,qint64)), this, SIGNAL(downloadProgress(qint64,qint64)));
connect(this, SIGNAL(networkActivity()), account(), SIGNAL(propagatorNetworkActivity()));
AbstractNetworkJob::start();
}
void GETFileJob::slotMetaDataChanged()
{
if (reply()->error() != QNetworkReply::NoError
|| reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() / 100 != 2) {
// We will handle the error when the job is finished.
int httpStatus = reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// If the status code isn't 2xx, don't write the reply body to the file.
// For any error: handle it when the job is finished, not here.
if (httpStatus / 100 != 2) {
_device->close();
return;
}
if (reply()->error() != QNetworkReply::NoError) {
return;
}
@@ -484,16 +499,17 @@ void GETFileJob::slotReadyRead()
return;
}
qint64 w = _device->write(buffer.constData(), r);
if (w != r) {
_errorString = _device->errorString();
_errorStatus = SyncFileItem::NormalError;
qDebug() << "Error while writing to file" << w << r << _errorString;
reply()->abort();
return;
if (_device->isOpen()) {
qint64 w = _device->write(buffer.constData(), r);
if (w != r) {
_errorString = _device->errorString();
_errorStatus = SyncFileItem::NormalError;
qDebug() << "Error while writing to file" << w << r << _errorString;
reply()->abort();
return;
}
}
}
resetTimeout();
}
void PropagateDownloadFileQNAM::start()
@@ -558,17 +574,13 @@ void PropagateDownloadFileQNAM::start()
/* Allow compressed content by setting the header */
//headers["Accept-Encoding"] = "gzip";
if (_tmpFile.size() > 0) {
quint64 done = _tmpFile.size();
if (done == _item._size) {
_startSize = _tmpFile.size();
if (_startSize > 0) {
if (_startSize == _item._size) {
qDebug() << "File is already complete, no need to download";
downloadFinished();
return;
}
headers["Range"] = "bytes=" + QByteArray::number(done) +'-';
headers["Accept-Ranges"] = "bytes";
qDebug() << "Retry with range " << headers["Range"];
_startSize = done;
}
_job = new GETFileJob(AccountManager::instance()->account(),
@@ -595,18 +607,33 @@ void PropagateDownloadFileQNAM::slotGetFinished()
QNetworkReply::NetworkError err = job->reply()->error();
if (err != QNetworkReply::NoError) {
if (_tmpFile.size() == 0) {
// don't keep the temporary file if it is empty.
_item._httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
// If we sent a 'Range' header and get 416 back, we want to retry
// without the header.
bool badRangeHeader = job->resumeStart() > 0 && _item._httpErrorCode == 416;
if (badRangeHeader) {
qDebug() << Q_FUNC_INFO << "server replied 416 to our range request, trying again without in next sync";
}
// Don't keep the temporary file if it is empty or we
// used a bad range header.
if (_tmpFile.size() == 0 || badRangeHeader) {
_tmpFile.close();
_tmpFile.remove();
_propagator->_journal->setDownloadInfo(_item._file, SyncJournalDb::DownloadInfo());
}
_item._httpErrorCode = job->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
_propagator->_activeJobs--;
SyncFileItem::Status status = job->errorStatus();
if (status == SyncFileItem::NoStatus) {
status = classifyError(err, _item._httpErrorCode);
}
if (badRangeHeader) {
// Can't do this in classifyError() because 416 without a
// Range header should result in NormalError.
status = SyncFileItem::SoftError;
}
done(status, job->errorString());
return;
}
+2
Ver Arquivo
@@ -133,6 +133,8 @@ public:
SyncFileItem::Status errorStatus() { return _errorStatus; }
quint64 resumeStart() const { return _resumeStart; }
virtual void slotTimeout();
+7
Ver Arquivo
@@ -46,6 +46,13 @@ SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent) :
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
_ui->setupUi(this);
// People perceive this as a Window, so also make Ctrl+W work
QAction *closeWindowAction = new QAction(this);
closeWindowAction->setShortcut(QKeySequence("Ctrl+W"));
connect(closeWindowAction, SIGNAL(triggered()), SLOT(accept()));
addAction(closeWindowAction);
setObjectName("Settings"); // required as group for saveGeometry call
setWindowTitle(tr("%1").arg(Theme::instance()->appNameGUI()));
+6 -1
Ver Arquivo
@@ -30,8 +30,13 @@ SettingsDialogMac::SettingsDialogMac(ownCloudGui *gui, QWidget *parent)
// Emulate dialog behavior: Escape means close
QAction *closeDialogAction = new QAction(this);
closeDialogAction->setShortcut(QKeySequence(Qt::Key_Escape));
connect(closeDialogAction, SIGNAL(triggered()), SLOT(close()));
addAction(closeDialogAction);
// People perceive this as a Window, so also make Ctrl+W work
QAction *closeWindowAction = new QAction(this);
closeWindowAction->setShortcut(QKeySequence(Qt::Key_Escape));
closeWindowAction->setShortcut(QKeySequence("Ctrl+W"));
connect(closeWindowAction, SIGNAL(triggered()), SLOT(close()));
addAction(closeWindowAction);
+5 -1
Ver Arquivo
@@ -176,6 +176,11 @@ void SslButton::updateAccountInfo(Account *account)
} else {
setVisible(true);
}
if(QMenu *oldMenu = menu()) {
oldMenu->hide(); // Need to be hidden because the QToolButton would be left in invalid state if the menu is deleted while it is visible
setMenu(0);
oldMenu->deleteLater(); // setMenu do not delete the previous menu.
}
if (account->url().scheme() == QLatin1String("https")) {
setIcon(QIcon(QPixmap(":/mirall/resources/lock-https.png")));
QSslCipher cipher = account->sslConfiguration().sessionCipher();
@@ -212,7 +217,6 @@ void SslButton::updateAccountInfo(Account *account)
} else {
setIcon(QIcon(QPixmap(":/mirall/resources/lock-http.png")));
setToolTip(tr("This connection is NOT secure as it is not encrypted.\n"));
setMenu(0);
}
}
-12
Ver Arquivo
@@ -164,18 +164,6 @@ QByteArray Utility::userAgentString()
.toLatin1();
}
void Utility::raiseDialog( QWidget *raiseWidget )
{
#ifndef TOKEN_AUTH_ONLY
if( raiseWidget && raiseWidget->parentWidget() == 0) {
// Qt has a bug which causes parent-less dialogs to pop-under.
raiseWidget->showNormal();
raiseWidget->raise();
raiseWidget->activateWindow();
}
#endif
}
bool Utility::hasLaunchOnStartup(const QString &appName)
{
return hasLaunchOnStartup_private(appName);
-1
Ver Arquivo
@@ -36,7 +36,6 @@ namespace Utility
OWNCLOUDSYNC_EXPORT QString octetsToString( qint64 octets );
OWNCLOUDSYNC_EXPORT QString platform();
OWNCLOUDSYNC_EXPORT QByteArray userAgentString();
OWNCLOUDSYNC_EXPORT void raiseDialog(QWidget *);
OWNCLOUDSYNC_EXPORT bool hasLaunchOnStartup(const QString &appName);
OWNCLOUDSYNC_EXPORT void setLaunchOnStartup(const QString &appName, const QString& guiName, bool launch);
OWNCLOUDSYNC_EXPORT qint64 freeDiskSpace(const QString &path, bool *ok = 0);
+5 -1
Ver Arquivo
@@ -16,6 +16,7 @@
#include <QDir>
#include <QFileDialog>
#include <QUrl>
#include <QTimer>
#include <QPushButton>
#include <QMessageBox>
@@ -145,9 +146,12 @@ void OwncloudSetupPage::initializePage()
if (Theme::instance()->overrideServerUrl().isEmpty()) {
_ui.leUrl->setFocus();
} else {
setVisible(false);
setCommitPage(true);
validatePage();
setVisible(false);
// because the wizard will call show on us right after this call, we need to hide in the
// next event loop iteration.
QTimer::singleShot(0, this, SLOT(hide()));
}
}
-1
Ver Arquivo
@@ -161,7 +161,6 @@ void OwncloudWizard::slotCurrentPageChanged( int id )
if( id == WizardCommon::Page_ServerSetup ) {
emit clearPendingRequests();
_setupPage->initializePage();
}
if( id == WizardCommon::Page_Result ) {