1
0
mirror of https://github.com/chylex/Nextcloud-Desktop.git synced 2026-04-12 14:57:41 +02:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Camila San
e0b32c19e4 Bump version to 2.6.0
Signed-off-by: Camila San <hello@camila.codes>
2019-09-27 17:01:24 +02:00
157 changed files with 22394 additions and 28067 deletions

View File

@@ -344,9 +344,10 @@ steps:
from_secret: DEBIAN_SECRET_IV from_secret: DEBIAN_SECRET_IV
trigger: trigger:
branch: branch:
- stable-2.6 - master
event: event:
- tag - pull_request
- push
--- ---
kind: pipeline kind: pipeline
name: Documentation name: Documentation

View File

@@ -198,7 +198,7 @@ X-GNOME-Autostart-Delay=3
# Translations # Translations
Icon[de_DE]=@APPLICATION_ICON_NAME@ Icon[de]=@APPLICATION_ICON_NAME@
Name[de_DE]=@APPLICATION_NAME@ Client zur Desktop-Synchronisation Name[de]=@APPLICATION_NAME@ Client zur Desktop-Synchronisation
Comment[de_DE]=@APPLICATION_NAME@ Client zur Desktop-Synchronisation Comment[de]=@APPLICATION_NAME@ Client zur Desktop-Synchronisation
GenericName[de_DE]=Synchronisationsordner GenericName[de]=Synchronisationsordner

View File

@@ -203,16 +203,8 @@ if( WIN32 )
add_definitions( -D__USE_MINGW_ANSI_STDIO=1 ) add_definitions( -D__USE_MINGW_ANSI_STDIO=1 )
add_definitions( -DNOMINMAX ) add_definitions( -DNOMINMAX )
# Get APIs from from Vista onwards. # Get APIs from from Vista onwards.
add_definitions( -D_WIN32_WINNT=0x0601 ) add_definitions( -D_WIN32_WINNT=0x0600)
add_definitions( -DWINVER=0x0601 ) add_definitions( -DWINVER=0x0600)
if( MSVC )
# Use automatic overload for suitable CRT safe-functions
# See https://docs.microsoft.com/de-de/cpp/c-runtime-library/security-features-in-the-crt?view=vs-2019
add_definitions( -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 )
# Also: Disable compiler warnings because we don't use Windows CRT safe-functions explicitly and don't intend to
# as this is a pure cross-platform source the only alternative would be a ton of ifdefs with calls to the _s version
add_definitions( -D_CRT_SECURE_NO_WARNINGS )
endif( MSVC )
endif( WIN32 ) endif( WIN32 )
if (APPLE) if (APPLE)

View File

@@ -1,6 +1,6 @@
set( MIRALL_VERSION_MAJOR 2 ) set( MIRALL_VERSION_MAJOR 2 )
set( MIRALL_VERSION_MINOR 6 ) set( MIRALL_VERSION_MINOR 6 )
set( MIRALL_VERSION_PATCH 1 ) set( MIRALL_VERSION_PATCH 0 )
set( MIRALL_VERSION_YEAR 2019 ) set( MIRALL_VERSION_YEAR 2019 )
set( MIRALL_SOVERSION 0 ) set( MIRALL_SOVERSION 0 )

View File

@@ -7,6 +7,7 @@ Build-Depends: cmake,
cdbs, cdbs,
dh-python, dh-python,
extra-cmake-modules (>= 5.16), extra-cmake-modules (>= 5.16),
kdelibs5-dev,
libkf5kio-dev, libkf5kio-dev,
libcmocka-dev, libcmocka-dev,
libhttp-dav-perl, libhttp-dav-perl,

View File

@@ -32,12 +32,11 @@ FRAMEWORK_SEARCH_PATH=[
os.path.join(os.environ['HOME'], 'Library/Frameworks') os.path.join(os.environ['HOME'], 'Library/Frameworks')
] ]
LIBRARY_SEARCH_PATH=['/usr/local/lib', '/usr/local/Qt-5.12.5/lib', '.'] LIBRARY_SEARCH_PATH=['/usr/local/lib', '/usr/local/Qt-5.6.2/lib', '.']
QT_PLUGINS = [ QT_PLUGINS = [
'sqldrivers/libqsqlite.dylib', 'sqldrivers/libqsqlite.dylib',
'platforms/libqcocoa.dylib', 'platforms/libqcocoa.dylib',
'styles/libqmacstyle.dylib',
'imageformats/libqgif.dylib', 'imageformats/libqgif.dylib',
'imageformats/libqico.dylib', 'imageformats/libqico.dylib',
'imageformats/libqjpeg.dylib', 'imageformats/libqjpeg.dylib',
@@ -47,7 +46,7 @@ QT_PLUGINS = [
QT_PLUGINS_SEARCH_PATH=[ QT_PLUGINS_SEARCH_PATH=[
# os.path.join(os.environ['QTDIR'], 'plugins'), # os.path.join(os.environ['QTDIR'], 'plugins'),
# '/usr/local/Cellar/qt/5.2.1/plugins', # '/usr/local/Cellar/qt/5.2.1/plugins',
'/usr/local/Qt-5.12.5/plugins', '/usr/local/Qt-5.6.2/plugins',
] ]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 151 KiB

2
binary

Submodule binary updated: 09f12de312...3425fab2c6

View File

@@ -3,11 +3,7 @@
# For details see the accompanying COPYING* file. # For details see the accompanying COPYING* file.
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long -Wno-gnu-zero-variadic-macro-arguments")
# Use this only for Clang
if (CMAKE_CXX_COMPILER MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-long-long -Wno-gnu-zero-variadic-macro-arguments")
endif()
# Fix sqlite compilation on macOS # Fix sqlite compilation on macOS
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-incompatible-pointer-types-discards-qualifiers") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-incompatible-pointer-types-discards-qualifiers")

View File

@@ -89,7 +89,7 @@ IFACEMETHODIMP OCContextMenu::Initialize(
HDROP hDrop = static_cast<HDROP>(GlobalLock(stm.hGlobal)); HDROP hDrop = static_cast<HDROP>(GlobalLock(stm.hGlobal));
if (hDrop) { if (hDrop) {
UINT nFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); UINT nFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
for (UINT i = 0; i < nFiles; ++i) { for (int i = 0; i < nFiles; ++i) {
// Get the path of the file. // Get the path of the file.
wchar_t buffer[MAX_PATH]; wchar_t buffer[MAX_PATH];

View File

@@ -5,8 +5,6 @@
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
// Note: Here was a #define for windows target version #define WINVER 0x0501
// e.g. WINVER / _WIN32_WINNT, see https://devblogs.microsoft.com/oldnewthing/20070411-00/?p=27283 #define _WIN32_WINNT 0x0501
// Unnecessary because we define both in desktop/CMakeLists.txt
#include <SDKDDKVer.h> #include <SDKDDKVer.h>

View File

@@ -13,10 +13,8 @@
*/ */
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define WINVER 0x0501
// Note: Here was a #define for windows target version #define _WIN32_WINNT 0x0501
// e.g. WINVER / _WIN32_WINNT, see https://devblogs.microsoft.com/oldnewthing/20070411-00/?p=27283
// Unnecessary because we define both in desktop/CMakeLists.txt
#include "CommunicationSocket.h" #include "CommunicationSocket.h"
#include "RegistryUtil.h" #include "RegistryUtil.h"

View File

@@ -1,9 +1,7 @@
#pragma once #pragma once
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define WINVER 0x0501
// Note: Here was a #define for windows target version #define _WIN32_WINNT 0x0501
// e.g. WINVER / _WIN32_WINNT, see https://devblogs.microsoft.com/oldnewthing/20070411-00/?p=27283
// Unnecessary because we define both in desktop/CMakeLists.txt
#include <windows.h> #include <windows.h>

View File

@@ -33,8 +33,8 @@ endif()
if(WIN32) if(WIN32)
# Enable DEP & ASLR # Enable DEP & ASLR
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /nxcompat /dynamicbase") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /nxcompat /dynamicbase") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--nxcompat -Wl,--dynamicbase")
elseif(UNIX AND NOT APPLE) elseif(UNIX AND NOT APPLE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now")

View File

@@ -11,50 +11,43 @@
// For overloading macros by argument count // For overloading macros by argument count
// See stackoverflow.com/questions/16683146/can-macros-be-overloaded-by-number-of-arguments // See stackoverflow.com/questions/16683146/can-macros-be-overloaded-by-number-of-arguments
// Bugfix 08/09/2019: Broken arg expansion led to always collapsing to 1 arg (XXXX_1 overload result) #define OC_ASSERT_CAT(A, B) A##B
// See also: https://stackoverflow.com/questions/9183993/msvc-variadic-macro-expansion #define OC_ASSERT_SELECT(NAME, NUM) OC_ASSERT_CAT(NAME##_, NUM)
#define OC_ASSERT_GLUE(x, y) x y
#define OC_ASSERT_GET_COUNT(_1, _2, _3, COUNT, ...) COUNT #define OC_ASSERT_GET_COUNT(_1, _2, _3, COUNT, ...) COUNT
#define OC_ASSERT_EXPAND_ARGS(args) OC_ASSERT_GET_COUNT args #define OC_ASSERT_VA_SIZE(...) OC_ASSERT_GET_COUNT(__VA_ARGS__, 3, 2, 1, 0)
#define OC_ASSERT_VA_SIZE(...) OC_ASSERT_EXPAND_ARGS((__VA_ARGS__, 3, 2, 1, 0))
#define OC_ASSERT_SELECT2(NAME, COUNT) NAME##COUNT #define OC_ASSERT_OVERLOAD(NAME, ...) OC_ASSERT_SELECT(NAME, OC_ASSERT_VA_SIZE(__VA_ARGS__)) \
#define OC_ASSERT_SELECT1(NAME, COUNT) OC_ASSERT_SELECT2(NAME, COUNT) (__VA_ARGS__)
#define OC_ASSERT_SELECT(NAME, COUNT) OC_ASSERT_SELECT1(NAME, COUNT)
#define OC_ASSERT_OVERLOAD(NAME, ...) OC_ASSERT_GLUE(OC_ASSERT_SELECT(NAME, OC_ASSERT_VA_SIZE(__VA_ARGS__)), \
(__VA_ARGS__))
// Default assert: If the condition is false in debug builds, terminate. // Default assert: If the condition is false in debug builds, terminate.
// //
// Prints a message on failure, even in release builds. // Prints a message on failure, even in release builds.
#define ASSERT1(cond) \ #define ASSERT(...) OC_ASSERT_OVERLOAD(ASSERT, __VA_ARGS__)
#define ASSERT_1(cond) \
if (!(cond)) { \ if (!(cond)) { \
OC_ASSERT_MSG("ASSERT: \"%s\" in file %s, line %d", #cond, __FILE__, __LINE__); \ OC_ASSERT_MSG("ASSERT: \"%s\" in file %s, line %d", #cond, __FILE__, __LINE__); \
} else { \ } else { \
} }
#define ASSERT2(cond, message) \ #define ASSERT_2(cond, message) \
if (!(cond)) { \ if (!(cond)) { \
OC_ASSERT_MSG("ASSERT: \"%s\" in file %s, line %d with message: %s", #cond, __FILE__, __LINE__, message); \ OC_ASSERT_MSG("ASSERT: \"%s\" in file %s, line %d with message: %s", #cond, __FILE__, __LINE__, message); \
} else { \ } else { \
} }
#define ASSERT(...) OC_ASSERT_OVERLOAD(ASSERT, __VA_ARGS__)
// Enforce condition to be true, even in release builds. // Enforce condition to be true, even in release builds.
// //
// Prints 'message' and aborts execution if 'cond' is false. // Prints 'message' and aborts execution if 'cond' is false.
#define ENFORCE1(cond) \ #define ENFORCE(...) OC_ASSERT_OVERLOAD(ENFORCE, __VA_ARGS__)
#define ENFORCE_1(cond) \
if (!(cond)) { \ if (!(cond)) { \
qFatal("ENFORCE: \"%s\" in file %s, line %d", #cond, __FILE__, __LINE__); \ qFatal("ENFORCE: \"%s\" in file %s, line %d", #cond, __FILE__, __LINE__); \
} else { \ } else { \
} }
#define ENFORCE2(cond, message) \ #define ENFORCE_2(cond, message) \
if (!(cond)) { \ if (!(cond)) { \
qFatal("ENFORCE: \"%s\" in file %s, line %d with message: %s", #cond, __FILE__, __LINE__, message); \ qFatal("ENFORCE: \"%s\" in file %s, line %d with message: %s", #cond, __FILE__, __LINE__, message); \
} else { \ } else { \
} }
#define ENFORCE(...) OC_ASSERT_OVERLOAD(ENFORCE, __VA_ARGS__)
// An assert that is only present in debug builds: typically used for // An assert that is only present in debug builds: typically used for
// asserts that are too expensive for release mode. // asserts that are too expensive for release mode.

View File

@@ -207,10 +207,7 @@ static inline uint64_t c_jhash64(const uint8_t *k, uint64_t length, uint64_t int
/* handle the last 23 bytes */ /* handle the last 23 bytes */
c += length; c += length;
switch(len) { switch(len) {
// pragma only for GCC (and clang continues to pretend to be it by defining __GNUC__)
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
case 23: c+=((uint64_t)k[22]<<56); case 23: c+=((uint64_t)k[22]<<56);
case 22: c+=((uint64_t)k[21]<<48); case 22: c+=((uint64_t)k[21]<<48);
case 21: c+=((uint64_t)k[20]<<40); case 21: c+=((uint64_t)k[20]<<40);

View File

@@ -281,8 +281,8 @@ int SqlQuery::prepare(const QByteArray &sql, bool allow_failure)
*/ */
static bool startsWithInsensitive(const QByteArray &a, const char *b) static bool startsWithInsensitive(const QByteArray &a, const char *b)
{ {
size_t len = strlen(b); int len = strlen(b);
return a.size() >= len && qstrnicmp(a.constData(), b, Utility::convertSizeToUint(len)) == 0; return a.size() >= len && qstrnicmp(a.constData(), b, len) == 0;
} }
bool SqlQuery::isSelect() bool SqlQuery::isSelect()

View File

@@ -103,7 +103,6 @@ public:
: _chunk(0) : _chunk(0)
, _transferid(0) , _transferid(0)
, _size(0) , _size(0)
, _modtime(0)
, _errorCount(0) , _errorCount(0)
, _valid(false) , _valid(false)
{ {

View File

@@ -396,26 +396,6 @@ void Utility::crash()
*a = 1; *a = 1;
} }
// Use this functions to retrieve uint/int (often required by Qt and WIN32) from size_t
// without compiler warnings about possible truncation
uint Utility::convertSizeToUint(size_t &convertVar)
{
if( convertVar > UINT_MAX ) {
//throw std::bad_cast();
convertVar = UINT_MAX; // intentionally default to wrong value here to not crash: exception handling TBD
}
return static_cast<uint>(convertVar);
}
uint Utility::convertSizeToInt(size_t &convertVar)
{
if( convertVar > INT_MAX ) {
//throw std::bad_cast();
convertVar = INT_MAX; // intentionally default to wrong value here to not crash: exception handling TBD
}
return static_cast<int>(convertVar);
}
// read the output of the owncloud --version command from the owncloud // read the output of the owncloud --version command from the owncloud
// version that is on disk. This works for most versions of the client, // version that is on disk. This works for most versions of the client,
// because clients that do not yet know the --version flag return the // because clients that do not yet know the --version flag return the

View File

@@ -55,12 +55,6 @@ namespace Utility {
OCSYNC_EXPORT QByteArray userAgentString(); OCSYNC_EXPORT QByteArray userAgentString();
OCSYNC_EXPORT bool hasLaunchOnStartup(const QString &appName); OCSYNC_EXPORT bool hasLaunchOnStartup(const QString &appName);
OCSYNC_EXPORT void setLaunchOnStartup(const QString &appName, const QString &guiName, bool launch); OCSYNC_EXPORT void setLaunchOnStartup(const QString &appName, const QString &guiName, bool launch);
OCSYNC_EXPORT uint convertSizeToUint(size_t &convertVar);
OCSYNC_EXPORT uint convertSizeToInt(size_t &convertVar);
#ifdef Q_OS_WIN
OCSYNC_EXPORT DWORD convertSizeToDWORD(size_t &convertVar);
#endif
/** /**
* Return the amount of free space available. * Return the amount of free space available.

View File

@@ -90,13 +90,32 @@ void setLaunchOnStartup_private(const QString &appName, const QString &guiName,
// TODO: Right now only detection on toggle/startup, not when windows theme is switched while nextcloud is running // TODO: Right now only detection on toggle/startup, not when windows theme is switched while nextcloud is running
static inline bool hasDarkSystray_private() static inline bool hasDarkSystray_private()
{ {
if(Utility::registryGetKeyValue( HKEY_CURRENT_USER, bool hasDarkSystray = true;
"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", // Open registry key first, continue only on success (may be legitimately absent in earlier windows versions)
"SystemUsesLightTheme" ) == 1) { HKEY hKey;
return false; LONG lRes = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey);
}
else { // classical windows function - preserve buff size for DWORD, call ExW version, store regkey value in nResult
return true; if (lRes == ERROR_SUCCESS) {
DWORD dwBufferSize(sizeof(DWORD));
DWORD nResult(0);
// https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw
LONG nError = ::RegQueryValueExW(hKey,
L"SystemUsesLightTheme",
NULL,
NULL,
reinterpret_cast<LPBYTE>(&nResult),
&dwBufferSize);
// if RegQuery returned no error and light theme was found, change systray return value
if (nError == ERROR_SUCCESS && nResult == 1)
hasDarkSystray = false;
return hasDarkSystray;
} else {
// fallback to true if regkey could not be determined
return hasDarkSystray;
} }
} }
@@ -264,13 +283,4 @@ bool Utility::registryWalkSubKeys(HKEY hRootKey, const QString &subKey, const st
return retCode != ERROR_NO_MORE_ITEMS; return retCode != ERROR_NO_MORE_ITEMS;
} }
DWORD Utility::convertSizeToDWORD(size_t &convertVar)
{
if( convertVar > UINT_MAX ) {
//throw std::bad_cast();
convertVar = UINT_MAX; // intentionally default to wrong value here to not crash: exception handling TBD
}
return static_cast<DWORD>(convertVar);
}
} // namespace OCC } // namespace OCC

View File

@@ -73,7 +73,7 @@ static void csync_exclude_expand_escapes(QByteArray &input)
line[o++] = line[i]; line[o++] = line[i];
} }
} }
input.resize(OCC::Utility::convertSizeToUint(o)); input.resize(o);
} }
// See http://support.microsoft.com/kb/74496 and // See http://support.microsoft.com/kb/74496 and
@@ -322,11 +322,7 @@ bool ExcludedFiles::loadExcludeFile(const QByteArray & basePath, const QString &
csync_exclude_expand_escapes(line); csync_exclude_expand_escapes(line);
_allExcludes[basePath].append(line); _allExcludes[basePath].append(line);
} }
prepare(basePath);
// nothing to prepare if the user decided to not exclude anything
if(_allExcludes.size())
prepare(basePath);
return true; return true;
} }
@@ -342,8 +338,8 @@ bool ExcludedFiles::reloadExcludeFiles()
_fullRegexDir.clear(); _fullRegexDir.clear();
bool success = true; bool success = true;
for (const auto& basePath : _excludeFiles.keys()) { for (auto basePath : _excludeFiles.keys()) {
for (const auto& file : _excludeFiles.value(basePath)) { for (auto file : _excludeFiles.value(basePath)) {
success = loadExcludeFile(basePath, file); success = loadExcludeFile(basePath, file);
} }
} }

View File

@@ -724,8 +724,7 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
if (ctx->current == LOCAL_REPLICA) { if (ctx->current == LOCAL_REPLICA) {
ASSERT(dirent->path.startsWith(ctx->local.uri)); // path is relative to uri ASSERT(dirent->path.startsWith(ctx->local.uri)); // path is relative to uri
// "len + 1" to include the slash in-between. // "len + 1" to include the slash in-between.
size_t uriLength = strlen(ctx->local.uri); dirent->path = dirent->path.mid(strlen(ctx->local.uri) + 1);
dirent->path = dirent->path.mid(OCC::Utility::convertSizeToInt(uriLength) + 1);
} }
previous_fs = ctx->current_fs; previous_fs = ctx->current_fs;

View File

@@ -38,7 +38,6 @@
#include "c_alloc.h" #include "c_alloc.h"
#include "c_string.h" #include "c_string.h"
#include "common/filesystembase.h" #include "common/filesystembase.h"
#include "common/utility.h"
/* Convert a locale String to UTF8 */ /* Convert a locale String to UTF8 */
QByteArray c_utf8_from_locale(const mbchar_t *wstr) QByteArray c_utf8_from_locale(const mbchar_t *wstr)
@@ -53,10 +52,10 @@ QByteArray c_utf8_from_locale(const mbchar_t *wstr)
size_t len; size_t len;
len = wcslen(wstr); len = wcslen(wstr);
/* Call once to get the required size. */ /* Call once to get the required size. */
size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, OCC::Utility::convertSizeToInt(len), NULL, 0, NULL, NULL); size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, len, NULL, 0, NULL, NULL);
if (size_needed > 0) { if (size_needed > 0) {
dst.resize(size_needed); dst.resize(size_needed);
WideCharToMultiByte(CP_UTF8, 0, wstr, OCC::Utility::convertSizeToInt(len), dst.data(), size_needed, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, wstr, len, dst.data(), size_needed, NULL, NULL);
} }
return dst; return dst;
#else #else
@@ -96,7 +95,7 @@ mbchar_t* c_utf8_string_to_locale(const char *str)
int size_needed; int size_needed;
len = strlen(str); len = strlen(str);
size_needed = MultiByteToWideChar(CP_UTF8, 0, str, OCC::Utility::convertSizeToInt(len), NULL, 0); size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
if (size_needed > 0) { if (size_needed > 0) {
int size_char = (size_needed + 1) * sizeof(mbchar_t); int size_char = (size_needed + 1) * sizeof(mbchar_t);
dst = (mbchar_t*)c_malloc(size_char); dst = (mbchar_t*)c_malloc(size_char);
@@ -115,8 +114,7 @@ mbchar_t* c_utf8_string_to_locale(const char *str)
return NULL; return NULL;
} else { } else {
#ifdef _WIN32 #ifdef _WIN32
size_t strLength = strlen(str); QByteArray unc_str = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(str, strlen(str)));
QByteArray unc_str = OCC::FileSystem::pathtoUNC(QByteArray::fromRawData(str, OCC::Utility::convertSizeToInt(strLength)));
mbchar_t *dst = c_utf8_string_to_locale(unc_str); mbchar_t *dst = c_utf8_string_to_locale(unc_str);
return dst; return dst;
#else #else

View File

@@ -57,7 +57,7 @@ csync_vio_handle_t *csync_vio_local_opendir(const char *name) {
handle = (dhandle_t*)c_malloc(sizeof(dhandle_t)); handle = (dhandle_t*)c_malloc(sizeof(dhandle_t));
// the file wildcard has to be attached // the file wildcard has to be attached
size_t len_name = strlen(name); int len_name = strlen(name);
if( len_name ) { if( len_name ) {
char *h = NULL; char *h = NULL;

View File

@@ -104,7 +104,6 @@ set(client_SRCS
guiutility.cpp guiutility.cpp
elidedlabel.cpp elidedlabel.cpp
iconjob.cpp iconjob.cpp
remotewipe.cpp
creds/credentialsfactory.cpp creds/credentialsfactory.cpp
creds/httpcredentialsgui.cpp creds/httpcredentialsgui.cpp
creds/oauth.cpp creds/oauth.cpp
@@ -182,9 +181,6 @@ if (APPLE)
../3rdparty/qtmacgoodies/src/macstandardicon.mm ../3rdparty/qtmacgoodies/src/macstandardicon.mm
../3rdparty/qtmacgoodies/src/macwindow.mm ../3rdparty/qtmacgoodies/src/macwindow.mm
) )
# We want to access Cocoa specific structures in the code above
# and need the platform plugin interface for that - which is private.
include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS})
endif() endif()
if(NOT WIN32) if(NOT WIN32)

View File

@@ -368,7 +368,6 @@ void AccountManager::shutdown()
_accounts.clear(); _accounts.clear();
foreach (const auto &acc, accountsCopy) { foreach (const auto &acc, accountsCopy) {
emit accountRemoved(acc.data()); emit accountRemoved(acc.data());
emit removeAccountFolders(acc.data());
} }
} }

View File

@@ -70,6 +70,7 @@ public:
*/ */
void deleteAccount(AccountState *account); void deleteAccount(AccountState *account);
/** /**
* Creates an account and sets up some basic handlers. * Creates an account and sets up some basic handlers.
* Does *not* add the account to the account manager just yet. * Does *not* add the account to the account manager just yet.
@@ -103,7 +104,6 @@ public slots:
Q_SIGNALS: Q_SIGNALS:
void accountAdded(AccountState *account); void accountAdded(AccountState *account);
void accountRemoved(AccountState *account); void accountRemoved(AccountState *account);
void removeAccountFolders(AccountState *account);
private: private:
AccountManager() {} AccountManager() {}

View File

@@ -147,8 +147,6 @@ AccountSettings::AccountSettings(AccountState *accountState, QWidget *parent)
createAccountToolbox(); createAccountToolbox();
connect(AccountManager::instance(), &AccountManager::accountAdded, connect(AccountManager::instance(), &AccountManager::accountAdded,
this, &AccountSettings::slotAccountAdded); this, &AccountSettings::slotAccountAdded);
connect(this, &AccountSettings::removeAccountFolders,
AccountManager::instance(), &AccountManager::removeAccountFolders);
connect(ui->_folderList, &QWidget::customContextMenuRequested, connect(ui->_folderList, &QWidget::customContextMenuRequested,
this, &AccountSettings::slotCustomContextMenuRequested); this, &AccountSettings::slotCustomContextMenuRequested);
connect(ui->_folderList, &QAbstractItemView::clicked, connect(ui->_folderList, &QAbstractItemView::clicked,
@@ -336,9 +334,9 @@ void AccountSettings::slotEncryptionFlagError(const QByteArray& fileId, int http
void AccountSettings::slotLockForEncryptionSuccess(const QByteArray& fileId, const QByteArray &token) void AccountSettings::slotLockForEncryptionSuccess(const QByteArray& fileId, const QByteArray &token)
{ {
accountsState()->account()->e2e()->setTokenForFolder(fileId, token); accountsState()->account()->e2e()->setTokenForFolder(fileId, token);
FolderMetadata emptyMetadata(accountsState()->account()); FolderMetadata emptyMetadata(accountsState()->account());
auto encryptedMetadata = emptyMetadata.encryptedMetadata(); auto encryptedMetadata = emptyMetadata.encryptedMetadata();
if (encryptedMetadata.isEmpty()) { if (encryptedMetadata.isEmpty()) {
//TODO: Mark the folder as unencrypted as the metadata generation failed. //TODO: Mark the folder as unencrypted as the metadata generation failed.
@@ -350,36 +348,36 @@ void AccountSettings::slotLockForEncryptionSuccess(const QByteArray& fileId, con
return; return;
} }
auto storeMetadataJob = new StoreMetaDataApiJob(accountsState()->account(), fileId, emptyMetadata.encryptedMetadata()); auto storeMetadataJob = new StoreMetaDataApiJob(accountsState()->account(), fileId, emptyMetadata.encryptedMetadata());
connect(storeMetadataJob, &StoreMetaDataApiJob::success, connect(storeMetadataJob, &StoreMetaDataApiJob::success,
this, &AccountSettings::slotUploadMetadataSuccess); this, &AccountSettings::slotUploadMetadataSuccess);
connect(storeMetadataJob, &StoreMetaDataApiJob::error, connect(storeMetadataJob, &StoreMetaDataApiJob::error,
this, &AccountSettings::slotUpdateMetadataError); this, &AccountSettings::slotUpdateMetadataError);
storeMetadataJob->start(); storeMetadataJob->start();
} }
void AccountSettings::slotUploadMetadataSuccess(const QByteArray& folderId) void AccountSettings::slotUploadMetadataSuccess(const QByteArray& folderId)
{ {
const auto token = accountsState()->account()->e2e()->tokenForFolder(folderId); const auto token = accountsState()->account()->e2e()->tokenForFolder(folderId);
auto unlockJob = new UnlockEncryptFolderApiJob(accountsState()->account(), folderId, token); auto unlockJob = new UnlockEncryptFolderApiJob(accountsState()->account(), folderId, token);
connect(unlockJob, &UnlockEncryptFolderApiJob::success, connect(unlockJob, &UnlockEncryptFolderApiJob::success,
this, &AccountSettings::slotUnlockFolderSuccess); this, &AccountSettings::slotUnlockFolderSuccess);
connect(unlockJob, &UnlockEncryptFolderApiJob::error, connect(unlockJob, &UnlockEncryptFolderApiJob::error,
this, &AccountSettings::slotUnlockFolderError); this, &AccountSettings::slotUnlockFolderError);
unlockJob->start(); unlockJob->start();
} }
void AccountSettings::slotUpdateMetadataError(const QByteArray& folderId, int httpReturnCode) void AccountSettings::slotUpdateMetadataError(const QByteArray& folderId, int httpReturnCode)
{ {
Q_UNUSED(httpReturnCode); Q_UNUSED(httpReturnCode);
const auto token = accountsState()->account()->e2e()->tokenForFolder(folderId); const auto token = accountsState()->account()->e2e()->tokenForFolder(folderId);
auto unlockJob = new UnlockEncryptFolderApiJob(accountsState()->account(), folderId, token); auto unlockJob = new UnlockEncryptFolderApiJob(accountsState()->account(), folderId, token);
connect(unlockJob, &UnlockEncryptFolderApiJob::success, connect(unlockJob, &UnlockEncryptFolderApiJob::success,
this, &AccountSettings::slotUnlockFolderSuccess); this, &AccountSettings::slotUnlockFolderSuccess);
connect(unlockJob, &UnlockEncryptFolderApiJob::error, connect(unlockJob, &UnlockEncryptFolderApiJob::error,
this, &AccountSettings::slotUnlockFolderError); this, &AccountSettings::slotUnlockFolderError);
unlockJob->start(); unlockJob->start();
} }
void AccountSettings::slotLockForEncryptionError(const QByteArray& fileId, int httpErrorCode) void AccountSettings::slotLockForEncryptionError(const QByteArray& fileId, int httpErrorCode)

View File

@@ -63,7 +63,6 @@ signals:
void openFolderAlias(const QString &); void openFolderAlias(const QString &);
void showIssuesList(AccountState *account); void showIssuesList(AccountState *account);
void requesetMnemonic(); void requesetMnemonic();
void removeAccountFolders(AccountState *account);
public slots: public slots:
void slotOpenOC(); void slotOpenOC();

View File

@@ -187,7 +187,7 @@
<item row="0" column="2"> <item row="0" column="2">
<widget class="QToolButton" name="_accountToolbox"> <widget class="QToolButton" name="_accountToolbox">
<property name="text"> <property name="text">
<string notr="true">...</string> <string>...</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@@ -14,7 +14,6 @@
#include "accountstate.h" #include "accountstate.h"
#include "accountmanager.h" #include "accountmanager.h"
#include "remotewipe.h"
#include "account.h" #include "account.h"
#include "creds/abstractcredentials.h" #include "creds/abstractcredentials.h"
#include "creds/httpcredentials.h" #include "creds/httpcredentials.h"
@@ -25,11 +24,6 @@
#include <QTimer> #include <QTimer>
#include <qfontmetrics.h> #include <qfontmetrics.h>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkRequest>
#include <QBuffer>
namespace OCC { namespace OCC {
Q_LOGGING_CATEGORY(lcAccountState, "nextcloud.gui.account.state", QtInfoMsg) Q_LOGGING_CATEGORY(lcAccountState, "nextcloud.gui.account.state", QtInfoMsg)
@@ -42,12 +36,11 @@ AccountState::AccountState(AccountPtr account)
, _waitingForNewCredentials(false) , _waitingForNewCredentials(false)
, _notificationsEtagResponseHeader("*") , _notificationsEtagResponseHeader("*")
, _maintenanceToConnectedDelay(60000 + (qrand() % (4 * 60000))) // 1-5min delay , _maintenanceToConnectedDelay(60000 + (qrand() % (4 * 60000))) // 1-5min delay
, _remoteWipe(new RemoteWipe(_account))
{ {
qRegisterMetaType<AccountState *>("AccountState*"); qRegisterMetaType<AccountState *>("AccountState*");
connect(account.data(), &Account::invalidCredentials, connect(account.data(), &Account::invalidCredentials,
this, &AccountState::slotHandleRemoteWipeCheck); this, &AccountState::slotInvalidCredentials);
connect(account.data(), &Account::credentialsFetched, connect(account.data(), &Account::credentialsFetched,
this, &AccountState::slotCredentialsFetched); this, &AccountState::slotCredentialsFetched);
connect(account.data(), &Account::credentialsAsked, connect(account.data(), &Account::credentialsAsked,
@@ -310,7 +303,7 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
break; break;
case ConnectionValidator::CredentialsWrong: case ConnectionValidator::CredentialsWrong:
case ConnectionValidator::CredentialsNotReady: case ConnectionValidator::CredentialsNotReady:
handleInvalidCredentials(); slotInvalidCredentials();
break; break;
case ConnectionValidator::SslError: case ConnectionValidator::SslError:
setState(SignedOut); setState(SignedOut);
@@ -329,20 +322,7 @@ void AccountState::slotConnectionValidatorResult(ConnectionValidator::Status sta
} }
} }
void AccountState::slotHandleRemoteWipeCheck() void AccountState::slotInvalidCredentials()
{
// make sure it changes account state and icons
signOutByUi();
qCInfo(lcAccountState) << "Invalid credentials for" << _account->url().toString()
<< "checking for remote wipe request";
_waitingForNewCredentials = false;
setState(SignedOut);
}
void AccountState::handleInvalidCredentials()
{ {
if (isSignedOut() || _waitingForNewCredentials) if (isSignedOut() || _waitingForNewCredentials)
return; return;
@@ -363,7 +343,6 @@ void AccountState::handleInvalidCredentials()
account()->credentials()->askFromUser(); account()->credentials()->askFromUser();
} }
void AccountState::slotCredentialsFetched(AbstractCredentials *) void AccountState::slotCredentialsFetched(AbstractCredentials *)
{ {
// Make a connection attempt, no matter whether the credentials are // Make a connection attempt, no matter whether the credentials are

View File

@@ -29,7 +29,6 @@ namespace OCC {
class AccountState; class AccountState;
class Account; class Account;
class RemoteWipe;
typedef QExplicitlySharedDataPointer<AccountState> AccountStatePtr; typedef QExplicitlySharedDataPointer<AccountState> AccountStatePtr;
@@ -151,9 +150,6 @@ public:
*/ */
void setNavigationAppsEtagResponseHeader(const QByteArray &value); void setNavigationAppsEtagResponseHeader(const QByteArray &value);
///Asks for user credentials
void handleInvalidCredentials();
public slots: public slots:
/// Triggers a ping to the server to update state and /// Triggers a ping to the server to update state and
/// connection status and errors. /// connection status and errors.
@@ -168,11 +164,7 @@ signals:
protected Q_SLOTS: protected Q_SLOTS:
void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList &errors); void slotConnectionValidatorResult(ConnectionValidator::Status status, const QStringList &errors);
void slotInvalidCredentials();
/// When client gets a 401 or 403 checks if server requested remote wipe
/// before asking for user credentials again
void slotHandleRemoteWipeCheck();
void slotCredentialsFetched(AbstractCredentials *creds); void slotCredentialsFetched(AbstractCredentials *creds);
void slotCredentialsAsked(AbstractCredentials *creds); void slotCredentialsAsked(AbstractCredentials *creds);
@@ -198,13 +190,6 @@ private:
* Milliseconds for which to delay reconnection after 503/maintenance. * Milliseconds for which to delay reconnection after 503/maintenance.
*/ */
int _maintenanceToConnectedDelay; int _maintenanceToConnectedDelay;
/**
* Connects remote wipe check with the account
* the log out triggers the check (loads app password -> create request)
*/
RemoteWipe *_remoteWipe;
}; };
} }

View File

@@ -26,8 +26,6 @@
#include <QPainter> #include <QPainter>
#include <QApplication> #include <QApplication>
#define HASQT5_11 (QT_VERSION >= QT_VERSION_CHECK(5,11,0))
namespace OCC { namespace OCC {
int ActivityItemDelegate::_iconHeight = 0; int ActivityItemDelegate::_iconHeight = 0;
@@ -108,11 +106,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
// subject text rect // subject text rect
QRect actionTextBox = actionIconRect; QRect actionTextBox = actionIconRect;
#if (HASQT5_11)
int actionTextBoxWidth = fm.horizontalAdvance(actionText);
#else
int actionTextBoxWidth = fm.width(actionText); int actionTextBoxWidth = fm.width(actionText);
#endif
actionTextBox.setTop(option.rect.top() + margin + offset/2); actionTextBox.setTop(option.rect.top() + margin + offset/2);
actionTextBox.setHeight(fm.height()); actionTextBox.setHeight(fm.height());
actionTextBox.setLeft(actionIconRect.right() + margin); actionTextBox.setLeft(actionIconRect.right() + margin);
@@ -120,11 +114,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
// message text rect // message text rect
QRect messageTextBox = actionTextBox; QRect messageTextBox = actionTextBox;
#if (HASQT5_11)
int messageTextWidth = fm.horizontalAdvance(messageText);
#else
int messageTextWidth = fm.width(messageText); int messageTextWidth = fm.width(messageText);
#endif
int messageTextTop = option.rect.top() + fm.height() + margin; int messageTextTop = option.rect.top() + fm.height() + margin;
if(actionText.isEmpty()) messageTextTop = option.rect.top() + margin + offset/2; if(actionText.isEmpty()) messageTextTop = option.rect.top() + margin + offset/2;
messageTextBox.setTop(messageTextTop); messageTextBox.setTop(messageTextTop);
@@ -139,11 +129,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
// time box rect // time box rect
QRect timeBox = messageTextBox; QRect timeBox = messageTextBox;
QString timeStr = tr("%1").arg(timeText); QString timeStr = tr("%1").arg(timeText);
#if (HASQT5_11)
int timeTextWidth = fm.horizontalAdvance(timeStr);
#else
int timeTextWidth = fm.width(timeStr); int timeTextWidth = fm.width(timeStr);
#endif
int timeTop = option.rect.top() + fm.height() + fm.height() + margin + offset/2; int timeTop = option.rect.top() + fm.height() + fm.height() + margin + offset/2;
if(messageText.isEmpty() || actionText.isEmpty()) if(messageText.isEmpty() || actionText.isEmpty())
timeTop = option.rect.top() + fm.height() + margin; timeTop = option.rect.top() + fm.height() + margin;
@@ -194,11 +180,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
if(objectType == _remote_share) primaryButton.text = tr("Accept"); if(objectType == _remote_share) primaryButton.text = tr("Accept");
if(objectType == _call) primaryButton.text = tr("Join"); if(objectType == _call) primaryButton.text = tr("Join");
#if (HASQT5_11)
primaryButton.rect.setLeft(left - margin * 2 - fm.horizontalAdvance(primaryButton.text));
#else
primaryButton.rect.setLeft(left - margin * 2 - fm.width(primaryButton.text)); primaryButton.rect.setLeft(left - margin * 2 - fm.width(primaryButton.text));
#endif
// save info to be able to filter mouse clicks // save info to be able to filter mouse clicks
_buttonHeight = buttonSize; _buttonHeight = buttonSize;
@@ -214,12 +196,7 @@ void ActivityItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
// Primary button will be 'open browser' // Primary button will be 'open browser'
primaryButton.text = tr("Open Browser"); primaryButton.text = tr("Open Browser");
#if (HASQT5_11)
primaryButton.rect.setLeft(left - margin * 2 - fm.horizontalAdvance(primaryButton.text));
#else
primaryButton.rect.setLeft(left - margin * 2 - fm.width(primaryButton.text)); primaryButton.rect.setLeft(left - margin * 2 - fm.width(primaryButton.text));
#endif
// save info to be able to filter mouse clicks // save info to be able to filter mouse clicks
_buttonHeight = buttonSize; _buttonHeight = buttonSize;

View File

@@ -108,7 +108,6 @@ Application::Application(int &argc, char **argv)
, _userTriggeredConnect(false) , _userTriggeredConnect(false)
, _debugMode(false) , _debugMode(false)
, _backgroundMode(false) , _backgroundMode(false)
, _isQuitting(false)
{ {
_startedAt.start(); _startedAt.start();
@@ -265,8 +264,6 @@ Application::~Application()
} }
// Remove the account from the account manager so it can be deleted. // Remove the account from the account manager so it can be deleted.
disconnect(AccountManager::instance(), &AccountManager::accountRemoved,
this, &Application::slotAccountStateRemoved);
AccountManager::instance()->shutdown(); AccountManager::instance()->shutdown();
} }
@@ -286,7 +283,7 @@ void Application::slotAccountStateRemoved(AccountState *accountState)
} }
// if there is no more account, show the wizard. // if there is no more account, show the wizard.
if (!_isQuitting && AccountManager::instance()->accounts().isEmpty()) { if (AccountManager::instance()->accounts().isEmpty()) {
// allow to add a new account if there is non any more. Always think // allow to add a new account if there is non any more. Always think
// about single account theming! // about single account theming!
OwncloudSetupWizard::runWizard(this, SLOT(slotownCloudWizardDone(int))); OwncloudSetupWizard::runWizard(this, SLOT(slotownCloudWizardDone(int)));
@@ -309,8 +306,6 @@ void Application::slotAccountStateAdded(AccountState *accountState)
void Application::slotCleanup() void Application::slotCleanup()
{ {
_isQuitting = true;
AccountManager::instance()->save(); AccountManager::instance()->save();
FolderMan::instance()->unloadAndDeleteAllFolders(); FolderMan::instance()->unloadAndDeleteAllFolders();

View File

@@ -114,7 +114,6 @@ private:
bool _userTriggeredConnect; bool _userTriggeredConnect;
bool _debugMode; bool _debugMode;
bool _backgroundMode; bool _backgroundMode;
bool _isQuitting;
ClientProxy _proxy; ClientProxy _proxy;

View File

@@ -52,11 +52,7 @@ void Flow2Auth::openBrowser()
// Step 1: Initiate a login, do an anonymous POST request // Step 1: Initiate a login, do an anonymous POST request
QUrl url = Utility::concatUrlPath(_account->url().toString(), QLatin1String("/index.php/login/v2")); QUrl url = Utility::concatUrlPath(_account->url().toString(), QLatin1String("/index.php/login/v2"));
// add 'Content-Length: 0' header (see https://github.com/nextcloud/desktop/issues/1473) auto job = _account->sendRequest("POST", url);
QNetworkRequest req;
req.setHeader(QNetworkRequest::ContentLengthHeader, "0");
auto job = _account->sendRequest("POST", url, req);
job->setTimeout(qMin(30 * 1000ll, job->timeoutMsec())); job->setTimeout(qMin(30 * 1000ll, job->timeoutMsec()));
QObject::connect(job, &SimpleNetworkJob::finishedSignal, this, [this](QNetworkReply *reply) { QObject::connect(job, &SimpleNetworkJob::finishedSignal, this, [this](QNetworkReply *reply) {

View File

@@ -358,8 +358,6 @@ void WebFlowCredentials::forgetSensitiveData() {
fetchUser(); fetchUser();
_account->deleteAppPassword();
const QString kck = keychainKey(_account->url().toString(), _user, _account->id()); const QString kck = keychainKey(_account->url().toString(), _user, _account->id());
if (kck.isEmpty()) { if (kck.isEmpty()) {
qCDebug(lcWebFlowCredentials()) << "InvalidateToken: User is empty, bailing out!"; qCDebug(lcWebFlowCredentials()) << "InvalidateToken: User is empty, bailing out!";
@@ -374,7 +372,7 @@ void WebFlowCredentials::forgetSensitiveData() {
invalidateToken(); invalidateToken();
/* IMPORTANT /* IMPORTANT
* TODO: For "Log out" & "Remove account": Remove client CA certs and KEY! /* TODO: For "Log out" & "Remove account": Remove client CA certs and KEY!
* *
* Disabled as long as selecting another cert is not supported by the UI. * Disabled as long as selecting another cert is not supported by the UI.
* *
@@ -418,9 +416,6 @@ void WebFlowCredentials::slotFinished(QNetworkReply *reply) {
if (reply->error() == QNetworkReply::NoError) { if (reply->error() == QNetworkReply::NoError) {
_credentialsValid = true; _credentialsValid = true;
/// Used later for remote wipe
_account->setAppPassword(_password);
} }
} }
@@ -544,7 +539,7 @@ void WebFlowCredentials::slotReadClientCaCertsPEMJobDone(QKeychain::Job *incomin
return; return;
} else { } else {
if (readJob->error() != QKeychain::Error::EntryNotFound || if (readJob->error() != QKeychain::Error::EntryNotFound ||
((readJob->error() == QKeychain::Error::EntryNotFound) && _clientSslCaCertificates.count() == 0)) { (readJob->error() == QKeychain::Error::EntryNotFound) && _clientSslCaCertificates.count() == 0) {
qCWarning(lcWebFlowCredentials) << "Unable to read client CA cert slot " << QString::number(_clientSslCaCertificates.count()) << readJob->errorString(); qCWarning(lcWebFlowCredentials) << "Unable to read client CA cert slot " << QString::number(_clientSslCaCertificates.count()) << readJob->errorString();
} }
} }

View File

@@ -417,13 +417,6 @@ void Folder::createGuiLog(const QString &filename, LogStatus status, int count,
text = tr("%1 could not be synced due to an error. See the log for details.").arg(file); text = tr("%1 could not be synced due to an error. See the log for details.").arg(file);
} }
break; break;
case LogStatusFileLocked:
if (count > 1) {
text = tr("%1 and %n other file(s) are currently locked.", "", count -1).arg(file);
} else {
text = tr("%1 is currently locked.").arg(file);
}
break;
} }
if (!text.isEmpty()) { if (!text.isEmpty()) {
@@ -902,19 +895,13 @@ void Folder::slotItemCompleted(const SyncFileItemPtr &item)
} }
// add new directories or remove gone away dirs to the watcher // add new directories or remove gone away dirs to the watcher
if (_folderWatcher && item->isDirectory()) { if (item->isDirectory() && item->_instruction == CSYNC_INSTRUCTION_NEW) {
switch (item->_instruction) { if (_folderWatcher)
case CSYNC_INSTRUCTION_NEW: _folderWatcher->addPath(path() + item->_file);
_folderWatcher->addPath(path() + item->_file); }
break; if (item->isDirectory() && item->_instruction == CSYNC_INSTRUCTION_REMOVE) {
case CSYNC_INSTRUCTION_REMOVE: if (_folderWatcher)
_folderWatcher->removePath(path() + item->_file); _folderWatcher->removePath(path() + item->_file);
break;
case CSYNC_INSTRUCTION_RENAME:
_folderWatcher->removePath(path() + item->_file);
_folderWatcher->addPath(path() + item->destination());
break;
}
} }
// Success and failure of sync items adjust what the next sync is // Success and failure of sync items adjust what the next sync is
@@ -1085,7 +1072,7 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction dir, bool *cancel
if (!cfgFile.promptDeleteFiles()) if (!cfgFile.promptDeleteFiles())
return; return;
QString msg = dir == SyncFileItem::Down ? tr("All files in the sync folder '%1' were deleted on the server.\n" QString msg = dir == SyncFileItem::Down ? tr("All files in the sync folder '%1' folder were deleted on the server.\n"
"These deletes will be synchronized to your local sync folder, making such files " "These deletes will be synchronized to your local sync folder, making such files "
"unavailable unless you have a right to restore. \n" "unavailable unless you have a right to restore. \n"
"If you decide to restore the files, they will be re-synced with the server if you have rights to do so.\n" "If you decide to restore the files, they will be re-synced with the server if you have rights to do so.\n"

View File

@@ -75,7 +75,7 @@ FolderMan::FolderMan(QObject *parent)
this, &FolderMan::slotScheduleFolderByTime); this, &FolderMan::slotScheduleFolderByTime);
_timeScheduler.start(); _timeScheduler.start();
connect(AccountManager::instance(), &AccountManager::removeAccountFolders, connect(AccountManager::instance(), &AccountManager::accountRemoved,
this, &FolderMan::slotRemoveFoldersForAccount); this, &FolderMan::slotRemoveFoldersForAccount);
connect(_lockWatcher.data(), &LockWatcher::fileUnlocked, connect(_lockWatcher.data(), &LockWatcher::fileUnlocked,
@@ -443,7 +443,7 @@ void FolderMan::slotFolderSyncPaused(Folder *f, bool paused)
void FolderMan::slotFolderCanSyncChanged() void FolderMan::slotFolderCanSyncChanged()
{ {
Folder *f = qobject_cast<Folder *>(sender()); Folder *f = qobject_cast<Folder *>(sender());
ASSERT(f); ASSERT(f);
if (f->canSync()) { if (f->canSync()) {
_socketApi->slotRegisterPath(f->alias()); _socketApi->slotRegisterPath(f->alias());
} else { } else {
@@ -562,7 +562,7 @@ void FolderMan::slotEtagJobDestroyed(QObject * /*o*/)
void FolderMan::slotRunOneEtagJob() void FolderMan::slotRunOneEtagJob()
{ {
if (_currentEtagJob.isNull()) { if (_currentEtagJob.isNull()) {
Folder *folder = nullptr; Folder *folder;
foreach (Folder *f, _folderMap) { foreach (Folder *f, _folderMap) {
if (f->etagJob()) { if (f->etagJob()) {
// Caveat: always grabs the first folder with a job, but we think this is Ok for now and avoids us having a seperate queue. // Caveat: always grabs the first folder with a job, but we think this is Ok for now and avoids us having a seperate queue.
@@ -1084,73 +1084,6 @@ bool FolderMan::startFromScratch(const QString &localFolder)
return true; return true;
} }
void FolderMan::slotWipeFolderForAccount(AccountState *accountState)
{
QVarLengthArray<Folder *, 16> foldersToRemove;
Folder::MapIterator i(_folderMap);
while (i.hasNext()) {
i.next();
Folder *folder = i.value();
if (folder->accountState() == accountState) {
foldersToRemove.append(folder);
}
}
bool success = false;
foreach (const auto &f, foldersToRemove) {
if (!f) {
qCCritical(lcFolderMan) << "Can not remove null folder";
return;
}
qCInfo(lcFolderMan) << "Removing " << f->alias();
const bool currentlyRunning = (_currentSyncFolder == f);
if (currentlyRunning) {
// abort the sync now
terminateSyncProcess();
}
if (_scheduledFolders.removeAll(f) > 0) {
emit scheduleQueueChanged();
}
// wipe database
f->wipe();
// wipe data
QDir userFolder(f->path());
if (userFolder.exists()) {
success = userFolder.removeRecursively();
if (!success) {
qCWarning(lcFolderMan) << "Failed to remove existing folder " << f->path();
} else {
qCInfo(lcFolderMan) << "wipe: Removed file " << f->path();
}
} else {
success = true;
qCWarning(lcFolderMan) << "folder does not exist, can not remove.";
}
f->setSyncPaused(true);
// remove the folder configuration
f->removeFromSettings();
unloadFolder(f);
if (currentlyRunning) {
delete f;
}
_navigationPaneHelper.scheduleUpdateCloudStorageRegistry();
}
emit folderListChanged(_folderMap);
emit wipeDone(accountState, success);
}
void FolderMan::setDirtyProxy() void FolderMan::setDirtyProxy()
{ {
foreach (Folder *f, _folderMap.values()) { foreach (Folder *f, _folderMap.values()) {

View File

@@ -207,11 +207,6 @@ signals:
*/ */
void folderListChanged(const Folder::Map &); void folderListChanged(const Folder::Map &);
/**
* Emitted once slotRemoveFoldersForAccount is done wiping
*/
void wipeDone(AccountState *account, bool success);
public slots: public slots:
/** /**
@@ -236,9 +231,6 @@ public slots:
// slot to schedule an ETag job (from Folder only) // slot to schedule an ETag job (from Folder only)
void slotScheduleETagJob(const QString &alias, RequestEtagJob *job); void slotScheduleETagJob(const QString &alias, RequestEtagJob *job);
/** Wipe folder */
void slotWipeFolderForAccount(AccountState *accountState);
private slots: private slots:
void slotFolderSyncPaused(Folder *, bool paused); void slotFolderSyncPaused(Folder *, bool paused);
void slotFolderCanSyncChanged(); void slotFolderCanSyncChanged();

View File

@@ -168,7 +168,6 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
QString itemString = qvariant_cast<QString>(index.data(SyncProgressItemString)); QString itemString = qvariant_cast<QString>(index.data(SyncProgressItemString));
int warningCount = qvariant_cast<int>(index.data(WarningCount)); int warningCount = qvariant_cast<int>(index.data(WarningCount));
bool syncOngoing = qvariant_cast<bool>(index.data(SyncRunning)); bool syncOngoing = qvariant_cast<bool>(index.data(SyncRunning));
QDateTime syncDate = qvariant_cast<QDateTime>(index.data(SyncDate));
bool syncEnabled = qvariant_cast<bool>(index.data(FolderAccountConnected)); bool syncEnabled = qvariant_cast<bool>(index.data(FolderAccountConnected));
QRect iconRect = option.rect; QRect iconRect = option.rect;
@@ -253,7 +252,7 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
if (!showProgess) { if (!showProgess) {
painter->setFont(subFont); painter->setFont(subFont);
QString elidedRemotePathText = subFm.elidedText( QString elidedRemotePathText = subFm.elidedText(
tr("Synchronized with local folder (%1)").arg(syncDate.toTimeSpec(Qt::LocalTime).toString(Qt::SystemLocaleShortDate)), tr("Synchronized with local folder"),
Qt::ElideRight, remotePathRect.width()); Qt::ElideRight, remotePathRect.width());
painter->drawText(QStyle::visualRect(option.direction, option.rect, remotePathRect), painter->drawText(QStyle::visualRect(option.direction, option.rect, remotePathRect),
textAlign, elidedRemotePathText); textAlign, elidedRemotePathText);

View File

@@ -44,7 +44,6 @@ public:
SyncProgressItemString, SyncProgressItemString,
WarningCount, WarningCount,
SyncRunning, SyncRunning,
SyncDate,
AddButton // 1 = enabled; 2 = disabled AddButton // 1 = enabled; 2 = disabled
}; };

View File

@@ -218,8 +218,6 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
return f->syncResult().errorStrings(); return f->syncResult().errorStrings();
case FolderStatusDelegate::SyncRunning: case FolderStatusDelegate::SyncRunning:
return f->syncResult().status() == SyncResult::SyncRunning; return f->syncResult().status() == SyncResult::SyncRunning;
case FolderStatusDelegate::SyncDate:
return f->syncResult().syncTime();
case FolderStatusDelegate::HeaderRole: case FolderStatusDelegate::HeaderRole:
return f->shortGuiRemotePathOrAppName(); return f->shortGuiRemotePathOrAppName();
case FolderStatusDelegate::FolderAliasRole: case FolderStatusDelegate::FolderAliasRole:

View File

@@ -19,8 +19,6 @@
#include "folderwatcher.h" #include "folderwatcher.h"
#include "folderwatcher_win.h" #include "folderwatcher_win.h"
#include "common/utility.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <tchar.h> #include <tchar.h>
@@ -54,7 +52,7 @@ void WatcherThread::watchChanges(size_t fileNotifyBufferSize,
// QVarLengthArray ensures the stack-buffer is aligned like double and qint64. // QVarLengthArray ensures the stack-buffer is aligned like double and qint64.
QVarLengthArray<char, 4096 * 10> fileNotifyBuffer; QVarLengthArray<char, 4096 * 10> fileNotifyBuffer;
fileNotifyBuffer.resize(OCC::Utility::convertSizeToInt(fileNotifyBufferSize)); fileNotifyBuffer.resize(fileNotifyBufferSize);
const size_t fileNameBufferSize = 4096; const size_t fileNameBufferSize = 4096;
TCHAR fileNameBuffer[fileNameBufferSize]; TCHAR fileNameBuffer[fileNameBufferSize];
@@ -68,7 +66,7 @@ void WatcherThread::watchChanges(size_t fileNotifyBufferSize,
DWORD dwBytesReturned = 0; DWORD dwBytesReturned = 0;
SecureZeroMemory(pFileNotifyBuffer, fileNotifyBufferSize); SecureZeroMemory(pFileNotifyBuffer, fileNotifyBufferSize);
if (!ReadDirectoryChangesW(_directory, (LPVOID)pFileNotifyBuffer, if (!ReadDirectoryChangesW(_directory, (LPVOID)pFileNotifyBuffer,
OCC::Utility::convertSizeToDWORD(fileNotifyBufferSize), true, fileNotifyBufferSize, true,
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
&dwBytesReturned, &dwBytesReturned,
&overlapped, &overlapped,
@@ -115,7 +113,7 @@ void WatcherThread::watchChanges(size_t fileNotifyBufferSize,
FILE_NOTIFY_INFORMATION *curEntry = pFileNotifyBuffer; FILE_NOTIFY_INFORMATION *curEntry = pFileNotifyBuffer;
forever { forever {
size_t len = curEntry->FileNameLength / 2; size_t len = curEntry->FileNameLength / 2;
QString file = _path + "\\" + QString::fromWCharArray(curEntry->FileName, OCC::Utility::convertSizeToInt(len)); QString file = _path + "\\" + QString::fromWCharArray(curEntry->FileName, len);
// Unless the file was removed or renamed, get its full long name // Unless the file was removed or renamed, get its full long name
// TODO: We could still try expanding the path in the tricky cases... // TODO: We could still try expanding the path in the tricky cases...
@@ -124,7 +122,7 @@ void WatcherThread::watchChanges(size_t fileNotifyBufferSize,
&& curEntry->Action != FILE_ACTION_RENAMED_OLD_NAME) { && curEntry->Action != FILE_ACTION_RENAMED_OLD_NAME) {
size_t longNameSize = GetLongPathNameW(reinterpret_cast<LPCWSTR>(file.utf16()), fileNameBuffer, fileNameBufferSize); size_t longNameSize = GetLongPathNameW(reinterpret_cast<LPCWSTR>(file.utf16()), fileNameBuffer, fileNameBufferSize);
if (longNameSize > 0) { if (longNameSize > 0) {
longfile = QString::fromUtf16(reinterpret_cast<const ushort *>(fileNameBuffer), OCC::Utility::convertSizeToInt(longNameSize)); longfile = QString::fromUtf16(reinterpret_cast<const ushort *>(fileNameBuffer), longNameSize);
} else { } else {
qCWarning(lcFolderWatcher) << "Error converting file name to full length, keeping original name."; qCWarning(lcFolderWatcher) << "Error converting file name to full length, keeping original name.";
} }

View File

@@ -107,7 +107,7 @@
<enum>QFrame::Plain</enum> <enum>QFrame::Plain</enum>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">TextLabel</string> <string>TextLabel</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::RichText</enum> <enum>Qt::RichText</enum>

View File

@@ -26,7 +26,6 @@
#include "updater/updater.h" #include "updater/updater.h"
#include "updater/ocupdater.h" #include "updater/ocupdater.h"
#include "ignorelisteditor.h" #include "ignorelisteditor.h"
#include "common/utility.h"
#include "config.h" #include "config.h"
@@ -36,12 +35,6 @@
#include <QDir> #include <QDir>
#include <QScopedValueRollback> #include <QScopedValueRollback>
#define QTLEGACY (QT_VERSION < QT_VERSION_CHECK(5,9,0))
#if !(QTLEGACY)
#include <QOperatingSystemVersion>
#endif
namespace OCC { namespace OCC {
GeneralSettings::GeneralSettings(QWidget *parent) GeneralSettings::GeneralSettings(QWidget *parent)
@@ -86,13 +79,9 @@ GeneralSettings::GeneralSettings(QWidget *parent)
// Hide on non-Windows, or WindowsVersion < 10. // Hide on non-Windows, or WindowsVersion < 10.
// The condition should match the default value of ConfigFile::showInExplorerNavigationPane. // The condition should match the default value of ConfigFile::showInExplorerNavigationPane.
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#if QTLEGACY if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS10)
if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS10)
#else
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows10)
#endif
_ui->showInExplorerNavigationPaneCheckBox->setVisible(false);
#endif #endif
_ui->showInExplorerNavigationPaneCheckBox->setVisible(false);
/* Set the left contents margin of the layout to zero to make the checkboxes /* Set the left contents margin of the layout to zero to make the checkboxes
* align properly vertically , fixes bug #3758 * align properly vertically , fixes bug #3758

View File

@@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string notr="true">IgnoreListTableWidget</string> <string>IgnoreListTableWidget</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" rowspan="4"> <item row="0" column="0" rowspan="4">

View File

@@ -55,7 +55,7 @@
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">Label</string> <string>Label</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>563</width> <width>542</width>
<height>444</height> <height>396</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -228,7 +228,7 @@
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>999999</number> <number>9999</number>
</property> </property>
<property name="value"> <property name="value">
<number>80</number> <number>80</number>
@@ -307,7 +307,7 @@
<number>1</number> <number>1</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>999999</number> <number>9999</number>
</property> </property>
<property name="value"> <property name="value">
<number>10</number> <number>10</number>

View File

@@ -22,12 +22,6 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QApplication> #include <QApplication>
#define QTLEGACY (QT_VERSION < QT_VERSION_CHECK(5,9,0))
#if !(QTLEGACY)
#include <QOperatingSystemVersion>
#endif
namespace OCC { namespace OCC {
// according to the QStandardDir impl from Qt5 // according to the QStandardDir impl from Qt5
@@ -95,14 +89,10 @@ void showInFileManager(const QString &localPath)
{ {
if (Utility::isWindows()) { if (Utility::isWindows()) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#if QTLEGACY if (QSysInfo::windowsVersion() <= QSysInfo::WV_2003) {
if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS10) return;
#else }
if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows7)
#endif
return;
#endif #endif
QString explorer = "explorer.exe "; // FIXME: we trust it's in PATH QString explorer = "explorer.exe "; // FIXME: we trust it's in PATH
QFileInfo fi(localPath); QFileInfo fi(localPath);

View File

@@ -675,12 +675,6 @@ void ownCloudGui::updateContextMenu()
_contextMenu->addSeparator(); _contextMenu->addSeparator();
if (_navLinksMenu) {
_contextMenu->addMenu(_navLinksMenu);
}
_contextMenu->addSeparator();
if (accountList.isEmpty()) { if (accountList.isEmpty()) {
_contextMenu->addAction(_actionNewAccountWizard); _contextMenu->addAction(_actionNewAccountWizard);
} }
@@ -694,7 +688,6 @@ void ownCloudGui::updateContextMenu()
} }
_contextMenu->addSeparator(); _contextMenu->addSeparator();
if (atLeastOnePaused) { if (atLeastOnePaused) {
QString text; QString text;
if (accountList.count() > 1) { if (accountList.count() > 1) {
@@ -784,8 +777,6 @@ void ownCloudGui::setupActions()
{ {
_actionStatus = new QAction(tr("Unknown status"), this); _actionStatus = new QAction(tr("Unknown status"), this);
_actionStatus->setEnabled(false); _actionStatus->setEnabled(false);
_navLinksMenu = new QMenu(tr("Apps"));
_navLinksMenu->setEnabled(false);
_actionSettings = new QAction(tr("Settings..."), this); _actionSettings = new QAction(tr("Settings..."), this);
_actionNewAccountWizard = new QAction(tr("New account..."), this); _actionNewAccountWizard = new QAction(tr("New account..."), this);
_actionRecent = new QAction(tr("View more activity..."), this); _actionRecent = new QAction(tr("View more activity..."), this);
@@ -827,11 +818,8 @@ void ownCloudGui::fetchNavigationApps(AccountStatePtr account){
void ownCloudGui::buildNavigationAppsMenu(AccountStatePtr account, QMenu *accountMenu){ void ownCloudGui::buildNavigationAppsMenu(AccountStatePtr account, QMenu *accountMenu){
auto navLinks = _navApps.value(account); auto navLinks = _navApps.value(account);
_navLinksMenu->clear();
_navLinksMenu->setEnabled(navLinks.size() > 0);
if(navLinks.size() > 0){ if(navLinks.size() > 0){
// when there is only one account add the nav links above the settings // when there is only one account add the nav links above the settings
QAction *actionBefore = _actionSettings; QAction *actionBefore = _actionSettings;
@@ -850,13 +838,17 @@ void ownCloudGui::buildNavigationAppsMenu(AccountStatePtr account, QMenu *accoun
} }
// Create submenu with links // Create submenu with links
QMenu *navLinksMenu = new QMenu(tr("Apps"));
accountMenu->insertSeparator(actionBefore);
accountMenu->insertMenu(actionBefore, navLinksMenu);
foreach (const QJsonValue &value, navLinks) { foreach (const QJsonValue &value, navLinks) {
auto navLink = value.toObject(); auto navLink = value.toObject();
QAction *action = new QAction(navLink.value("name").toString(), this); QAction *action = new QAction(navLink.value("name").toString(), this);
QUrl href(navLink.value("href").toString()); QUrl href(navLink.value("href").toString());
connect(action, &QAction::triggered, this, [href] { QDesktopServices::openUrl(href); }); connect(action, &QAction::triggered, this, [href] { QDesktopServices::openUrl(href); });
_navLinksMenu->addAction(action); navLinksMenu->addAction(action);
} }
accountMenu->insertSeparator(actionBefore);
} }
} }

View File

@@ -168,7 +168,6 @@ private:
QAction *_actionQuit; QAction *_actionQuit;
QAction *_actionCrash; QAction *_actionCrash;
QMenu *_navLinksMenu;
QMap<AccountStatePtr, QJsonArray> _navApps; QMap<AccountStatePtr, QJsonArray> _navApps;
QList<QAction *> _recentItemsActions; QList<QAction *> _recentItemsActions;

View File

@@ -466,41 +466,7 @@ void OwncloudSetupWizard::slotCreateLocalAndRemoteFolders(const QString &localFo
_ocWizard->appendToConfigurationLog(res); _ocWizard->appendToConfigurationLog(res);
} }
if (nextStep) { if (nextStep) {
/* EntityExistsJob *job = new EntityExistsJob(_ocWizard->account(), _ocWizard->account()->davPath() + remoteFolder, this);
* BEGIN - Sanitize URL paths to eliminate double-slashes
*
* Purpose: Don't rely on unsafe paths, be extra careful.
*
* Example: https://cloud.example.com/remote.php/webdav//
*
*/
qCInfo(lcWizard) << "Sanitize got URL path:" << QString(_ocWizard->account()->url().toString() + '/' + _ocWizard->account()->davPath() + remoteFolder);
QString newDavPath = _ocWizard->account()->davPath(),
newRemoteFolder = remoteFolder;
while (newDavPath.startsWith('/')) {
newDavPath.remove(0, 1);
}
while (newDavPath.endsWith('/')) {
newDavPath.chop(1);
}
while (newRemoteFolder.startsWith('/')) {
newRemoteFolder.remove(0, 1);
}
while (newRemoteFolder.endsWith('/')) {
newRemoteFolder.chop(1);
}
QString newUrlPath = newDavPath + '/' + newRemoteFolder;
qCInfo(lcWizard) << "Sanitized to URL path:" << _ocWizard->account()->url().toString() + '/' + newUrlPath;
/*
* END - Sanitize URL paths to eliminate double-slashes
*/
EntityExistsJob *job = new EntityExistsJob(_ocWizard->account(), newUrlPath, this);
connect(job, &EntityExistsJob::exists, this, &OwncloudSetupWizard::slotRemoteFolderExists); connect(job, &EntityExistsJob::exists, this, &OwncloudSetupWizard::slotRemoteFolderExists);
job->start(); job->start();
} else { } else {

View File

@@ -71,7 +71,7 @@
<item row="2" column="1"> <item row="2" column="1">
<widget class="QLabel" name="proxyAddress"> <widget class="QLabel" name="proxyAddress">
<property name="text"> <property name="text">
<string notr="true">TextLabel</string> <string>TextLabel</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::PlainText</enum> <enum>Qt::PlainText</enum>

View File

@@ -1,161 +0,0 @@
/*
* Copyright (C) by Camila Ayres <hello@camila.codes>
*
* 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 "remotewipe.h"
#include "folderman.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkRequest>
#include <QBuffer>
namespace OCC {
Q_LOGGING_CATEGORY(lcRemoteWipe, "nextcloud.gui.remotewipe", QtInfoMsg)
RemoteWipe::RemoteWipe(AccountPtr account, QObject *parent)
: _account(account),
_appPassword(QString()),
_accountRemoved(false),
_networkManager(nullptr),
_networkReplyCheck(nullptr),
_networkReplySuccess(nullptr)
{
QObject::connect(AccountManager::instance(), &AccountManager::accountRemoved,
this, [=](AccountState *) {
_accountRemoved = true;
});
QObject::connect(this, &RemoteWipe::authorized, FolderMan::instance(),
&FolderMan::slotWipeFolderForAccount);
QObject::connect(FolderMan::instance(), &FolderMan::wipeDone, this,
&RemoteWipe::notifyServerSuccessJob);
QObject::connect(_account.data(), &Account::appPasswordRetrieved, this,
&RemoteWipe::startCheckJobWithAppPassword);
}
void RemoteWipe::startCheckJobWithAppPassword(QString pwd){
if(pwd.isEmpty())
return;
_appPassword = pwd;
QUrl requestUrl = Utility::concatUrlPath(_account->url().toString(),
QLatin1String("/index.php/core/wipe/check"));
QNetworkRequest request;
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");
request.setUrl(requestUrl);
request.setSslConfiguration(_account->getOrCreateSslConfig());
auto requestBody = new QBuffer;
QUrlQuery arguments(QString("token=%1").arg(_appPassword));
requestBody->setData(arguments.query(QUrl::FullyEncoded).toLatin1());
_networkReplyCheck = _networkManager.post(request, requestBody);
QObject::connect(&_networkManager, SIGNAL(sslErrors(QNetworkReply *, QList<QSslError>)),
_account.data(), SLOT(slotHandleSslErrors(QNetworkReply *, QList<QSslError>)));
QObject::connect(_networkReplyCheck, &QNetworkReply::finished, this,
&RemoteWipe::checkJobSlot);
}
void RemoteWipe::checkJobSlot()
{
auto jsonData = _networkReplyCheck->readAll();
QJsonParseError jsonParseError;
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
bool wipe = false;
//check for errors
if (_networkReplyCheck->error() != QNetworkReply::NoError ||
jsonParseError.error != QJsonParseError::NoError) {
QString errorReason;
QString errorFromJson = json["error"].toString();
if (!errorFromJson.isEmpty()) {
qCWarning(lcRemoteWipe) << QString("Error returned from the server: <em>%1<em>")
.arg(errorFromJson.toHtmlEscaped());
} else if (_networkReplyCheck->error() != QNetworkReply::NoError) {
qCWarning(lcRemoteWipe) << QString("There was an error accessing the 'token' endpoint: <br><em>%1</em>")
.arg(_networkReplyCheck->errorString().toHtmlEscaped());
} else if (jsonParseError.error != QJsonParseError::NoError) {
qCWarning(lcRemoteWipe) << QString("Could not parse the JSON returned from the server: <br><em>%1</em>")
.arg(jsonParseError.errorString());
} else {
qCWarning(lcRemoteWipe) << QString("The reply from the server did not contain all expected fields");
}
// check for wipe request
} else if(!json.value("wipe").isUndefined()){
wipe = json["wipe"].toBool();
}
auto manager = AccountManager::instance();
auto accountState = manager->account(_account->displayName()).data();
if(wipe){
// delete account
manager->deleteAccount(accountState);
manager->save();
// delete data
emit authorized(accountState);
} else {
// ask user for his credentials again
accountState->handleInvalidCredentials();
}
_networkReplyCheck->deleteLater();
}
void RemoteWipe::notifyServerSuccessJob(AccountState *accountState, bool dataWiped){
if(_accountRemoved && dataWiped && _account == accountState->account()){
QUrl requestUrl = Utility::concatUrlPath(_account->url().toString(),
QLatin1String("/index.php/core/wipe/success"));
QNetworkRequest request;
request.setHeader(QNetworkRequest::ContentTypeHeader,
"application/x-www-form-urlencoded");
request.setUrl(requestUrl);
request.setSslConfiguration(_account->getOrCreateSslConfig());
auto requestBody = new QBuffer;
QUrlQuery arguments(QString("token=%1").arg(_appPassword));
requestBody->setData(arguments.query(QUrl::FullyEncoded).toLatin1());
_networkReplySuccess = _networkManager.post(request, requestBody);
QObject::connect(_networkReplySuccess, &QNetworkReply::finished, this,
&RemoteWipe::notifyServerSuccessJobSlot);
}
}
void RemoteWipe::notifyServerSuccessJobSlot()
{
auto jsonData = _networkReplySuccess->readAll();
QJsonParseError jsonParseError;
QJsonObject json = QJsonDocument::fromJson(jsonData, &jsonParseError).object();
if (_networkReplySuccess->error() != QNetworkReply::NoError ||
jsonParseError.error != QJsonParseError::NoError) {
QString errorReason;
QString errorFromJson = json["error"].toString();
if (!errorFromJson.isEmpty()) {
qCWarning(lcRemoteWipe) << QString("Error returned from the server: <em>%1</em>")
.arg(errorFromJson.toHtmlEscaped());
} else if (_networkReplySuccess->error() != QNetworkReply::NoError) {
qCWarning(lcRemoteWipe) << QString("There was an error accessing the 'success' endpoint: <br><em>%1</em>")
.arg(_networkReplySuccess->errorString().toHtmlEscaped());
} else if (jsonParseError.error != QJsonParseError::NoError) {
qCWarning(lcRemoteWipe) << QString("Could not parse the JSON returned from the server: <br><em>%1</em>")
.arg(jsonParseError.errorString());
} else {
qCWarning(lcRemoteWipe) << QString("The reply from the server did not contain all expected fields.");
}
}
_networkReplySuccess->deleteLater();
}
}

View File

@@ -1,61 +0,0 @@
#ifndef REMOTEWIPE_H
#define REMOTEWIPE_H
#include "accountmanager.h"
#include <QNetworkAccessManager>
class QJsonDocument;
class TestRemoteWipe;
namespace OCC {
class RemoteWipe : public QObject
{
Q_OBJECT
public:
explicit RemoteWipe(AccountPtr account, QObject *parent = nullptr);
signals:
/**
* Notify if wipe was requested
*/
void authorized(AccountState*);
/**
* Notify if user only needs to login again
*/
void askUserCredentials();
public slots:
/**
* Once receives a 401 or 403 status response it will do a fetch to
* <server>/index.php/core/wipe/check
*/
void startCheckJobWithAppPassword(QString);
private slots:
/**
* If wipe is requested, delete account and data, if not continue by asking
* the user to login again
*/
void checkJobSlot();
/**
* Once the client has wiped all the required data a POST to
* <server>/index.php/core/wipe/success
*/
void notifyServerSuccessJob(AccountState *accountState, bool);
void notifyServerSuccessJobSlot();
private:
AccountPtr _account;
QString _appPassword;
bool _accountRemoved;
QNetworkAccessManager _networkManager;
QNetworkReply *_networkReplyCheck;
QNetworkReply *_networkReplySuccess;
friend class ::TestRemoteWipe;
};
}
#endif // REMOTEWIPE_H

View File

@@ -48,7 +48,7 @@ const char TOOLBAR_CSS[] =
"QToolBar QToolBarExtension { padding:0; } " "QToolBar QToolBarExtension { padding:0; } "
"QToolBar QToolButton:checked { background: %3; color: %4; }"; "QToolBar QToolButton:checked { background: %3; color: %4; }";
static const float buttonSizeRatio = 1.618f; // golden ratio static const float buttonSizeRatio = 1.618; // golden ratio
} }

View File

@@ -89,7 +89,7 @@
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">share label</string> <string>share label</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::PlainText</enum> <enum>Qt::PlainText</enum>
@@ -120,7 +120,7 @@
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">Icon</string> <string>Icon</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -151,8 +151,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>367</width> <width>352</width>
<height>85</height> <height>68</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="scrollAreaVerticalLayout"/> <layout class="QVBoxLayout" name="scrollAreaVerticalLayout"/>

View File

@@ -277,7 +277,6 @@ void ShareLinkWidget::slotCreatePassword()
void ShareLinkWidget::slotCreateShareLink(bool clicked) void ShareLinkWidget::slotCreateShareLink(bool clicked)
{ {
Q_UNUSED(clicked);
slotToggleAnimation(true); slotToggleAnimation(true);
emit createLinkShare(); emit createLinkShare();
} }

View File

@@ -109,7 +109,7 @@
</palette> </palette>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">TextLabel</string> <string>TextLabel</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::PlainText</enum> <enum>Qt::PlainText</enum>

View File

@@ -628,7 +628,7 @@ void SocketApi::command_GET_STRINGS(const QString &argument, SocketListener *lis
{ "EMAIL_PRIVATE_LINK_MENU_TITLE", tr("Send private link by email...") }, { "EMAIL_PRIVATE_LINK_MENU_TITLE", tr("Send private link by email...") },
} }; } };
listener->sendMessage(QString("GET_STRINGS:BEGIN")); listener->sendMessage(QString("GET_STRINGS:BEGIN"));
for (const auto& key_value : strings) { for (auto key_value : strings) {
if (argument.isEmpty() || argument == QLatin1String(key_value.first)) { if (argument.isEmpty() || argument == QLatin1String(key_value.first)) {
listener->sendMessage(QString("STRING:%1:%2").arg(key_value.first, key_value.second)); listener->sendMessage(QString("STRING:%1:%2").arg(key_value.first, key_value.second));
} }

View File

@@ -37,7 +37,6 @@ SslButton::SslButton(QWidget *parent)
_menu = new QMenu(this); _menu = new QMenu(this);
QObject::connect(_menu, &QMenu::aboutToShow, QObject::connect(_menu, &QMenu::aboutToShow,
this, &SslButton::slotUpdateMenu); this, &SslButton::slotUpdateMenu);
setMenu(_menu);
} }
static QString addCertDetailsField(const QString &key, const QString &value) static QString addCertDetailsField(const QString &key, const QString &value)
@@ -172,9 +171,11 @@ void SslButton::updateAccountState(AccountState *accountState)
setIcon(QIcon(QLatin1String(":/client/resources/lock-https.png"))); setIcon(QIcon(QLatin1String(":/client/resources/lock-https.png")));
QSslCipher cipher = account->_sessionCipher; QSslCipher cipher = account->_sessionCipher;
setToolTip(tr("This connection is encrypted using %1 bit %2.\n").arg(cipher.usedBits()).arg(cipher.name())); setToolTip(tr("This connection is encrypted using %1 bit %2.\n").arg(cipher.usedBits()).arg(cipher.name()));
setMenu(_menu);
} else { } else {
setIcon(QIcon(QLatin1String(":/client/resources/lock-http.png"))); setIcon(QIcon(QLatin1String(":/client/resources/lock-http.png")));
setToolTip(tr("This connection is NOT secure as it is not encrypted.\n")); setToolTip(tr("This connection is NOT secure as it is not encrypted.\n"));
setMenu(nullptr);
} }
} }
@@ -188,8 +189,6 @@ void SslButton::slotUpdateMenu()
AccountPtr account = _accountState->account(); AccountPtr account = _accountState->account();
_menu->addAction(tr("Server version: %1").arg(account->serverVersion()))->setEnabled(false);
if (account->isHttp2Supported()) { if (account->isHttp2Supported()) {
_menu->addAction("HTTP/2")->setEnabled(false); _menu->addAction("HTTP/2")->setEnabled(false);
} }
@@ -240,8 +239,6 @@ void SslButton::slotUpdateMenu()
_menu->addMenu(buildCertMenu(_menu, it.previous(), account->approvedCerts(), i, systemCerts)); _menu->addMenu(buildCertMenu(_menu, it.previous(), account->approvedCerts(), i, systemCerts));
i++; i++;
} }
} else {
_menu->addAction(tr("The connection is not secure"))->setEnabled(false);
} }
} }

View File

@@ -148,7 +148,7 @@ QString OCUpdater::statusString() const
case DownloadTimedOut: case DownloadTimedOut:
return tr("Could not check for new updates."); return tr("Could not check for new updates.");
case UpdateOnlyAvailableThroughSystem: case UpdateOnlyAvailableThroughSystem:
return tr("New %1 version %2 is available. Please click <a href='%3'>here</a> to download the update.").arg(Theme::instance()->appNameGUI(), updateVersion, _updateInfo.web()); return tr("New %1 version %2 available. Please use the system's update tool to install it.").arg(Theme::instance()->appNameGUI(), updateVersion);
case CheckingServer: case CheckingServer:
return tr("Checking update server..."); return tr("Checking update server...");
case Unknown: case Unknown:

View File

@@ -99,7 +99,6 @@ void Flow2AuthCredsPage::asyncAuthResult(Flow2Auth::Result r, const QString &use
_appPassword = appPassword; _appPassword = appPassword;
OwncloudWizard *ocWizard = qobject_cast<OwncloudWizard *>(wizard()); OwncloudWizard *ocWizard = qobject_cast<OwncloudWizard *>(wizard());
Q_ASSERT(ocWizard); Q_ASSERT(ocWizard);
emit connectToOCUrl(ocWizard->account()->url().toString()); emit connectToOCUrl(ocWizard->account()->url().toString());
break; break;
} }

View File

@@ -11,7 +11,7 @@
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Browser Authentication</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
@@ -61,7 +61,6 @@
<widget class="QCommandLinkButton" name="copyLinkButton"> <widget class="QCommandLinkButton" name="copyLinkButton">
<property name="font"> <property name="font">
<font> <font>
<family>Segoe UI</family>
<weight>50</weight> <weight>50</weight>
<bold>false</bold> <bold>false</bold>
</font> </font>

View File

@@ -23,7 +23,7 @@
</size> </size>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Browser Authentication</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
@@ -73,7 +73,6 @@
<widget class="QCommandLinkButton" name="copyLinkButton"> <widget class="QCommandLinkButton" name="copyLinkButton">
<property name="font"> <property name="font">
<font> <font>
<family>Segoe UI</family>
<weight>50</weight> <weight>50</weight>
<bold>false</bold> <bold>false</bold>
</font> </font>

View File

@@ -42,8 +42,6 @@ OwncloudAdvancedSetupPage::OwncloudAdvancedSetupPage()
, _localFolderValid(false) , _localFolderValid(false)
, _progressIndi(new QProgressIndicator(this)) , _progressIndi(new QProgressIndicator(this))
, _remoteFolder() , _remoteFolder()
, _rSize(-1)
, _rSelectedSize(-1)
{ {
_ui.setupUi(this); _ui.setupUi(this);
@@ -370,8 +368,6 @@ void OwncloudAdvancedSetupPage::slotQuotaRetrieved(const QVariantMap &result)
{ {
_rSize = result["size"].toDouble(); _rSize = result["size"].toDouble();
_ui.lSyncEverythingSizeLabel->setText(tr("(%1)").arg(Utility::octetsToString(_rSize))); _ui.lSyncEverythingSizeLabel->setText(tr("(%1)").arg(Utility::octetsToString(_rSize)));
updateStatus();
} }
qint64 OwncloudAdvancedSetupPage::availableLocalSpace() const qint64 OwncloudAdvancedSetupPage::availableLocalSpace() const

View File

@@ -399,7 +399,7 @@
<item> <item>
<widget class="QLabel" name="syncModeLabel"> <widget class="QLabel" name="syncModeLabel">
<property name="text"> <property name="text">
<string notr="true">Status message</string> <string>Status message</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::RichText</enum> <enum>Qt::RichText</enum>

View File

@@ -25,24 +25,67 @@
<property name="styleSheet"> <property name="styleSheet">
<string notr="true"/> <string notr="true"/>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QGridLayout" name="gridLayout">
<item> <item row="16" column="0">
<spacer name="verticalSpacer_5"> <widget class="QLabel" name="bottomLabel">
<property name="orientation"> <property name="minimumSize">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>0</width>
<height>20</height> <height>0</height>
</size> </size>
</property> </property>
</spacer> <property name="text">
<string notr="true">TextLabel</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item> </item>
<item> <item row="14" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_6">
<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>
<widget class="QLabel" name="installLink">
<property name="text">
<string>&lt;a href=&quot;https://docs.nextcloud.com/server/15/admin_manual/installation/index.html#installation&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Host your own server&lt;/span&gt;&lt;/a&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<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>
<item row="3" column="0">
<widget class="QLabel" name="topLabel"> <widget class="QLabel" name="topLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -64,66 +107,117 @@
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="11" column="0" rowspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_9"> <layout class="QHBoxLayout" name="buttons" stretch="0,0,0,0">
<property name="spacing">
<number>6</number>
</property>
<property name="topMargin">
<number>20</number>
</property>
<item> <item>
<widget class="QPushButton" name="prevButton"> <spacer name="horizontalSpacer_3">
<property name="minimumSize"> <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="createAccountButton">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<property name="maximumSize"> <property name="autoFillBackground">
<size> <bool>false</bool>
<width>40</width>
<height>16777215</height>
</size>
</property> </property>
<property name="text"> <property name="text">
<string/> <string>Register with a provider</string>
</property> </property>
<property name="flat"> <property name="default">
<bool>true</bool> <bool>false</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="OCC::SlideShow" name="slideShow" native="true"> <widget class="QPushButton" name="loginButton">
<property name="font"> <property name="sizePolicy">
<font> <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<pointsize>12</pointsize> <horstretch>0</horstretch>
<weight>75</weight> <verstretch>0</verstretch>
<bold>true</bold> </sizepolicy>
</font> </property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Log in</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="flat">
<bool>false</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="nextButton"> <spacer name="horizontalSpacer_4">
<property name="minimumSize"> <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>40</width>
<height>0</height> <height>20</height>
</size> </size>
</property> </property>
<property name="maximumSize"> </spacer>
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
<item> <item row="6" column="0">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="OCC::SlideShow" name="slideShow">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QWidget" name="login" native="true"> <widget class="QWidget" name="login" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding"> <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
@@ -207,7 +301,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="placeholderText"> <property name="placeholderText">
<string notr="true">https://...</string> <string>https://...</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -242,7 +336,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string notr="true">Error Label</string> <string>Error Label</string>
</property> </property>
<property name="textFormat"> <property name="textFormat">
<enum>Qt::RichText</enum> <enum>Qt::RichText</enum>
@@ -291,8 +385,8 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item> <item row="0" column="0">
<spacer name="verticalSpacer_4"> <spacer name="verticalSpacer_5">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@@ -307,157 +401,6 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<layout class="QHBoxLayout" name="buttons" stretch="0,0,0,0">
<property name="spacing">
<number>6</number>
</property>
<property name="topMargin">
<number>20</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<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>
<widget class="QPushButton" name="createAccountButton">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="text">
<string>Register with a provider</string>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="loginButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Log in</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<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>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_6">
<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>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="installLink">
<property name="text">
<string notr="true">&lt;a href=&quot;https://docs.nextcloud.com/server/latest/admin_manual/installation/#installation&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#7a7a7a;&quot;&gt;Host your own server&lt;/span&gt;&lt;/a&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<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>
<item>
<widget class="QLabel" name="bottomLabel">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string notr="true">TextLabel</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

View File

@@ -84,22 +84,7 @@ OwncloudSetupPage::OwncloudSetupPage(QWidget *parent)
_ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-files.png"), tr("Secure collaboration & file exchange")); _ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-files.png"), tr("Secure collaboration & file exchange"));
_ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-groupware.png"), tr("Easy-to-use web mail, calendaring & contacts")); _ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-groupware.png"), tr("Easy-to-use web mail, calendaring & contacts"));
_ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-talk.png"), tr("Screensharing, online meetings & web conferences")); _ui.slideShow->addSlide(Theme::hidpiFileName(":/client/theme/colored/wizard-talk.png"), tr("Screensharing, online meetings & web conferences"));
connect(_ui.slideShow, &SlideShow::clicked, _ui.slideShow, &SlideShow::stopShow); connect(_ui.slideShow, &SlideShow::clicked, _ui.slideShow, &SlideShow::nextSlide);
connect(_ui.nextButton, &QPushButton::clicked, _ui.slideShow, &SlideShow::nextSlide);
connect(_ui.prevButton, &QPushButton::clicked, _ui.slideShow, &SlideShow::prevSlide);
auto widgetBgLightness = OwncloudSetupPage::palette().color(OwncloudSetupPage::backgroundRole()).lightness();
bool widgetHasDarkBg =
(widgetBgLightness >= 125)
? false
: true;
_ui.nextButton->setIcon(theme->uiThemeIcon(QString("control-next.svg"), widgetHasDarkBg));
_ui.prevButton->setIcon(theme->uiThemeIcon(QString("control-prev.svg"), widgetHasDarkBg));
// QPushButtons are a mess when it comes to consistent background coloring without stylesheets,
// so we do it here even though this is an exceptional styling method here
_ui.createAccountButton->setStyleSheet("QPushButton {background-color: #0082C9; color: white}");
_ui.slideShow->startShow(); _ui.slideShow->startShow();
QPalette pal = _ui.slideShow->palette(); QPalette pal = _ui.slideShow->palette();

View File

@@ -19,8 +19,6 @@
#include <QStyle> #include <QStyle>
#include <QStyleHints> #include <QStyleHints>
#define HASQT5_11 (QT_VERSION >= QT_VERSION_CHECK(5,11,0))
namespace OCC { namespace OCC {
static const int Spacing = 6; static const int Spacing = 6;
@@ -90,11 +88,7 @@ QSize SlideShow::sizeHint() const
QFontMetrics fm = fontMetrics(); QFontMetrics fm = fontMetrics();
QSize labelSize(0, fm.height()); QSize labelSize(0, fm.height());
for (const QString &label : _labels) { for (const QString &label : _labels) {
#if (HASQT5_11)
labelSize.setWidth(std::max(fm.horizontalAdvance(label), labelSize.width()));
#else
labelSize.setWidth(std::max(fm.width(label), labelSize.width())); labelSize.setWidth(std::max(fm.width(label), labelSize.width()));
#endif
} }
QSize pixmapSize; QSize pixmapSize;
for (const QPixmap &pixmap : _pixmaps) { for (const QPixmap &pixmap : _pixmaps) {
@@ -122,7 +116,7 @@ void SlideShow::nextSlide()
_reverse = false; _reverse = false;
} }
void SlideShow::prevSlide() void SlideShow::previousSlide()
{ {
setCurrentSlide((_currentIndex > 0 ? _currentIndex : _labels.count()) - 1); setCurrentSlide((_currentIndex > 0 ? _currentIndex : _labels.count()) - 1);
_reverse = true; _reverse = true;

View File

@@ -51,7 +51,7 @@ public slots:
void startShow(int interval = 0); void startShow(int interval = 0);
void stopShow(); void stopShow();
void nextSlide(); void nextSlide();
void prevSlide(); void previousSlide();
void reset(); void reset();
signals: signals:

View File

@@ -4,9 +4,6 @@
#include <QWebEngineProfile> #include <QWebEngineProfile>
#include <QWebEngineUrlRequestInterceptor> #include <QWebEngineUrlRequestInterceptor>
#include <QWebEngineUrlRequestJob> #include <QWebEngineUrlRequestJob>
#if QT_VERSION >= 0x051200
#include <QWebEngineUrlScheme>
#endif
#include <QWebEngineUrlSchemeHandler> #include <QWebEngineUrlSchemeHandler>
#include <QWebEngineView> #include <QWebEngineView>
#include <QDesktopServices> #include <QDesktopServices>
@@ -68,10 +65,7 @@ WebView::WebView(QWidget *parent)
_ui() _ui()
{ {
_ui.setupUi(this); _ui.setupUi(this);
#if QT_VERSION >= 0x051200
QWebEngineUrlScheme _ncsheme("nc");
QWebEngineUrlScheme::registerScheme(_ncsheme);
#endif
_webview = new QWebEngineView(this); _webview = new QWebEngineView(this);
_profile = new QWebEngineProfile(this); _profile = new QWebEngineProfile(this);
_page = new WebEnginePage(_profile); _page = new WebEnginePage(_profile);
@@ -181,7 +175,6 @@ WebEnginePage::WebEnginePage(QWebEngineProfile *profile, QObject* parent) : QWeb
} }
QWebEnginePage * WebEnginePage::createWindow(QWebEnginePage::WebWindowType type) { QWebEnginePage * WebEnginePage::createWindow(QWebEnginePage::WebWindowType type) {
Q_UNUSED(type);
ExternalWebEnginePage *view = new ExternalWebEnginePage(this->profile()); ExternalWebEnginePage *view = new ExternalWebEnginePage(this->profile());
return view; return view;
} }
@@ -223,8 +216,6 @@ ExternalWebEnginePage::ExternalWebEnginePage(QWebEngineProfile *profile, QObject
bool ExternalWebEnginePage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) bool ExternalWebEnginePage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame)
{ {
Q_UNUSED(type);
Q_UNUSED(isMainFrame);
QDesktopServices::openUrl(url); QDesktopServices::openUrl(url);
return false; return false;
} }

View File

@@ -160,37 +160,6 @@ void AbstractNetworkJob::slotFinished()
qCWarning(lcNetworkJob) << "SslHandshakeFailedError: " << errorString() << " : can be caused by a webserver wanting SSL client certificates"; qCWarning(lcNetworkJob) << "SslHandshakeFailedError: " << errorString() << " : can be caused by a webserver wanting SSL client certificates";
} }
// Qt doesn't yet transparently resend HTTP2 requests, do so here
const auto maxHttp2Resends = 5;
QByteArray verb = requestVerb(*reply());
if (_reply->error() == QNetworkReply::ContentReSendError
&& _reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute).toBool()) {
if ((_requestBody && !_requestBody->isSequential()) || verb.isEmpty()) {
qCWarning(lcNetworkJob) << "Can't resend HTTP2 request, verb or body not suitable"
<< _reply->request().url() << verb << _requestBody;
} else if (_http2ResendCount >= maxHttp2Resends) {
qCWarning(lcNetworkJob) << "Not resending HTTP2 request, number of resends exhausted"
<< _reply->request().url() << _http2ResendCount;
} else {
qCInfo(lcNetworkJob) << "HTTP2 resending" << _reply->request().url();
_http2ResendCount++;
resetTimeout();
if (_requestBody) {
if(!_requestBody->isOpen())
_requestBody->open(QIODevice::ReadOnly);
_requestBody->seek(0);
}
sendRequest(
verb,
_reply->request().url(),
_reply->request(),
_requestBody);
return;
}
}
if (_reply->error() != QNetworkReply::NoError) { if (_reply->error() != QNetworkReply::NoError) {
if (!_ignoreCredentialFailure || _reply->error() != QNetworkReply::AuthenticationRequiredError) { if (!_ignoreCredentialFailure || _reply->error() != QNetworkReply::AuthenticationRequiredError) {
qCWarning(lcNetworkJob) << _reply->error() << errorString() qCWarning(lcNetworkJob) << _reply->error() << errorString()

View File

@@ -188,8 +188,7 @@ private:
QPointer<QNetworkReply> _reply; // (QPointer because the NetworkManager may be destroyed before the jobs at exit) QPointer<QNetworkReply> _reply; // (QPointer because the NetworkManager may be destroyed before the jobs at exit)
QString _path; QString _path;
QTimer _timer; QTimer _timer;
int _redirectCount = 0; int _redirectCount;
int _http2ResendCount = 0;
// Set by the xyzRequest() functions and needed to be able to redirect // Set by the xyzRequest() functions and needed to be able to redirect
// requests, should it be required. // requests, should it be required.

View File

@@ -36,15 +36,9 @@
#include <QAuthenticator> #include <QAuthenticator>
#include <QStandardPaths> #include <QStandardPaths>
#include <keychain.h>
#include "creds/abstractcredentials.h"
using namespace QKeychain;
namespace OCC { namespace OCC {
Q_LOGGING_CATEGORY(lcAccount, "nextcloud.sync.account", QtInfoMsg) Q_LOGGING_CATEGORY(lcAccount, "nextcloud.sync.account", QtInfoMsg)
const char app_password[] = "_app-password";
Account::Account(QObject *parent) Account::Account(QObject *parent)
: QObject(parent) : QObject(parent)
@@ -59,17 +53,16 @@ AccountPtr Account::create()
AccountPtr acc = AccountPtr(new Account); AccountPtr acc = AccountPtr(new Account);
acc->setSharedThis(acc); acc->setSharedThis(acc);
//TODO: This probably needs to have a better //TODO: This probably needs to have a better
// coupling, but it should work for now. // coupling, but it should work for now.
acc->e2e()->setAccount(acc); acc->e2e()->setAccount(acc);
return acc; return acc;
} }
ClientSideEncryption* Account::e2e() ClientSideEncryption* Account::e2e()
{ {
// Qt expects everything in the connect to be a pointer, so return a pointer. // Qt expects everything in the connect to be a pointer, so return a pointer.
return &_e2e; return &_e2e;
} }
Account::~Account() Account::~Account()
@@ -439,9 +432,6 @@ void Account::slotCredentialsAsked()
void Account::handleInvalidCredentials() void Account::handleInvalidCredentials()
{ {
// Retrieving password will trigger remote wipe check job
retrieveAppPassword();
emit invalidCredentials(); emit invalidCredentials();
} }
@@ -513,63 +503,4 @@ void Account::setNonShib(bool nonShib)
} }
} }
void Account::setAppPassword(QString appPassword){
const QString kck = AbstractCredentials::keychainKey(
url().toString(),
davUser() + app_password,
id()
);
WritePasswordJob *job = new WritePasswordJob(Theme::instance()->appName());
job->setInsecureFallback(false);
job->setKey(kck);
job->setBinaryData(appPassword.toLatin1());
connect(job, &WritePasswordJob::finished, [](Job *) {
qCInfo(lcAccount) << "appPassword stored in keychain";
});
job->start();
}
void Account::retrieveAppPassword(){
const QString kck = AbstractCredentials::keychainKey(
url().toString(),
credentials()->user() + app_password,
id()
);
ReadPasswordJob *job = new ReadPasswordJob(Theme::instance()->appName());
job->setInsecureFallback(false);
job->setKey(kck);
connect(job, &WritePasswordJob::finished, [this](Job *incoming) {
ReadPasswordJob *readJob = static_cast<ReadPasswordJob *>(incoming);
QString pwd("");
// Error or no valid public key error out
if (readJob->error() == NoError &&
readJob->binaryData().length() > 0) {
pwd = readJob->binaryData();
}
emit appPasswordRetrieved(pwd);
});
job->start();
}
void Account::deleteAppPassword(){
const QString kck = AbstractCredentials::keychainKey(
url().toString(),
credentials()->user() + app_password,
id()
);
if (kck.isEmpty()) {
qCDebug(lcAccount) << "appPassword is empty";
return;
}
DeletePasswordJob *job = new DeletePasswordJob(Theme::instance()->appName());
job->setInsecureFallback(false);
job->setKey(kck);
job->start();
}
} // namespace OCC } // namespace OCC

View File

@@ -41,12 +41,6 @@ class QNetworkReply;
class QUrl; class QUrl;
class QNetworkAccessManager; class QNetworkAccessManager;
namespace QKeychain {
class Job;
class WritePasswordJob;
class ReadPasswordJob;
}
namespace OCC { namespace OCC {
class AbstractCredentials; class AbstractCredentials;
@@ -56,6 +50,7 @@ class QuotaInfo;
class AccessManager; class AccessManager;
class SimpleNetworkJob; class SimpleNetworkJob;
/** /**
* @brief Reimplement this to handle SSL errors from libsync * @brief Reimplement this to handle SSL errors from libsync
* @ingroup libsync * @ingroup libsync
@@ -241,11 +236,6 @@ public:
ClientSideEncryption* e2e(); ClientSideEncryption* e2e();
/// Used in RemoteWipe
void retrieveAppPassword();
void setAppPassword(QString appPassword);
void deleteAppPassword();
public slots: public slots:
/// Used when forgetting credentials /// Used when forgetting credentials
void clearQNAMCache(); void clearQNAMCache();
@@ -272,9 +262,6 @@ signals:
void accountChangedAvatar(); void accountChangedAvatar();
void accountChangedDisplayName(); void accountChangedDisplayName();
/// Used in RemoteWipe
void appPasswordRetrieved(QString);
protected Q_SLOTS: protected Q_SLOTS:
void slotCredentialsFetched(); void slotCredentialsFetched();
void slotCredentialsAsked(); void slotCredentialsAsked();

View File

@@ -32,7 +32,6 @@
#include <QUuid> #include <QUuid>
#include <keychain.h> #include <keychain.h>
#include "common/utility.h"
#include "wordlist.h" #include "wordlist.h"
@@ -63,11 +62,11 @@ namespace {
namespace { namespace {
QByteArray BIO2ByteArray(BIO *b) { QByteArray BIO2ByteArray(BIO *b) {
size_t pending = BIO_ctrl_pending(b); int pending = BIO_ctrl_pending(b);
char *tmp = (char *)calloc(pending+1, sizeof(char)); char *tmp = (char *)calloc(pending+1, sizeof(char));
BIO_read(b, tmp, OCC::Utility::convertSizeToInt(pending)); BIO_read(b, tmp, pending);
QByteArray res(tmp, OCC::Utility::convertSizeToInt(pending)); QByteArray res(tmp, pending);
free(tmp); free(tmp);
return res; return res;
@@ -550,7 +549,7 @@ QByteArray decryptStringAsymmetric(EVP_PKEY *privateKey, const QByteArray& data)
} }
const auto ret = std::string((char*) out, outlen); const auto ret = std::string((char*) out, outlen);
QByteArray raw((const char*) out, OCC::Utility::convertSizeToInt(outlen)); QByteArray raw((const char*) out, outlen);
qCInfo(lcCse()) << raw; qCInfo(lcCse()) << raw;
return raw; return raw;
} }
@@ -604,7 +603,7 @@ QByteArray encryptStringAsymmetric(EVP_PKEY *publicKey, const QByteArray& data)
} }
// Transform the encrypted data into base64. // Transform the encrypted data into base64.
QByteArray raw((const char*) out, OCC::Utility::convertSizeToInt(outLen)); QByteArray raw((const char*) out, outLen);
qCInfo(lcCse()) << raw.toBase64(); qCInfo(lcCse()) << raw.toBase64();
return raw.toBase64(); return raw.toBase64();
} }

View File

@@ -432,7 +432,6 @@ void SignPublicKeyApiJob::start()
{ {
QNetworkRequest req; QNetworkRequest req;
req.setRawHeader("OCS-APIREQUEST", "true"); req.setRawHeader("OCS-APIREQUEST", "true");
req.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/x-www-form-urlencoded"));
QUrlQuery query; QUrlQuery query;
query.addQueryItem(QLatin1String("format"), QLatin1String("json")); query.addQueryItem(QLatin1String("format"), QLatin1String("json"));
QUrl url = Utility::concatUrlPath(account()->url(), path()); QUrl url = Utility::concatUrlPath(account()->url(), path());

View File

@@ -37,12 +37,6 @@
#include <QNetworkProxy> #include <QNetworkProxy>
#include <QStandardPaths> #include <QStandardPaths>
#define QTLEGACY (QT_VERSION < QT_VERSION_CHECK(5,9,0))
#if !(QTLEGACY)
#include <QOperatingSystemVersion>
#endif
#define DEFAULT_REMOTE_POLL_INTERVAL 5000 // default remote poll time in milliseconds #define DEFAULT_REMOTE_POLL_INTERVAL 5000 // default remote poll time in milliseconds
#define DEFAULT_MAX_LOG_LINES 20000 #define DEFAULT_MAX_LOG_LINES 20000
@@ -180,11 +174,7 @@ bool ConfigFile::showInExplorerNavigationPane() const
{ {
const bool defaultValue = const bool defaultValue =
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#if QTLEGACY QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10
(QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS10);
#else
QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10;
#endif
#else #else
false false
#endif #endif

View File

@@ -798,11 +798,7 @@ namespace { // Anonymous namespace for the recall feature
static void preserveGroupOwnership(const QString &fileName, const QFileInfo &fi) static void preserveGroupOwnership(const QString &fileName, const QFileInfo &fi)
{ {
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
int chownErr = chown(fileName.toLocal8Bit().constData(), -1, fi.groupId()); chown(fileName.toLocal8Bit().constData(), -1, fi.groupId());
if (chownErr) {
// TODO: Consider further error handling!
qCWarning(lcPropagateDownload) << QString("preserveGroupOwnership: chown error %1: setting group %2 failed on file %3").arg(chownErr).arg(fi.groupId()).arg(fileName);
}
#else #else
Q_UNUSED(fileName); Q_UNUSED(fileName);
Q_UNUSED(fi); Q_UNUSED(fi);

View File

@@ -177,14 +177,6 @@ QIcon Theme::themeIcon(const QString &name, bool sysTray, bool sysTrayMenuVisibl
return cached; return cached;
} }
QIcon Theme::uiThemeIcon(const QString &iconName, bool uiHasDarkBg) const
{
QString themeResBasePath = ":/client/theme/";
QString iconPath = themeResBasePath + (uiHasDarkBg?"white/":"black/") + iconName;
std::string icnPath = iconPath.toUtf8().constData();
return QIcon(QPixmap(iconPath));
}
QString Theme::hidpiFileName(const QString &fileName, QPaintDevice *dev) QString Theme::hidpiFileName(const QString &fileName, QPaintDevice *dev)
{ {
qreal devicePixelRatio = dev ? dev->devicePixelRatio() : qApp->primaryScreen()->devicePixelRatio(); qreal devicePixelRatio = dev ? dev->devicePixelRatio() : qApp->primaryScreen()->devicePixelRatio();

View File

@@ -347,14 +347,6 @@ public:
* important dependency versions. * important dependency versions.
*/ */
virtual QString versionSwitchOutput() const; virtual QString versionSwitchOutput() const;
/**
* @brief Request suitable QIcon resource depending on the background colour of the parent widget.
*
* This should be replaced (TODO) by a real theming implementation for the client UI
* (actually 2019/09/13 only systray theming).
*/
virtual QIcon uiThemeIcon(const QString &iconName, bool uiHasDarkBg) const;
protected: protected:
#ifndef TOKEN_AUTH_ONLY #ifndef TOKEN_AUTH_ONLY

View File

@@ -40,5 +40,3 @@ System Volume Information
.nfs* .nfs*
My Saved Places. My Saved Places.
\#*#

View File

@@ -12,10 +12,10 @@ include_directories(${CMAKE_SOURCE_DIR}/src
${SQLITE3_INCLUDE_DIR} ${SQLITE3_INCLUDE_DIR}
) )
include(nextcloud_add_test.cmake) include(owncloud_add_test.cmake)
nextcloud_add_test(NextcloudPropagator "") owncloud_add_test(OwncloudPropagator "")
nextcloud_add_test(Updater "") owncloud_add_test(Updater "")
SET(FolderWatcher_SRC ../src/gui/folderwatcher.cpp) SET(FolderWatcher_SRC ../src/gui/folderwatcher.cpp)
@@ -29,64 +29,49 @@ IF( APPLE )
list(APPEND FolderWatcher_SRC ../src/gui/folderwatcher_mac.cpp) list(APPEND FolderWatcher_SRC ../src/gui/folderwatcher_mac.cpp)
list(APPEND FolderWatcher_SRC ../src/gui/socketapisocket_mac.mm) list(APPEND FolderWatcher_SRC ../src/gui/socketapisocket_mac.mm)
ENDIF() ENDIF()
nextcloud_add_test(NetrcParser ../src/cmd/netrcparser.cpp) owncloud_add_test(NetrcParser ../src/cmd/netrcparser.cpp)
nextcloud_add_test(OwnSql "") owncloud_add_test(OwnSql "")
nextcloud_add_test(SyncJournalDB "") owncloud_add_test(SyncJournalDB "")
nextcloud_add_test(SyncFileItem "") owncloud_add_test(SyncFileItem "")
nextcloud_add_test(ConcatUrl "") owncloud_add_test(ConcatUrl "")
nextcloud_add_test(XmlParse "") owncloud_add_test(XmlParse "")
nextcloud_add_test(ChecksumValidator "") owncloud_add_test(ChecksumValidator "")
nextcloud_add_test(ExcludedFiles "") owncloud_add_test(ExcludedFiles "")
nextcloud_add_test(FileSystem "") owncloud_add_test(FileSystem "")
nextcloud_add_test(Utility "") owncloud_add_test(Utility "")
nextcloud_add_test(SyncEngine "syncenginetestutils.h") owncloud_add_test(SyncEngine "syncenginetestutils.h")
nextcloud_add_test(SyncMove "syncenginetestutils.h") owncloud_add_test(SyncMove "syncenginetestutils.h")
nextcloud_add_test(SyncConflict "syncenginetestutils.h") owncloud_add_test(SyncConflict "syncenginetestutils.h")
nextcloud_add_test(SyncFileStatusTracker "syncenginetestutils.h") owncloud_add_test(SyncFileStatusTracker "syncenginetestutils.h")
nextcloud_add_test(ChunkingNg "syncenginetestutils.h") owncloud_add_test(ChunkingNg "syncenginetestutils.h")
nextcloud_add_test(UploadReset "syncenginetestutils.h") owncloud_add_test(UploadReset "syncenginetestutils.h")
nextcloud_add_test(AllFilesDeleted "syncenginetestutils.h") owncloud_add_test(AllFilesDeleted "syncenginetestutils.h")
nextcloud_add_test(Blacklist "syncenginetestutils.h") owncloud_add_test(Blacklist "syncenginetestutils.h")
nextcloud_add_test(FolderWatcher "${FolderWatcher_SRC}") owncloud_add_test(FolderWatcher "${FolderWatcher_SRC}")
if( UNIX AND NOT APPLE ) if( UNIX AND NOT APPLE )
nextcloud_add_test(InotifyWatcher "${FolderWatcher_SRC}") owncloud_add_test(InotifyWatcher "${FolderWatcher_SRC}")
endif(UNIX AND NOT APPLE) endif(UNIX AND NOT APPLE)
nextcloud_add_benchmark(LargeSync "syncenginetestutils.h") owncloud_add_benchmark(LargeSync "syncenginetestutils.h")
SET(FolderMan_SRC ../src/gui/folderman.cpp) SET(FolderMan_SRC ../src/gui/folderman.cpp)
list(APPEND FolderMan_SRC ../src/gui/folder.cpp ) list(APPEND FolderMan_SRC ../src/gui/folder.cpp )
list(APPEND FolderMan_SRC ../src/gui/socketapi.cpp ) list(APPEND FolderMan_SRC ../src/gui/socketapi.cpp )
list(APPEND FolderMan_SRC ../src/gui/accountstate.cpp )
list(APPEND FolderMan_SRC ../src/gui/syncrunfilelog.cpp ) list(APPEND FolderMan_SRC ../src/gui/syncrunfilelog.cpp )
list(APPEND FolderMan_SRC ../src/gui/lockwatcher.cpp ) list(APPEND FolderMan_SRC ../src/gui/lockwatcher.cpp )
list(APPEND FolderMan_SRC ../src/gui/guiutility.cpp ) list(APPEND FolderMan_SRC ../src/gui/guiutility.cpp )
list(APPEND FolderMan_SRC ../src/gui/navigationpanehelper.cpp ) list(APPEND FolderMan_SRC ../src/gui/navigationpanehelper.cpp )
list(APPEND FolderMan_SRC ../src/gui/connectionvalidator.cpp ) list(APPEND FolderMan_SRC ../src/gui/connectionvalidator.cpp )
list(APPEND FolderMan_SRC ../src/gui/clientproxy.cpp ) list(APPEND FolderMan_SRC ../src/gui/clientproxy.cpp )
list(APPEND FolderMan_SRC ../src/gui/accountstate.cpp )
list(APPEND FolderMan_SRC ../src/gui/remotewipe.cpp )
list(APPEND FolderMan_SRC ${FolderWatcher_SRC}) list(APPEND FolderMan_SRC ${FolderWatcher_SRC})
list(APPEND FolderMan_SRC stubfolderman.cpp ) list(APPEND FolderMan_SRC stub.cpp )
nextcloud_add_test(FolderMan "${FolderMan_SRC}") owncloud_add_test(FolderMan "${FolderMan_SRC}")
SET(RemoteWipe_SRC ../src/gui/remotewipe.cpp) owncloud_add_test(OAuth "syncenginetestutils.h;../src/gui/creds/oauth.cpp")
list(APPEND RemoteWipe_SRC ../src/gui/clientproxy.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/guiutility.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/connectionvalidator.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/accountstate.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/socketapi.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/folder.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/syncrunfilelog.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/folderwatcher_linux.cpp )
list(APPEND RemoteWipe_SRC ../src/gui/folderwatcher.cpp )
list(APPEND RemoteWipe_SRC ${RemoteWipe_SRC})
list(APPEND RemoteWipe_SRC stubremotewipe.cpp )
nextcloud_add_test(RemoteWipe "${RemoteWipe_SRC}")
nextcloud_add_test(OAuth "syncenginetestutils.h;../src/gui/creds/oauth.cpp")
configure_file(test_journal.db "${PROJECT_BINARY_DIR}/bin/test_journal.db" COPYONLY) configure_file(test_journal.db "${PROJECT_BINARY_DIR}/bin/test_journal.db" COPYONLY)

View File

@@ -1,6 +1,6 @@
find_package(Qt5 COMPONENTS Core Test Xml Network REQUIRED) find_package(Qt5 COMPONENTS Core Test Xml Network REQUIRED)
macro(nextcloud_add_test test_class additional_cpp) macro(owncloud_add_test test_class additional_cpp)
set(CMAKE_AUTOMOC TRUE) set(CMAKE_AUTOMOC TRUE)
set(OWNCLOUD_TEST_CLASS ${test_class}) set(OWNCLOUD_TEST_CLASS ${test_class})
string(TOLOWER "${OWNCLOUD_TEST_CLASS}" OWNCLOUD_TEST_CLASS_LOWERCASE) string(TOLOWER "${OWNCLOUD_TEST_CLASS}" OWNCLOUD_TEST_CLASS_LOWERCASE)
@@ -19,7 +19,7 @@ macro(nextcloud_add_test test_class additional_cpp)
add_test(NAME ${OWNCLOUD_TEST_CLASS}Test COMMAND ${OWNCLOUD_TEST_CLASS}Test) add_test(NAME ${OWNCLOUD_TEST_CLASS}Test COMMAND ${OWNCLOUD_TEST_CLASS}Test)
endmacro() endmacro()
macro(nextcloud_add_benchmark test_class additional_cpp) macro(owncloud_add_benchmark test_class additional_cpp)
set(CMAKE_AUTOMOC TRUE) set(CMAKE_AUTOMOC TRUE)
set(OWNCLOUD_TEST_CLASS ${test_class}) set(OWNCLOUD_TEST_CLASS ${test_class})
string(TOLOWER "${OWNCLOUD_TEST_CLASS}" OWNCLOUD_TEST_CLASS_LOWERCASE) string(TOLOWER "${OWNCLOUD_TEST_CLASS}" OWNCLOUD_TEST_CLASS_LOWERCASE)

View File

@@ -1,11 +1,7 @@
// stub to prevent linker error // stub to prevent linker error
#include "accountmanager.h" #include "accountmanager.h"
OCC::AccountManager *OCC::AccountManager::instance() { return static_cast<AccountManager *>(new QObject); } OCC::AccountManager *OCC::AccountManager::instance() { return static_cast<AccountManager *>(new QObject); }
void OCC::AccountManager::save(bool) { }
void OCC::AccountManager::saveAccountState(AccountState *) { } void OCC::AccountManager::saveAccountState(AccountState *) { }
void OCC::AccountManager::deleteAccount(AccountState *) { } void OCC::AccountManager::save(bool saveCredentials) { Q_UNUSED(saveCredentials); }
void OCC::AccountManager::accountRemoved(OCC::AccountState*) { } void OCC::AccountManager::accountRemoved(OCC::AccountState*) { }
OCC::AccountStatePtr OCC::AccountManager::account(const QString &){ return AccountStatePtr(); }
void OCC::AccountManager::removeAccountFolders(OCC::AccountState*) { }
const QMetaObject OCC::AccountManager::staticMetaObject = QObject::staticMetaObject; const QMetaObject OCC::AccountManager::staticMetaObject = QObject::staticMetaObject;

View File

@@ -1,30 +0,0 @@
// stub to prevent linker error
#include "accountmanager.h"
#include "accountstate.h"
#include "socketapi.h"
#include "folderman.h"
OCC::AccountManager *OCC::AccountManager::instance() { return static_cast<AccountManager *>(new QObject); }
void OCC::AccountManager::save(bool) { }
OCC::AccountState *OCC::AccountManager::addAccount(const AccountPtr& ac) { return new OCC::AccountState(ac); }
void OCC::AccountManager::deleteAccount(AccountState *) { }
void OCC::AccountManager::accountRemoved(OCC::AccountState*) { }
OCC::AccountStatePtr OCC::AccountManager::account(const QString &){ return AccountStatePtr(); }
const QMetaObject OCC::AccountManager::staticMetaObject = QObject::staticMetaObject;
OCC::FolderMan *OCC::FolderMan::instance() { return static_cast<FolderMan *>(new QObject); }
void OCC::FolderMan::wipeDone(OCC::AccountState*, bool) { }
OCC::Folder* OCC::FolderMan::addFolder(OCC::AccountState* as, OCC::FolderDefinition const &f) { return nullptr; }
void OCC::FolderMan::slotWipeFolderForAccount(OCC::AccountState*) { }
QString OCC::FolderMan::unescapeAlias(QString const&){ return QString(); }
QString OCC::FolderMan::escapeAlias(QString const&){ return QString(); }
void OCC::FolderMan::scheduleFolder(OCC::Folder*){ }
OCC::SocketApi *OCC::FolderMan::socketApi(){ return new SocketApi; }
OCC::Folder::Map OCC::FolderMan::map() { return OCC::Folder::Map(); }
void OCC::FolderMan::setSyncEnabled(bool) { }
void OCC::FolderMan::slotSyncOnceFileUnlocks(QString const&) { }
void OCC::FolderMan::slotScheduleETagJob(QString const&, OCC::RequestEtagJob*){ }
OCC::Folder *OCC::FolderMan::folderForPath(QString const&) { return nullptr; }
OCC::Folder* OCC::FolderMan::folder(QString const&) { return nullptr; }
void OCC::FolderMan::folderSyncStateChange(OCC::Folder*) { }
const QMetaObject OCC::FolderMan::staticMetaObject = QObject::staticMetaObject;

View File

@@ -39,8 +39,6 @@ private slots:
QVERIFY(excluded.isExcluded("/a/foo_conflict-bar", "/a", keepHidden)); QVERIFY(excluded.isExcluded("/a/foo_conflict-bar", "/a", keepHidden));
QVERIFY(excluded.isExcluded("/a/foo (conflicted copy bar)", "/a", keepHidden)); QVERIFY(excluded.isExcluded("/a/foo (conflicted copy bar)", "/a", keepHidden));
QVERIFY(excluded.isExcluded("/a/.b", "/a", excludeHidden)); QVERIFY(excluded.isExcluded("/a/.b", "/a", excludeHidden));
QVERIFY(excluded.isExcluded("/a/#b#", "/a", keepHidden));
} }
}; };

View File

@@ -14,10 +14,29 @@
#include "account.h" #include "account.h"
#include "accountstate.h" #include "accountstate.h"
#include "configfile.h" #include "configfile.h"
#include "testhelper.h" #include "creds/httpcredentials.h"
using namespace OCC; using namespace OCC;
class HttpCredentials;
class HttpCredentialsTest : public HttpCredentials {
public:
HttpCredentialsTest(const QString& user, const QString& password)
: HttpCredentials(user, password)
{}
void askFromUser() Q_DECL_OVERRIDE {
}
};
static FolderDefinition folderDefinition(const QString &path) {
FolderDefinition d;
d.localPath = path;
d.targetPath = path;
d.alias = path;
return d;
}
class TestFolderMan: public QObject class TestFolderMan: public QObject
{ {

View File

@@ -1,28 +0,0 @@
#ifndef TESTHELPER_H
#define TESTHELPER_H
#include "folder.h"
#include "creds/httpcredentials.h"
using namespace OCC;
class HttpCredentialsTest : public HttpCredentials {
public:
HttpCredentialsTest(const QString& user, const QString& password)
: HttpCredentials(user, password)
{}
void askFromUser() Q_DECL_OVERRIDE {
}
};
static FolderDefinition folderDefinition(const QString &path) {
FolderDefinition d;
d.localPath = path;
d.targetPath = path;
d.alias = path;
return d;
}
#endif // TESTHELPER_H

View File

@@ -8,21 +8,21 @@
#include <QDebug> #include <QDebug>
#include "propagatedownload.h" #include "propagatedownload.h"
#include "nextcloudpropagator_p.h" #include "owncloudpropagator_p.h"
using namespace OCC; using namespace OCC;
namespace OCC { namespace OCC {
QString OWNCLOUDSYNC_EXPORT createDownloadTmpFileName(const QString &previous); QString OWNCLOUDSYNC_EXPORT createDownloadTmpFileName(const QString &previous);
} }
class TestNextcloudPropagator : public QObject class TestOwncloudPropagator : public QObject
{ {
Q_OBJECT Q_OBJECT
private slots: private slots:
void testUpdateErrorFromSession() void testUpdateErrorFromSession()
{ {
// NextcloudPropagator propagator( NULL, QLatin1String("test1"), QLatin1String("test2"), new ProgressDatabase); // OwncloudPropagator propagator( NULL, QLatin1String("test1"), QLatin1String("test2"), new ProgressDatabase);
QVERIFY( true ); QVERIFY( true );
} }
@@ -78,5 +78,5 @@ private slots:
} }
}; };
QTEST_APPLESS_MAIN(TestNextcloudPropagator) QTEST_APPLESS_MAIN(TestOwncloudPropagator)
#include "testnextcloudpropagator.moc" #include "testowncloudpropagator.moc"

View File

@@ -1,83 +0,0 @@
/*
* This software is in the public domain, furnished "as is", without technical
* support, and with no warranty, express or implied, as to its usefulness for
* any purpose.
*
*/
#include <qglobal.h>
#include <QTemporaryDir>
#include <QtTest>
#include "remotewipe.h"
#include "common/utility.h"
#include "folderman.h"
#include "account.h"
#include "accountstate.h"
#include "configfile.h"
#include "testhelper.h"
using namespace OCC;
class TestRemoteWipe: public QObject
{
Q_OBJECT
private slots:
// TODO
void testWipe(){
// QTemporaryDir dir;
// ConfigFile::setConfDir(dir.path()); // we don't want to pollute the user's config file
// QVERIFY(dir.isValid());
// QDir dirToRemove(dir.path());
// QVERIFY(dirToRemove.mkpath("nextcloud"));
// QString dirPath = dirToRemove.canonicalPath();
// AccountPtr account = Account::create();
// QVERIFY(account);
// auto manager = AccountManager::instance();
// QVERIFY(manager);
// AccountState *newAccountState = manager->addAccount(account);
// manager->save();
// QVERIFY(newAccountState);
// QUrl url("http://example.de");
// HttpCredentialsTest *cred = new HttpCredentialsTest("testuser", "secret");
// account->setCredentials(cred);
// account->setUrl( url );
// FolderMan *folderman = FolderMan::instance();
// folderman->addFolder(newAccountState, folderDefinition(dirPath + "/sub/nextcloud/"));
// // check if account exists
// qDebug() << "Does account exists?!";
// QVERIFY(!account->id().isEmpty());
// manager->deleteAccount(newAccountState);
// manager->save();
// // check if account exists
// qDebug() << "Does account exists yet?!";
// QVERIFY(account);
// // check if folder exists
// QVERIFY(dirToRemove.exists());
// // remote folders
// qDebug() << "Removing folder for account " << newAccountState->account()->url();
// folderman->slotWipeFolderForAccount(newAccountState);
// // check if folders dont exist anymore
// QCOMPARE(dirToRemove.exists(), false);
}
};
QTEST_APPLESS_MAIN(TestRemoteWipe)
#include "testremotewipe.moc"

View File

@@ -543,7 +543,7 @@ private slots:
QVERIFY(conflicts.size() == 2); QVERIFY(conflicts.size() == 2);
QVERIFY(conflicts[0].contains("A (conflicted copy")); QVERIFY(conflicts[0].contains("A (conflicted copy"));
QVERIFY(conflicts[1].contains("B (conflicted copy")); QVERIFY(conflicts[1].contains("B (conflicted copy"));
for (const auto& conflict : conflicts) for (auto conflict : conflicts)
QDir(fakeFolder.localPath() + conflict).removeRecursively(); QDir(fakeFolder.localPath() + conflict).removeRecursively();
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@@ -581,7 +581,7 @@ private slots:
auto conflicts = findConflicts(fakeFolder.currentLocalState()); auto conflicts = findConflicts(fakeFolder.currentLocalState());
QVERIFY(conflicts.size() == 1); QVERIFY(conflicts.size() == 1);
QVERIFY(conflicts[0].contains("A (conflicted copy")); QVERIFY(conflicts[0].contains("A (conflicted copy"));
for (const auto& conflict : conflicts) for (auto conflict : conflicts)
QDir(fakeFolder.localPath() + conflict).removeRecursively(); QDir(fakeFolder.localPath() + conflict).removeRecursively();
QVERIFY(fakeFolder.syncEngine().isAnotherSyncNeeded() == ImmediateFollowUp); QVERIFY(fakeFolder.syncEngine().isAnotherSyncNeeded() == ImmediateFollowUp);

View File

@@ -289,12 +289,12 @@ private slots:
<< "foo bla bar/file" << "foo bla bar/file"
<< "fo_" << "fo_"
<< "fo_/file"; << "fo_/file";
for (const auto& elem : elements) for (auto elem : elements)
makeEntry(elem); makeEntry(elem);
auto checkElements = [&]() { auto checkElements = [&]() {
bool ok = true; bool ok = true;
for (const auto& elem : elements) { for (auto elem : elements) {
SyncJournalFileRecord record; SyncJournalFileRecord record;
_db.getFileRecord(elem, &record); _db.getFileRecord(elem, &record);
if (!record.isValid()) { if (!record.isValid()) {

Some files were not shown because too many files have changed in this diff Show More