From fd4fb88ce1efa8f673c74f04cd632a3f607565c4 Mon Sep 17 00:00:00 2001 From: Qstick Date: Mon, 7 Dec 2020 22:39:52 -0500 Subject: [PATCH] New: Add Validations for Recycle Bin Folder [common] --- .../Config/MediaManagementConfigModule.cs | 20 ++++++++- src/NzbDrone.Api/Movies/MovieModule.cs | 2 + .../RootFolders/RootFolderModule.cs | 2 + src/NzbDrone.Core/Movies/AddMovieValidator.cs | 8 ++-- .../Validation/Paths/MoviePathValidation.cs | 2 +- .../Validation/Paths/RecycleBinValidator.cs | 44 +++++++++++++++++++ .../Paths/RootFolderAncestorValidator.cs | 28 ++++++++++++ .../Config/MediaManagementConfigModule.cs | 22 +++++++++- src/Radarr.Api.V3/Movies/MovieModule.cs | 2 + .../RootFolders/RootFolderModule.cs | 2 + 10 files changed, 124 insertions(+), 8 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.Api/Config/MediaManagementConfigModule.cs b/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs index 43fb409632..8441f8f5c4 100644 --- a/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs +++ b/src/NzbDrone.Api/Config/MediaManagementConfigModule.cs @@ -8,11 +8,27 @@ namespace NzbDrone.Api.Config { public class MediaManagementConfigModule : NzbDroneConfigModule { - public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator, FolderChmodValidator folderChmodValidator) + public MediaManagementConfigModule(IConfigService configService, + PathExistsValidator pathExistsValidator, + FolderChmodValidator folderChmodValidator, + FolderWritableValidator folderWritableValidator, + MoviePathValidator moviePathValidator, + StartupFolderValidator startupFolderValidator, + SystemFolderValidator systemFolderValidator, + RootFolderAncestorValidator rootFolderAncestorValidator, + RootFolderValidator rootFolderValidator) : base(configService) { SharedValidator.RuleFor(c => c.ChmodFolder).SetValidator(folderChmodValidator).When(c => !string.IsNullOrEmpty(c.ChmodFolder) && PlatformInfo.IsMono); - SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath().SetValidator(pathExistsValidator).When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); + SharedValidator.RuleFor(c => c.RecycleBin).IsValidPath() + .SetValidator(folderWritableValidator) + .SetValidator(rootFolderValidator) + .SetValidator(pathExistsValidator) + .SetValidator(moviePathValidator) + .SetValidator(rootFolderAncestorValidator) + .SetValidator(startupFolderValidator) + .SetValidator(systemFolderValidator) + .When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); } protected override MediaManagementConfigResource ToResource(IConfigService model) diff --git a/src/NzbDrone.Api/Movies/MovieModule.cs b/src/NzbDrone.Api/Movies/MovieModule.cs index 319174b805..c9efffaa2e 100644 --- a/src/NzbDrone.Api/Movies/MovieModule.cs +++ b/src/NzbDrone.Api/Movies/MovieModule.cs @@ -37,6 +37,7 @@ public MovieModule(IBroadcastSignalRMessage signalRBroadcaster, IAddMovieService addMovieService, IMapCoversToLocal coverMapper, RootFolderValidator rootFolderValidator, + RecycleBinValidator recycleBinValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator, MoviePathValidator moviesPathValidator, MovieExistsValidator moviesExistsValidator, @@ -66,6 +67,7 @@ public MovieModule(IBroadcastSignalRMessage signalRBroadcaster, .SetValidator(mappedNetworkDriveValidator) .SetValidator(moviesPathValidator) .SetValidator(moviesAncestorValidator) + .SetValidator(recycleBinValidator) .SetValidator(systemFolderValidator) .When(s => !s.Path.IsNullOrWhiteSpace()); diff --git a/src/NzbDrone.Api/RootFolders/RootFolderModule.cs b/src/NzbDrone.Api/RootFolders/RootFolderModule.cs index c392af27a2..7984c2dc68 100644 --- a/src/NzbDrone.Api/RootFolders/RootFolderModule.cs +++ b/src/NzbDrone.Api/RootFolders/RootFolderModule.cs @@ -16,6 +16,7 @@ public RootFolderModule(IRootFolderService rootFolderService, RootFolderValidator rootFolderValidator, PathExistsValidator pathExistsValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator, + RecycleBinValidator recycleBinValidator, StartupFolderValidator startupFolderValidator, SystemFolderValidator systemFolderValidator, FolderWritableValidator folderWritableValidator) @@ -34,6 +35,7 @@ public RootFolderModule(IRootFolderService rootFolderService, .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) .SetValidator(startupFolderValidator) + .SetValidator(recycleBinValidator) .SetValidator(pathExistsValidator) .SetValidator(systemFolderValidator) .SetValidator(folderWritableValidator); diff --git a/src/NzbDrone.Core/Movies/AddMovieValidator.cs b/src/NzbDrone.Core/Movies/AddMovieValidator.cs index a143a74463..57da73e8d3 100644 --- a/src/NzbDrone.Core/Movies/AddMovieValidator.cs +++ b/src/NzbDrone.Core/Movies/AddMovieValidator.cs @@ -12,13 +12,15 @@ public interface IAddMovieValidator public class AddMovieValidator : AbstractValidator, IAddMovieValidator { public AddMovieValidator(RootFolderValidator rootFolderValidator, - MoviePathValidator moviePathValidator, - MovieAncestorValidator movieAncestorValidator, - MovieTitleSlugValidator movieTitleSlugValidator) + RecycleBinValidator recycleBinValidator, + MoviePathValidator moviePathValidator, + MovieAncestorValidator movieAncestorValidator, + MovieTitleSlugValidator movieTitleSlugValidator) { RuleFor(c => c.Path).Cascade(CascadeMode.StopOnFirstFailure) .IsValidPath() .SetValidator(rootFolderValidator) + .SetValidator(recycleBinValidator) .SetValidator(moviePathValidator) .SetValidator(movieAncestorValidator); diff --git a/src/NzbDrone.Core/Validation/Paths/MoviePathValidation.cs b/src/NzbDrone.Core/Validation/Paths/MoviePathValidation.cs index 0e24f1bf74..e613c8127e 100644 --- a/src/NzbDrone.Core/Validation/Paths/MoviePathValidation.cs +++ b/src/NzbDrone.Core/Validation/Paths/MoviePathValidation.cs @@ -10,7 +10,7 @@ public class MoviePathValidator : PropertyValidator private readonly IMovieService _moviesService; public MoviePathValidator(IMovieService moviesService) - : base("Path is already configured for another movie: {moviePath}") + : base("Path is already configured for an existing movie: {moviePath}") { _moviesService = moviesService; } diff --git a/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs b/src/NzbDrone.Core/Validation/Paths/RecycleBinValidator.cs new file mode 100644 index 0000000000..a8a714fe6a --- /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 0000000000..19f0800b50 --- /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/Radarr.Api.V3/Config/MediaManagementConfigModule.cs b/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs index fffedc5151..cad1aea7b7 100644 --- a/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs +++ b/src/Radarr.Api.V3/Config/MediaManagementConfigModule.cs @@ -8,12 +8,30 @@ namespace Radarr.Api.V3.Config { public class MediaManagementConfigModule : RadarrConfigModule { - public MediaManagementConfigModule(IConfigService configService, PathExistsValidator pathExistsValidator, FolderChmodValidator folderChmodValidator) + public MediaManagementConfigModule(IConfigService configService, + PathExistsValidator pathExistsValidator, + FolderChmodValidator folderChmodValidator, + FolderWritableValidator folderWritableValidator, + MoviePathValidator moviePathValidator, + StartupFolderValidator startupFolderValidator, + SystemFolderValidator systemFolderValidator, + RootFolderAncestorValidator rootFolderAncestorValidator, + RootFolderValidator rootFolderValidator) : base(configService) { 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.RecycleBin).IsValidPath() + .SetValidator(folderWritableValidator) + .SetValidator(rootFolderValidator) + .SetValidator(pathExistsValidator) + .SetValidator(rootFolderAncestorValidator) + .SetValidator(startupFolderValidator) + .SetValidator(systemFolderValidator) + .SetValidator(moviePathValidator) + .When(c => !string.IsNullOrWhiteSpace(c.RecycleBin)); + SharedValidator.RuleFor(c => c.MinimumFreeSpaceWhenImporting).GreaterThanOrEqualTo(100); } diff --git a/src/Radarr.Api.V3/Movies/MovieModule.cs b/src/Radarr.Api.V3/Movies/MovieModule.cs index 9c646ef1f8..23efbc8752 100644 --- a/src/Radarr.Api.V3/Movies/MovieModule.cs +++ b/src/Radarr.Api.V3/Movies/MovieModule.cs @@ -56,6 +56,7 @@ public MovieModule(IBroadcastSignalRMessage signalRBroadcaster, MoviePathValidator moviesPathValidator, MovieExistsValidator moviesExistsValidator, MovieAncestorValidator moviesAncestorValidator, + RecycleBinValidator recycleBinValidator, SystemFolderValidator systemFolderValidator, ProfileExistsValidator profileExistsValidator, MovieFolderAsRootFolderValidator movieFolderAsRootFolderValidator) @@ -84,6 +85,7 @@ public MovieModule(IBroadcastSignalRMessage signalRBroadcaster, .SetValidator(mappedNetworkDriveValidator) .SetValidator(moviesPathValidator) .SetValidator(moviesAncestorValidator) + .SetValidator(recycleBinValidator) .SetValidator(systemFolderValidator) .When(s => !s.Path.IsNullOrWhiteSpace()); diff --git a/src/Radarr.Api.V3/RootFolders/RootFolderModule.cs b/src/Radarr.Api.V3/RootFolders/RootFolderModule.cs index 950186624c..ff7c8f4ca4 100644 --- a/src/Radarr.Api.V3/RootFolders/RootFolderModule.cs +++ b/src/Radarr.Api.V3/RootFolders/RootFolderModule.cs @@ -17,6 +17,7 @@ public RootFolderModule(IRootFolderService rootFolderService, RootFolderValidator rootFolderValidator, PathExistsValidator pathExistsValidator, MappedNetworkDriveValidator mappedNetworkDriveValidator, + RecycleBinValidator recycleBinValidator, StartupFolderValidator startupFolderValidator, SystemFolderValidator systemFolderValidator, FolderWritableValidator folderWritableValidator) @@ -35,6 +36,7 @@ public RootFolderModule(IRootFolderService rootFolderService, .SetValidator(rootFolderValidator) .SetValidator(mappedNetworkDriveValidator) .SetValidator(startupFolderValidator) + .SetValidator(recycleBinValidator) .SetValidator(pathExistsValidator) .SetValidator(systemFolderValidator) .SetValidator(folderWritableValidator);