diff --git a/frontend/src/Settings/MediaManagement/MediaManagement.js b/frontend/src/Settings/MediaManagement/MediaManagement.js
index 3c6209773..221cb66c0 100644
--- a/frontend/src/Settings/MediaManagement/MediaManagement.js
+++ b/frontend/src/Settings/MediaManagement/MediaManagement.js
@@ -333,7 +333,7 @@ class MediaManagement extends Component {
-
-
- Folder chmod mode
-
-
-
-
-
- chown User
-
-
-
-
-
- chown Group
-
-
-
}
diff --git a/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs b/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs
index 3251b2cac..ce316268d 100644
--- a/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs
+++ b/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs
@@ -1,16 +1,17 @@
-using FluentValidation;
+using FluentValidation;
+using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
+using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths;
namespace NzbDrone.Api.Config
{
public class MediaManagementConfigModule : NzbDroneConfigModule
{
- public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator)
+ public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator, FileChmodValidator fileChmodValidator)
: base(configService)
{
- SharedValidator.RuleFor(c => c.FileChmod).NotEmpty();
- SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty();
+ SharedValidator.RuleFor(c => c.FileChmod).SetValidator(fileChmodValidator).When(c => !string.IsNullOrEmpty(c.FileChmod) && (OsInfo.IsLinux || OsInfo.IsOsx));
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin));
}
diff --git a/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs b/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs
index c62d239ce..691b7b85b 100644
--- a/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs
+++ b/src/NzbDrone.Api/Config/MediaManagementConfigResource.cs
@@ -16,9 +16,6 @@ namespace NzbDrone.Api.Config
public bool SetPermissionsLinux { get; set; }
public string FileChmod { get; set; }
- public string FolderChmod { get; set; }
- public string ChownUser { get; set; }
- public string ChownGroup { get; set; }
public bool SkipFreeSpaceCheckWhenImporting { get; set; }
public bool CopyUsingHardlinks { get; set; }
@@ -42,9 +39,6 @@ namespace NzbDrone.Api.Config
SetPermissionsLinux = model.SetPermissionsLinux,
FileChmod = model.FileChmod,
- FolderChmod = model.FolderChmod,
- ChownUser = model.ChownUser,
- ChownGroup = model.ChownGroup,
SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting,
CopyUsingHardlinks = model.CopyUsingHardlinks,
diff --git a/src/NzbDrone.Common.Test/DiskTests/DiskTransferServiceFixture.cs b/src/NzbDrone.Common.Test/DiskTests/DiskTransferServiceFixture.cs
index df67b6bc7..511994b7d 100644
--- a/src/NzbDrone.Common.Test/DiskTests/DiskTransferServiceFixture.cs
+++ b/src/NzbDrone.Common.Test/DiskTests/DiskTransferServiceFixture.cs
@@ -1048,7 +1048,7 @@ namespace NzbDrone.Common.Test.DiskTests
.Returns(new List());
Mocker.GetMock()
- .Setup(v => v.CopyPermissions(It.IsAny(), It.IsAny(), false));
+ .Setup(v => v.CopyPermissions(It.IsAny(), It.IsAny()));
}
private void WithRealDiskProvider()
@@ -1110,7 +1110,7 @@ namespace NzbDrone.Common.Test.DiskTests
.Returns(s => new FileStream(s, FileMode.Open, FileAccess.Read));
Mocker.GetMock()
- .Setup(v => v.CopyPermissions(It.IsAny(), It.IsAny(), false));
+ .Setup(v => v.CopyPermissions(It.IsAny(), It.IsAny()));
}
private void WithMockMount(string root)
diff --git a/src/NzbDrone.Common/Disk/DiskProviderBase.cs b/src/NzbDrone.Common/Disk/DiskProviderBase.cs
index 91614647e..979075104 100644
--- a/src/NzbDrone.Common/Disk/DiskProviderBase.cs
+++ b/src/NzbDrone.Common/Disk/DiskProviderBase.cs
@@ -31,8 +31,8 @@ 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 void SetPermissions(string path, string mask);
+ public abstract void CopyPermissions(string sourcePath, string targetPath);
public abstract long? GetTotalSize(string path);
public DateTime FolderGetCreationTime(string path)
@@ -552,5 +552,10 @@ namespace NzbDrone.Common.Disk
stream.CopyTo(fileStream);
}
}
+
+ public virtual bool IsValidFilePermissionMask(string mask)
+ {
+ throw new NotSupportedException();
+ }
}
}
diff --git a/src/NzbDrone.Common/Disk/IDiskProvider.cs b/src/NzbDrone.Common/Disk/IDiskProvider.cs
index 1668e5ba7..287fd96d4 100644
--- a/src/NzbDrone.Common/Disk/IDiskProvider.cs
+++ b/src/NzbDrone.Common/Disk/IDiskProvider.cs
@@ -10,8 +10,8 @@ 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);
+ void SetPermissions(string path, string mask);
+ void CopyPermissions(string sourcePath, string targetPath);
long? GetTotalSize(string path);
DateTime FolderGetCreationTime(string path);
DateTime FolderGetLastWrite(string path);
@@ -52,5 +52,6 @@ namespace NzbDrone.Common.Disk
List GetFileInfos(string path);
void RemoveEmptySubfolders(string path);
void SaveStream(Stream stream, string path);
+ bool IsValidFilePermissionMask(string mask);
}
}
diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs
index deaa0f494..c3abfd61a 100644
--- a/src/NzbDrone.Core/Configuration/ConfigService.cs
+++ b/src/NzbDrone.Core/Configuration/ConfigService.cs
@@ -322,27 +322,6 @@ namespace NzbDrone.Core.Configuration
set { SetValue("FileChmod", value); }
}
- public string FolderChmod
- {
- get { return GetValue("FolderChmod", "0755"); }
-
- set { SetValue("FolderChmod", value); }
- }
-
- public string ChownUser
- {
- get { return GetValue("ChownUser", ""); }
-
- set { SetValue("ChownUser", value); }
- }
-
- public string ChownGroup
- {
- get { return GetValue("ChownGroup", ""); }
-
- set { SetValue("ChownGroup", value); }
- }
-
public int FirstDayOfWeek
{
get { return GetValueInt("FirstDayOfWeek", (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek); }
diff --git a/src/NzbDrone.Core/Configuration/IConfigService.cs b/src/NzbDrone.Core/Configuration/IConfigService.cs
index db1e6f502..b2bc022c2 100644
--- a/src/NzbDrone.Core/Configuration/IConfigService.cs
+++ b/src/NzbDrone.Core/Configuration/IConfigService.cs
@@ -45,9 +45,6 @@ namespace NzbDrone.Core.Configuration
//Permissions (Media Management)
bool SetPermissionsLinux { get; set; }
string FileChmod { get; set; }
- string FolderChmod { get; set; }
- string ChownUser { get; set; }
- string ChownGroup { get; set; }
//Indexers
int Retention { get; set; }
diff --git a/src/NzbDrone.Core/Datastore/Migration/175_remove_chown_and_folderchmod_config.cs b/src/NzbDrone.Core/Datastore/Migration/175_remove_chown_and_folderchmod_config.cs
new file mode 100644
index 000000000..fea3a9742
--- /dev/null
+++ b/src/NzbDrone.Core/Datastore/Migration/175_remove_chown_and_folderchmod_config.cs
@@ -0,0 +1,15 @@
+using System.Data;
+using FluentMigrator;
+using NzbDrone.Core.Datastore.Migration.Framework;
+
+namespace NzbDrone.Core.Datastore.Migration
+{
+ [Migration(175)]
+ public class remove_chown_and_folderchmod_config : NzbDroneMigrationBase
+ {
+ protected override void MainDbUpgrade()
+ {
+ Execute.Sql("DELETE FROM config WHERE Key IN ('folderchmod', 'chownuser', 'chowngroup', 'parsingleniency')");
+ }
+ }
+}
diff --git a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs
index 45a8ff51d..e9f416e79 100644
--- a/src/NzbDrone.Core/MediaFiles/DiskScanService.cs
+++ b/src/NzbDrone.Core/MediaFiles/DiskScanService.cs
@@ -192,8 +192,8 @@ namespace NzbDrone.Core.MediaFiles
try
{
- var permissions = _configService.FolderChmod;
- _diskProvider.SetPermissions(path, permissions, _configService.ChownUser, _configService.ChownGroup);
+ var permissions = _configService.FileChmod;
+ _diskProvider.SetPermissions(path, permissions);
}
catch (Exception ex)
{
diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileAttributeService.cs b/src/NzbDrone.Core/MediaFiles/MediaFileAttributeService.cs
index bf60d9be6..3750af342 100644
--- a/src/NzbDrone.Core/MediaFiles/MediaFileAttributeService.cs
+++ b/src/NzbDrone.Core/MediaFiles/MediaFileAttributeService.cs
@@ -62,7 +62,7 @@ namespace NzbDrone.Core.MediaFiles
{
if (OsInfo.IsNotWindows)
{
- SetMonoPermissions(path, _configService.FolderChmod);
+ SetMonoPermissions(path, _configService.FileChmod);
}
}
@@ -84,7 +84,7 @@ namespace NzbDrone.Core.MediaFiles
try
{
- _diskProvider.SetPermissions(path, permissions, _configService.ChownUser, _configService.ChownGroup);
+ _diskProvider.SetPermissions(path, permissions);
}
catch (Exception ex)
{
diff --git a/src/NzbDrone.Core/Update/InstallUpdateService.cs b/src/NzbDrone.Core/Update/InstallUpdateService.cs
index c0adb851c..4783f8074 100644
--- a/src/NzbDrone.Core/Update/InstallUpdateService.cs
+++ b/src/NzbDrone.Core/Update/InstallUpdateService.cs
@@ -145,7 +145,7 @@ namespace NzbDrone.Core.Update
// Set executable flag on update app
if (OsInfo.IsOsx || (OsInfo.IsLinux && PlatformInfo.IsNetCore))
{
- _diskProvider.SetPermissions(_appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime), "0755", null, null);
+ _diskProvider.SetPermissions(_appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime), "0755");
}
_logger.Info("Starting update client {0}", _appFolderInfo.GetUpdateClientExePath(updatePackage.Runtime));
diff --git a/src/NzbDrone.Core/Validation/FileChmodValidator.cs b/src/NzbDrone.Core/Validation/FileChmodValidator.cs
new file mode 100644
index 000000000..c9f0881a7
--- /dev/null
+++ b/src/NzbDrone.Core/Validation/FileChmodValidator.cs
@@ -0,0 +1,26 @@
+using FluentValidation.Validators;
+using NzbDrone.Common.Disk;
+
+namespace NzbDrone.Core.Validation
+{
+ public class FileChmodValidator : PropertyValidator
+ {
+ private readonly IDiskProvider _diskProvider;
+
+ public FileChmodValidator(IDiskProvider diskProvider)
+ : base("Must contain a valid Unix permissions octal")
+ {
+ _diskProvider = diskProvider;
+ }
+
+ protected override bool IsValid(PropertyValidatorContext context)
+ {
+ if (context.PropertyValue == null)
+ {
+ return false;
+ }
+
+ return _diskProvider.IsValidFilePermissionMask(context.PropertyValue.ToString());
+ }
+ }
+}
diff --git a/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs b/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs
index 585c19eb4..19f008757 100644
--- a/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs
+++ b/src/NzbDrone.Mono.Test/DiskProviderTests/DiskProviderFixture.cs
@@ -151,11 +151,100 @@ namespace NzbDrone.Mono.Test.DiskProviderTests
Syscall.stat(dst, out var dstStat);
dstStat.st_mode.Should().Be(origStat.st_mode);
- Subject.CopyPermissions(src, dst, false);
+ Subject.CopyPermissions(src, dst);
// Verify CopyPermissions
Syscall.stat(dst, out dstStat);
dstStat.st_mode.Should().Be(srcStat.st_mode);
}
+
+ [Test]
+ public void should_set_file_permissions()
+ {
+ var tempFile = GetTempFilePath();
+
+ File.WriteAllText(tempFile, "File1");
+ SetWritePermissions(tempFile, false);
+
+ // Verify test setup
+ Syscall.stat(tempFile, out var fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0444");
+
+ Subject.SetPermissions(tempFile, "644");
+ Syscall.stat(tempFile, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0644");
+
+ Subject.SetPermissions(tempFile, "0644");
+ Syscall.stat(tempFile, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0644");
+
+ Subject.SetPermissions(tempFile, "1664");
+ Syscall.stat(tempFile, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("1664");
+ }
+
+ [Test]
+ public void should_set_folder_permissions()
+ {
+ var tempPath = GetTempFilePath();
+
+ Directory.CreateDirectory(tempPath);
+ SetWritePermissions(tempPath, false);
+
+ // Verify test setup
+ Syscall.stat(tempPath, out var fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0555");
+
+ Subject.SetPermissions(tempPath, "644");
+ Syscall.stat(tempPath, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0755");
+
+ Subject.SetPermissions(tempPath, "0644");
+ Syscall.stat(tempPath, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0755");
+
+ Subject.SetPermissions(tempPath, "1664");
+ Syscall.stat(tempPath, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("1775");
+
+ Subject.SetPermissions(tempPath, "775");
+ Syscall.stat(tempPath, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0775");
+
+ Subject.SetPermissions(tempPath, "640");
+ Syscall.stat(tempPath, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0750");
+
+ Subject.SetPermissions(tempPath, "0041");
+ Syscall.stat(tempPath, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0051");
+
+ // reinstate sane permissions so fokder can be cleaned up
+ Subject.SetPermissions(tempPath, "775");
+ Syscall.stat(tempPath, out fileStat);
+ NativeConvert.ToOctalPermissionString(fileStat.st_mode).Should().Be("0775");
+ }
+
+ [Test]
+ public void IsValidFilePermissionMask_should_return_correct()
+ {
+ // Files may not be executable
+ Subject.IsValidFilePermissionMask("0777").Should().BeFalse();
+ Subject.IsValidFilePermissionMask("0544").Should().BeFalse();
+ Subject.IsValidFilePermissionMask("0454").Should().BeFalse();
+ Subject.IsValidFilePermissionMask("0445").Should().BeFalse();
+
+ // No special bits should be set
+ Subject.IsValidFilePermissionMask("1644").Should().BeFalse();
+ Subject.IsValidFilePermissionMask("2644").Should().BeFalse();
+ Subject.IsValidFilePermissionMask("4644").Should().BeFalse();
+ Subject.IsValidFilePermissionMask("7644").Should().BeFalse();
+
+ // Files should be readable and writeable by owner
+ Subject.IsValidFilePermissionMask("0400").Should().BeFalse();
+ Subject.IsValidFilePermissionMask("0000").Should().BeFalse();
+ Subject.IsValidFilePermissionMask("0200").Should().BeFalse();
+ Subject.IsValidFilePermissionMask("0600").Should().BeTrue();
+ }
}
}
diff --git a/src/NzbDrone.Mono/Disk/DiskProvider.cs b/src/NzbDrone.Mono/Disk/DiskProvider.cs
index 249f3e31c..76cd2f803 100644
--- a/src/NzbDrone.Mono/Disk/DiskProvider.cs
+++ b/src/NzbDrone.Mono/Disk/DiskProvider.cs
@@ -70,13 +70,62 @@ namespace NzbDrone.Mono.Disk
}
}
- public override void SetPermissions(string path, string mask, string user, string group)
+ public override void SetPermissions(string path, string mask)
{
- SetPermissions(path, mask);
- SetOwner(path, user, group);
+ _logger.Debug("Setting permissions: {0} on {1}", mask, path);
+
+ var permissions = NativeConvert.FromOctalPermissionString(mask);
+
+ if (Directory.Exists(path))
+ {
+ permissions = GetFolderPermissions(permissions);
+ }
+
+ if (Syscall.chmod(path, permissions) < 0)
+ {
+ var error = Stdlib.GetLastError();
+
+ throw new LinuxPermissionsException("Error setting permissions: " + error);
+ }
+ }
+
+ private static FilePermissions GetFolderPermissions(FilePermissions permissions)
+ {
+ permissions |= (FilePermissions)((int)(permissions & (FilePermissions.S_IRUSR | FilePermissions.S_IRGRP | FilePermissions.S_IROTH)) >> 2);
+
+ return permissions;
}
- public override void CopyPermissions(string sourcePath, string targetPath, bool includeOwner)
+ public override bool IsValidFilePermissionMask(string mask)
+ {
+ try
+ {
+ var permissions = NativeConvert.FromOctalPermissionString(mask);
+
+ if ((permissions & (FilePermissions.S_ISUID | FilePermissions.S_ISGID | FilePermissions.S_ISVTX)) != 0)
+ {
+ return false;
+ }
+
+ if ((permissions & (FilePermissions.S_IXUSR | FilePermissions.S_IXGRP | FilePermissions.S_IXOTH)) != 0)
+ {
+ return false;
+ }
+
+ if ((permissions & (FilePermissions.S_IRUSR | FilePermissions.S_IWUSR)) != (FilePermissions.S_IRUSR | FilePermissions.S_IWUSR))
+ {
+ return false;
+ }
+
+ return true;
+ }
+ catch (FormatException)
+ {
+ return false;
+ }
+ }
+
+ public override void CopyPermissions(string sourcePath, string targetPath)
{
try
{
@@ -87,11 +136,6 @@ namespace NzbDrone.Mono.Disk
{
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)
{
@@ -372,39 +416,6 @@ namespace NzbDrone.Mono.Disk
}
}
- private void SetPermissions(string path, string mask)
- {
- _logger.Debug("Setting permissions: {0} on {1}", mask, path);
-
- var filePermissions = NativeConvert.FromOctalPermissionString(mask);
-
- if (Syscall.chmod(path, filePermissions) < 0)
- {
- var error = Stdlib.GetLastError();
-
- throw new LinuxPermissionsException("Error setting file permissions: " + error);
- }
- }
-
- private void SetOwner(string path, string user, string group)
- {
- if (string.IsNullOrWhiteSpace(user) && string.IsNullOrWhiteSpace(group))
- {
- _logger.Debug("User and Group for chown not configured, skipping chown.");
- return;
- }
-
- var userId = GetUserId(user);
- var groupId = GetGroupId(group);
-
- if (Syscall.chown(path, userId, groupId) < 0)
- {
- var error = Stdlib.GetLastError();
-
- throw new LinuxPermissionsException("Error setting file owner and/or group: " + error);
- }
- }
-
private uint GetUserId(string user)
{
if (user.IsNullOrWhiteSpace())
diff --git a/src/NzbDrone.Update/UpdateEngine/InstallUpdateService.cs b/src/NzbDrone.Update/UpdateEngine/InstallUpdateService.cs
index a7f1c1b97..0de0b4e69 100644
--- a/src/NzbDrone.Update/UpdateEngine/InstallUpdateService.cs
+++ b/src/NzbDrone.Update/UpdateEngine/InstallUpdateService.cs
@@ -125,7 +125,7 @@ namespace NzbDrone.Update.UpdateEngine
// Set executable flag on app
if (OsInfo.IsOsx || (OsInfo.IsLinux && PlatformInfo.IsNetCore))
{
- _diskProvider.SetPermissions(Path.Combine(installationFolder, "Radarr"), "0755", null, null);
+ _diskProvider.SetPermissions(Path.Combine(installationFolder, "Radarr"), "0755");
}
}
catch (Exception e)
diff --git a/src/NzbDrone.Windows/Disk/DiskProvider.cs b/src/NzbDrone.Windows/Disk/DiskProvider.cs
index e23190055..b2025a1f2 100644
--- a/src/NzbDrone.Windows/Disk/DiskProvider.cs
+++ b/src/NzbDrone.Windows/Disk/DiskProvider.cs
@@ -47,11 +47,11 @@ namespace NzbDrone.Windows.Disk
file.SetAccessControl(fs);
}
- public override void SetPermissions(string path, string mask, string user, string group)
+ public override void SetPermissions(string path, string mask)
{
}
- public override void CopyPermissions(string sourcePath, string targetPath, bool includeOwner)
+ public override void CopyPermissions(string sourcePath, string targetPath)
{
}
diff --git a/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs b/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs
index 70ded1d38..6a37a760e 100644
--- a/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs
+++ b/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs
@@ -1,17 +1,18 @@
using FluentValidation;
+using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Configuration;
+using NzbDrone.Core.Validation;
using NzbDrone.Core.Validation.Paths;
namespace Radarr.Api.V3.Config
{
public class MediaManagementConfigModule : RadarrConfigModule
{
- public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator)
+ public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator, FileChmodValidator fileChmodValidator)
: base(configService)
{
SharedValidator.RuleFor(c => c.RecycleBinCleanupDays).GreaterThanOrEqualTo(0);
- SharedValidator.RuleFor(c => c.FileChmod).NotEmpty();
- SharedValidator.RuleFor(c => c.FolderChmod).NotEmpty();
+ SharedValidator.RuleFor(c => c.FileChmod).SetValidator(fileChmodValidator).When(c => !string.IsNullOrEmpty(c.FileChmod) && (OsInfo.IsLinux || OsInfo.IsOsx));
SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin));
SharedValidator.RuleFor(c => c.MinimumFreeSpaceWhenImporting).GreaterThanOrEqualTo(100);
}
diff --git a/src/Radarr.Api.V3/Config/MediaManagementConfigResource.cs b/src/Radarr.Api.V3/Config/MediaManagementConfigResource.cs
index b25746e0b..549d077bc 100644
--- a/src/Radarr.Api.V3/Config/MediaManagementConfigResource.cs
+++ b/src/Radarr.Api.V3/Config/MediaManagementConfigResource.cs
@@ -19,9 +19,6 @@ namespace Radarr.Api.V3.Config
public bool SetPermissionsLinux { get; set; }
public string FileChmod { get; set; }
- public string FolderChmod { get; set; }
- public string ChownUser { get; set; }
- public string ChownGroup { get; set; }
public bool SkipFreeSpaceCheckWhenImporting { get; set; }
public int MinimumFreeSpaceWhenImporting { get; set; }
@@ -49,9 +46,6 @@ namespace Radarr.Api.V3.Config
SetPermissionsLinux = model.SetPermissionsLinux,
FileChmod = model.FileChmod,
- FolderChmod = model.FolderChmod,
- ChownUser = model.ChownUser,
- ChownGroup = model.ChownGroup,
SkipFreeSpaceCheckWhenImporting = model.SkipFreeSpaceCheckWhenImporting,
MinimumFreeSpaceWhenImporting = model.MinimumFreeSpaceWhenImporting,