From e724e8db60dae7f73b1f5185085f4e789548ec3a Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Sat, 7 Sep 2019 12:12:22 +0200 Subject: [PATCH] Fixed: Copy linux permission mask when moving folder to recycle bin folder fixes #3161 --- src/NzbDrone.Common/Disk/DiskProviderBase.cs | 1 + .../Disk/DiskTransferService.cs | 2 ++ src/NzbDrone.Common/Disk/IDiskProvider.cs | 1 + .../DiskProviderTests/DiskProviderFixture.cs | 30 +++++++++++++++++++ src/NzbDrone.Mono/Disk/DiskProvider.cs | 23 ++++++++++++++ src/NzbDrone.Windows/Disk/DiskProvider.cs | 7 ++++- 6 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Common/Disk/DiskProviderBase.cs b/src/NzbDrone.Common/Disk/DiskProviderBase.cs index 08acafff6..f2b3041fd 100644 --- a/src/NzbDrone.Common/Disk/DiskProviderBase.cs +++ b/src/NzbDrone.Common/Disk/DiskProviderBase.cs @@ -32,6 +32,7 @@ namespace NzbDrone.Common.Disk public abstract long? GetAvailableSpace(string path); public abstract void InheritFolderPermissions(string filename); public abstract void SetPermissions(string path, string mask, string user, string group); + public abstract void CopyPermissions(string sourcePath, string targetPath, bool includeOwner); public abstract long? GetTotalSize(string path); public DateTime FolderGetCreationTime(string path) diff --git a/src/NzbDrone.Common/Disk/DiskTransferService.cs b/src/NzbDrone.Common/Disk/DiskTransferService.cs index 5a9ef8099..51a25ee2f 100644 --- a/src/NzbDrone.Common/Disk/DiskTransferService.cs +++ b/src/NzbDrone.Common/Disk/DiskTransferService.cs @@ -76,6 +76,8 @@ namespace NzbDrone.Common.Disk if (!_diskProvider.FolderExists(targetPath)) { _diskProvider.CreateFolder(targetPath); + + _diskProvider.CopyPermissions(sourcePath, targetPath); } var result = mode; diff --git a/src/NzbDrone.Common/Disk/IDiskProvider.cs b/src/NzbDrone.Common/Disk/IDiskProvider.cs index 20f36c67d..7324898e2 100644 --- a/src/NzbDrone.Common/Disk/IDiskProvider.cs +++ b/src/NzbDrone.Common/Disk/IDiskProvider.cs @@ -11,6 +11,7 @@ namespace NzbDrone.Common.Disk long? GetAvailableSpace(string path); void InheritFolderPermissions(string filename); void SetPermissions(string path, string mask, string user, string group); + void CopyPermissions(string sourcePath, string targetPath, bool includeOwner = false); long? GetTotalSize(string path); DateTime FolderGetCreationTime(string path); DateTime FolderGetLastWrite(string path); diff --git a/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs b/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs index 5dc5f5f13..99cbdab73 100644 --- a/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs +++ b/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using FluentAssertions; using Mono.Unix; +using Mono.Unix.Native; using Moq; using NUnit.Framework; using NzbDrone.Common.Disk; @@ -127,5 +128,34 @@ namespace NzbDrone.Mono.Test.DiskProviderTests mount.Should().NotBeNull(); mount.RootDirectory.Should().Be(rootDir); } + + [Test] + public void should_copy_folder_permissions() + { + var src = GetTempFilePath(); + var dst = GetTempFilePath(); + + Directory.CreateDirectory(src); + + // Toggle one of the permission flags + Syscall.stat(src, out var origStat); + Syscall.chmod(src, origStat.st_mode ^ FilePermissions.S_IWGRP); + + // Verify test setup + Syscall.stat(src, out var srcStat); + srcStat.st_mode.Should().NotBe(origStat.st_mode); + + Subject.CreateFolder(dst); + + // Verify test setup + Syscall.stat(dst, out var dstStat); + dstStat.st_mode.Should().Be(origStat.st_mode); + + Subject.CopyPermissions(src, dst, false); + + // Verify CopyPermissions + Syscall.stat(dst, out dstStat); + dstStat.st_mode.Should().Be(srcStat.st_mode); + } } } diff --git a/src/NzbDrone.Mono/Disk/DiskProvider.cs b/src/NzbDrone.Mono/Disk/DiskProvider.cs index 2f63b0dfa..3e0d8f782 100644 --- a/src/NzbDrone.Mono/Disk/DiskProvider.cs +++ b/src/NzbDrone.Mono/Disk/DiskProvider.cs @@ -75,6 +75,29 @@ namespace NzbDrone.Mono.Disk SetOwner(path, user, group); } + public override void CopyPermissions(string sourcePath, string targetPath, bool includeOwner) + { + try + { + Syscall.stat(sourcePath, out var srcStat); + Syscall.stat(targetPath, out var tgtStat); + + if (srcStat.st_mode != tgtStat.st_mode) + { + Syscall.chmod(targetPath, srcStat.st_mode); + } + + if (includeOwner && (srcStat.st_uid != tgtStat.st_uid || srcStat.st_gid != tgtStat.st_gid)) + { + Syscall.chown(targetPath, srcStat.st_uid, srcStat.st_gid); + } + } + catch (Exception ex) + { + Logger.Debug(ex, "Failed to copy permissions from {0} to {1}", sourcePath, targetPath); + } + } + protected override List GetAllMounts() { return _procMountProvider.GetMounts() diff --git a/src/NzbDrone.Windows/Disk/DiskProvider.cs b/src/NzbDrone.Windows/Disk/DiskProvider.cs index 83ee14c50..54cfb285f 100644 --- a/src/NzbDrone.Windows/Disk/DiskProvider.cs +++ b/src/NzbDrone.Windows/Disk/DiskProvider.cs @@ -46,7 +46,12 @@ namespace NzbDrone.Windows.Disk public override void SetPermissions(string path, string mask, string user, string group) { - + + } + + public override void CopyPermissions(string sourcePath, string targetPath, bool includeOwner) + { + } public override long? GetTotalSize(string path)