Skip to content

Commit

Permalink
test and ensure folders can change between read/write and read-only
Browse files Browse the repository at this point in the history
Signed-off-by: Matthieu Gallien <[email protected]>
  • Loading branch information
mgallien committed Feb 19, 2024
1 parent 940758a commit 406cea5
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/libsync/owncloudpropagator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,37 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status)
if (_item->_instruction == CSYNC_INSTRUCTION_RENAME
|| _item->_instruction == CSYNC_INSTRUCTION_NEW
|| _item->_instruction == CSYNC_INSTRUCTION_UPDATE_METADATA) {

if (!_item->_remotePerm.isNull() &&
!_item->_remotePerm.hasPermission(RemotePermissions::CanAddFile) &&
!_item->_remotePerm.hasPermission(RemotePermissions::CanRename) &&
!_item->_remotePerm.hasPermission(RemotePermissions::CanMove) &&
!_item->_remotePerm.hasPermission(RemotePermissions::CanAddSubDirectories)) {
try {
std::filesystem::permissions(propagator()->fullLocalPath(_item->_file).toStdWString(), std::filesystem::perms::owner_write | std::filesystem::perms::group_write | std::filesystem::perms::others_write, std::filesystem::perm_options::remove);
}
catch (const std::filesystem::filesystem_error &e)
{
qCWarning(lcDirectory) << "exception when checking parent folder access rights" << e.what() << e.path1().c_str() << e.path2().c_str();
_item->_status = SyncFileItem::NormalError;
_item->_errorString = tr("The folder %1 cannot be made read-only: %2").arg(_item->_file, e.what());
}
} else if (!_item->_remotePerm.isNull() &&
(_item->_remotePerm.hasPermission(RemotePermissions::CanAddFile) ||
!_item->_remotePerm.hasPermission(RemotePermissions::CanRename) ||
!_item->_remotePerm.hasPermission(RemotePermissions::CanMove) ||
!_item->_remotePerm.hasPermission(RemotePermissions::CanAddSubDirectories))) {
try {
std::filesystem::permissions(propagator()->fullLocalPath(_item->_file).toStdWString(), std::filesystem::perms::owner_write, std::filesystem::perm_options::add);
}
catch (const std::filesystem::filesystem_error &e)
{
qCWarning(lcDirectory) << "exception when checking parent folder access rights" << e.what() << e.path1().c_str() << e.path2().c_str();
_item->_status = SyncFileItem::NormalError;
_item->_errorString = tr("The folder %1 cannot be made read-only: %2").arg(_item->_file, e.what());
}
}

const auto result = propagator()->updateMetadata(*_item);
if (!result) {
status = _item->_status = SyncFileItem::FatalError;
Expand Down
89 changes: 89 additions & 0 deletions test/testpermissions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <QtTest>

#include <filesystem>
#include <iostream>

using namespace OCC;

Expand Down Expand Up @@ -590,6 +591,94 @@ private slots:

QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}

static void demo_perms(std::filesystem::perms p)
{
using std::filesystem::perms;
auto show = [=](char op, perms perm)
{
std::cout << (perms::none == (perm & p) ? '-' : op);
};
show('r', perms::owner_read);
show('w', perms::owner_write);
show('x', perms::owner_exec);
show('r', perms::group_read);
show('w', perms::group_write);
show('x', perms::group_exec);
show('r', perms::others_read);
show('w', perms::others_write);
show('x', perms::others_exec);
std::cout << std::endl;
}

void testReadOnlyFolderIsReallyReadOnly()
{
FakeFolder fakeFolder{FileInfo{}};

auto &remote = fakeFolder.remoteModifier();

remote.mkdir("readOnlyFolder");

remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("M");

QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());

const auto folderStatus = std::filesystem::status(static_cast<QString>(fakeFolder.localPath() + QStringLiteral("/readOnlyFolder")).toStdWString());
QVERIFY(folderStatus.permissions() & std::filesystem::perms::owner_read);
}

void testReadWriteFolderIsReallyReadWrite()
{
FakeFolder fakeFolder{FileInfo{}};

auto &remote = fakeFolder.remoteModifier();

remote.mkdir("readWriteFolder");

remote.find("readWriteFolder")->permissions = RemotePermissions::fromServerString("WDNVRSM");

QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());

const auto folderStatus = std::filesystem::status(static_cast<QString>(fakeFolder.localPath() + QStringLiteral("/readWriteFolder")).toStdWString());
QVERIFY(folderStatus.permissions() & std::filesystem::perms::owner_read);
QVERIFY(folderStatus.permissions() & std::filesystem::perms::owner_write);
}

void testChangePermissionsFolder()
{
FakeFolder fakeFolder{FileInfo{}};

auto &remote = fakeFolder.remoteModifier();

remote.mkdir("testFolder");

remote.find("testFolder")->permissions = RemotePermissions::fromServerString("M");

QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());

auto folderStatus = std::filesystem::status(static_cast<QString>(fakeFolder.localPath() + QStringLiteral("/testFolder")).toStdWString());
QVERIFY(folderStatus.permissions() & std::filesystem::perms::owner_read);

remote.find("testFolder")->permissions = RemotePermissions::fromServerString("WDNVRSM");

QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());

folderStatus = std::filesystem::status(static_cast<QString>(fakeFolder.localPath() + QStringLiteral("/testFolder")).toStdWString());
QVERIFY(folderStatus.permissions() & std::filesystem::perms::owner_read);
QVERIFY(folderStatus.permissions() & std::filesystem::perms::owner_write);

remote.find("testFolder")->permissions = RemotePermissions::fromServerString("M");

QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());

folderStatus = std::filesystem::status(static_cast<QString>(fakeFolder.localPath() + QStringLiteral("/testFolder")).toStdWString());
QVERIFY(folderStatus.permissions() & std::filesystem::perms::owner_read);
}
};

QTEST_GUILESS_MAIN(TestPermissions)
Expand Down

0 comments on commit 406cea5

Please sign in to comment.