Skip to content

Commit

Permalink
Discovery: Handle the blacklistFiles from the server capabilities
Browse files Browse the repository at this point in the history
Issue #434

Ideally one could add the blacklist to the exlucde reggexp, but this
is simpler
  • Loading branch information
ogoffart authored and er-vin committed Dec 11, 2020
1 parent b4f68b7 commit 723ccf7
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/csync/csync_exclude.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ enum CSYNC_EXCLUDE_TYPE {
CSYNC_FILE_EXCLUDE_HIDDEN,
CSYNC_FILE_EXCLUDE_STAT_FAILED,
CSYNC_FILE_EXCLUDE_CONFLICT,
CSYNC_FILE_EXCLUDE_CANNOT_ENCODE
CSYNC_FILE_EXCLUDE_CANNOT_ENCODE,
CSYNC_FILE_EXCLUDE_SERVER_BLACKLISTED,
};

class ExcludedFilesTest;
Expand Down
5 changes: 5 additions & 0 deletions src/libsync/capabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ bool Capabilities::uploadConflictFiles() const
return _capabilities[QStringLiteral("uploadConflictFiles")].toBool();
}

QStringList Capabilities::blacklistedFiles() const
{
return _capabilities["files"].toMap()["blacklisted_files"].toStringList();
}

/*-------------------------------------------------------------------------------------*/

// Direct Editing
Expand Down
5 changes: 5 additions & 0 deletions src/libsync/capabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ class OWNCLOUDSYNC_EXPORT Capabilities
*/
QString invalidFilenameRegex() const;

/**
* return the list of filename that should not be uploaded
*/
QStringList blacklistedFiles() const;

/**
* Whether conflict files should remain local (default) or should be uploaded.
*/
Expand Down
14 changes: 12 additions & 2 deletions src/libsync/discovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ void ProcessDirectoryJob::process()
// local stat function.
// Recall file shall not be ignored (#4420)
bool isHidden = e.localEntry.isHidden || (f.first[0] == '.' && f.first != QLatin1String(".sys.admin#recall#"));
if (handleExcluded(path._target, e.localEntry.isDirectory || e.serverEntry.isDirectory, isHidden, e.localEntry.isSymLink))
if (handleExcluded(path._target, e.localEntry.name,
e.localEntry.isDirectory || e.serverEntry.isDirectory, isHidden,
e.localEntry.isSymLink))
continue;

if (_queryServer == InBlackList || _discoveryData->isInSelectiveSyncBlackList(path._original)) {
Expand All @@ -154,7 +156,7 @@ void ProcessDirectoryJob::process()
QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs);
}

bool ProcessDirectoryJob::handleExcluded(const QString &path, bool isDirectory, bool isHidden, bool isSymlink)
bool ProcessDirectoryJob::handleExcluded(const QString &path, const QString &localName, bool isDirectory, bool isHidden, bool isSymlink)
{
auto excluded = _discoveryData->_excludes->traversalPatternMatch(path, isDirectory ? ItemTypeDirectory : ItemTypeFile);

Expand All @@ -169,6 +171,11 @@ bool ProcessDirectoryJob::handleExcluded(const QString &path, bool isDirectory,
if (excluded == CSYNC_NOT_EXCLUDED && _discoveryData->_ignoreHiddenFiles && isHidden) {
excluded = CSYNC_FILE_EXCLUDE_HIDDEN;
}
if (excluded == CSYNC_NOT_EXCLUDED && !localName.isEmpty()
&& _discoveryData->_serverBlacklistedFiles.contains(localName)) {
excluded = CSYNC_FILE_EXCLUDE_SERVER_BLACKLISTED;
isInvalidPattern = true;
}

auto localCodec = QTextCodec::codecForLocale();
if (localCodec->mibEnum() != 106) {
Expand Down Expand Up @@ -248,6 +255,9 @@ bool ProcessDirectoryJob::handleExcluded(const QString &path, bool isDirectory,
case CSYNC_FILE_EXCLUDE_CANNOT_ENCODE:
item->_errorString = tr("The filename cannot be encoded on your file system.");
break;
case CSYNC_FILE_EXCLUDE_SERVER_BLACKLISTED:
item->_errorString = tr("The filename is blacklisted on the server.");
break;
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/libsync/discovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,10 @@ class ProcessDirectoryJob : public QObject
*/
void process();

// return true if the file is excluded
bool handleExcluded(const QString &path, bool isDirectory, bool isHidden, bool isSymlink);
// return true if the file is excluded.
// path is the full relative path of the file. localName is the base name of the local entry.
bool handleExcluded(const QString &path, const QString &localName, bool isDirectory,
bool isHidden, bool isSymlink);

/** Reconcile local/remote/db information for a single item.
*
Expand Down
1 change: 1 addition & 0 deletions src/libsync/discoveryphase.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ class DiscoveryPhase : public QObject
QStringList _selectiveSyncWhiteList;
ExcludedFiles *_excludes;
QRegExp _invalidFilenameRx; // FIXME: maybe move in ExcludedFiles
QStringList _serverBlacklistedFiles; // The blacklist from the capabilities
bool _ignoreHiddenFiles = false;
std::function<bool(const QString &)> _shouldDiscoverLocaly;

Expand Down
1 change: 1 addition & 0 deletions src/libsync/syncengine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ void SyncEngine::slotStartDiscovery()
}
if (!invalidFilenamePattern.isEmpty())
_discoveryPhase->_invalidFilenameRx = QRegExp(invalidFilenamePattern);
_discoveryPhase->_serverBlacklistedFiles = _account->capabilities().blacklistedFiles();
_discoveryPhase->_ignoreHiddenFiles = ignoreHiddenFiles();

connect(_discoveryPhase.data(), &DiscoveryPhase::itemDiscovered, this, &SyncEngine::slotItemDiscovered);
Expand Down
18 changes: 18 additions & 0 deletions test/testlocaldiscovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,25 @@ private slots:
QCOMPARE(fakeFolder.currentRemoteState(), expectedState);
}

// Tests the behavior of invalid filename detection
void testServerBlacklist()
{
FakeFolder fakeFolder { FileInfo::A12_B12_C12_S12() };
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());

fakeFolder.syncEngine().account()->setCapabilities({ { "files",
QVariantMap { { "blacklisted_files", QVariantList { ".foo", "bar" } } } } });
fakeFolder.localModifier().insert("C/.foo");
fakeFolder.localModifier().insert("C/bar");
fakeFolder.localModifier().insert("C/moo");
fakeFolder.localModifier().insert("C/.moo");

QVERIFY(fakeFolder.syncOnce());
QVERIFY(fakeFolder.currentRemoteState().find("C/moo"));
QVERIFY(fakeFolder.currentRemoteState().find("C/.moo"));
QVERIFY(!fakeFolder.currentRemoteState().find("C/.foo"));
QVERIFY(!fakeFolder.currentRemoteState().find("C/bar"));
}
};

QTEST_GUILESS_MAIN(TestLocalDiscovery)
Expand Down

0 comments on commit 723ccf7

Please sign in to comment.