From 482fe041613f01902dc1d52c4540d2a74c92eb19 Mon Sep 17 00:00:00 2001 From: Qstick Date: Wed, 23 Mar 2022 19:26:11 -0500 Subject: [PATCH] New: Add Validations for Recycle Bin Folder --- .../Books/Utilities/AddAuthorValidator.cs | 2 + .../Validation/Paths/RecycleBinValidator.cs | 44 +++++++++++++++++++ .../Paths/RootFolderAncestorValidator.cs | 28 ++++++++++++ src/Readarr.Api.V1/Author/AuthorController.cs | 2 + .../Config/MediaManagementConfigController.cs | 20 ++++++++- .../RootFolders/RootFolderController.cs | 2 + 6 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs create mode 100644 src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs diff --git a/src/NzbDrone.Core/Books/Utilities/AddAuthorValidator.cs b/src/NzbDrone.Core/Books/Utilities/AddAuthorValidator.cs index 3a87e073a..e3c548ec9 100644 --- a/src/NzbDrone.Core/Books/Utilities/AddAuthorValidator.cs +++ b/src/NzbDrone.Core/Books/Utilities/AddAuthorValidator.cs @@ -13,6 +13,7 @@ namespace NzbDrone.Core.Books public class AddAuthorValidator : AbstractValidator, IAddAuthorValidator { public AddAuthorValidator(RootFolderValidator rootFolderValidator, + RecycleBinValidator recycleBinValidator, AuthorPathValidator authorPathValidator, AuthorAncestorValidator authorAncestorValidator, QualityProfileExistsValidator qualityProfileExistsValidator, @@ -21,6 +22,7 @@ namespace NzbDrone.Core.Books RuleFor(c => c.Path).Cascade(CascadeMode.StopOnFirstFailure) .IsValidPath() .SetValidator(rootFolderValidator) + .SetValidator(recycleBinValidator) .SetValidator(authorPathValidator) .SetValidator(authorAncestorValidator); diff --git a/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs new file mode 100644 index 000000000..a8a714fe6 --- /dev/null +++ b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs @@ -0,0 +1,44 @@ +using FluentValidation.Validators; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Configuration; + +namespace NzbDrone.Core.Validation.Paths +{ + public class RecycleBinValidator : PropertyValidator + { + private readonly IConfigService _configService; + + public RecycleBinValidator(IConfigService configService) + : base("Path is {relationship} configured recycle bin folder") + { + _configService = configService; + } + + protected override bool IsValid(PropertyValidatorContext context) + { + var recycleBin = _configService.RecycleBin; + var folder = context.PropertyValue.ToString(); + + if (context.PropertyValue == null || recycleBin.IsNullOrWhiteSpace()) + { + return true; + } + + if (recycleBin.PathEquals(folder)) + { + context.MessageFormatter.AppendArgument("relationship", "set to"); + + return false; + } + + if (recycleBin.IsParentPath(folder)) + { + context.MessageFormatter.AppendArgument("relationship", "child of"); + + return false; + } + + return true; + } + } +} diff --git a/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs new file mode 100644 index 000000000..19f0800b5 --- /dev/null +++ b/src/NzbDrone.Core/Validation/Paths/RootFolderAncestorValidator.cs @@ -0,0 +1,28 @@ +using System.Linq; +using FluentValidation.Validators; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.RootFolders; + +namespace NzbDrone.Core.Validation.Paths +{ + public class RootFolderAncestorValidator : PropertyValidator + { + private readonly IRootFolderService _rootFolderService; + + public RootFolderAncestorValidator(IRootFolderService rootFolderService) + : base("Path is an ancestor of an existing root folder") + { + _rootFolderService = rootFolderService; + } + + protected override bool IsValid(PropertyValidatorContext context) + { + if (context.PropertyValue == null) + { + return true; + } + + return !_rootFolderService.All().Any(s => context.PropertyValue.ToString().IsParentPath(s.Path)); + } + } +} diff --git a/src/Readarr.Api.V1/Author/AuthorController.cs b/src/Readarr.Api.V1/Author/AuthorController.cs index 84a7cf8f0..0d859f6e0 100644 --- a/src/Readarr.Api.V1/Author/AuthorController.cs +++ b/src/Readarr.Api.V1/Author/AuthorController.cs @@ -51,6 +51,7 @@ namespace Readarr.Api.V1.Author IMapCoversToLocal coverMapper, IManageCommandQueue commandQueueManager, IRootFolderService rootFolderService, + RecycleBinValidator recycleBinValidator, RootFolderValidator rootFolderValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator, AuthorPathValidator authorPathValidator, @@ -80,6 +81,7 @@ namespace Readarr.Api.V1.Author .SetValidator(mappedNetworkDriveValidator) .SetValidator(authorPathValidator) .SetValidator(authorAncestorValidator) + .SetValidator(recycleBinValidator) .SetValidator(systemFolderValidator) .When(s => !s.Path.IsNullOrWhiteSpace()); diff --git a/src/Readarr.Api.V1/Config/MediaManagementConfigController.cs b/src/Readarr.Api.V1/Config/MediaManagementConfigController.cs index 95b4929ab..c3df96c31 100644 --- a/src/Readarr.Api.V1/Config/MediaManagementConfigController.cs +++ b/src/Readarr.Api.V1/Config/MediaManagementConfigController.cs @@ -10,12 +10,28 @@ namespace Readarr.Api.V1.Config [V1ApiController("config/mediamanagement")] public class MediaManagementConfigController : ConfigController { - public MediaManagementConfigController(IConfigService configService, PathExistsValidator pathExistsValidator, FolderChmodValidator folderChmodValidator) + public MediaManagementConfigController(IConfigService configService, + PathExistsValidator pathExistsValidator, + FolderChmodValidator folderChmodValidator, + FolderWritableValidator folderWritableValidator, + AuthorPathValidator authorPathValidator, + StartupFolderValidator startupFolderValidator, + SystemFolderValidator systemFolderValidator, + RootFolderAncestorValidator rootFolderAncestorValidator, + RootFolderValidator rootFolderValidator) : base(configService) { + SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath() + .SetValidator(folderWritableValidator) + .SetValidator(rootFolderValidator) + .SetValidator(pathExistsValidator) + .SetValidator(authorPathValidator) + .SetValidator(rootFolderAncestorValidator) + .SetValidator(startupFolderValidator) + .SetValidator(systemFolderValidator) + .When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); SharedValidator.RuleFor(c => c.RecycleBinCleanupDays).GreaterThanOrEqualTo(0); SharedValidator.RuleFor(c => c.ChmodFolder).SetValidator(folderChmodValidator).When(c => !string.IsNullOrEmpty(c.ChmodFolder) && (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/Readarr.Api.V1/RootFolders/RootFolderController.cs b/src/Readarr.Api.V1/RootFolders/RootFolderController.cs index ecf3b26c3..0974b1c26 100644 --- a/src/Readarr.Api.V1/RootFolders/RootFolderController.cs +++ b/src/Readarr.Api.V1/RootFolders/RootFolderController.cs @@ -25,6 +25,7 @@ namespace Readarr.Api.V1.RootFolders public RootFolderController(IRootFolderService rootFolderService, ICalibreProxy calibreProxy, IBroadcastSignalRMessage signalRBroadcaster, + RecycleBinValidator recycleBinValidator, RootFolderValidator rootFolderValidator, PathExistsValidator pathExistsValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator, @@ -43,6 +44,7 @@ namespace Readarr.Api.V1.RootFolders .IsValidPath() .SetValidator(mappedNetworkDriveValidator) .SetValidator(startupFolderValidator) + .SetValidator(recycleBinValidator) .SetValidator(pathExistsValidator) .SetValidator(systemFolderValidator) .SetValidator(folderWritableValidator);