From 21d9ecccd6a409fad8881fe81d75f9e5f1ddd100 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 22 Sep 2024 04:38:55 +0300 Subject: [PATCH] Fixed: Improve validation for individual album adding --- src/Lidarr.Api.V1/Albums/AlbumController.cs | 41 ++++++++++++++++--- src/Lidarr.Api.V1/Albums/AlbumResource.cs | 4 +- .../Validation/Paths/AlbumExistsValidator.cs | 29 +++++++++++++ 3 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 src/NzbDrone.Core/Validation/Paths/AlbumExistsValidator.cs diff --git a/src/Lidarr.Api.V1/Albums/AlbumController.cs b/src/Lidarr.Api.V1/Albums/AlbumController.cs index 7028e8d6d..82f8bc068 100644 --- a/src/Lidarr.Api.V1/Albums/AlbumController.cs +++ b/src/Lidarr.Api.V1/Albums/AlbumController.cs @@ -42,6 +42,14 @@ public AlbumController(IArtistService artistService, IMapCoversToLocal coverMapper, IUpgradableSpecification upgradableSpecification, IBroadcastSignalRMessage signalRBroadcaster, + RootFolderValidator rootFolderValidator, + MappedNetworkDriveValidator mappedNetworkDriveValidator, + ArtistPathValidator artistPathValidator, + ArtistAncestorValidator artistAncestorValidator, + RecycleBinValidator recycleBinValidator, + SystemFolderValidator systemFolderValidator, + AlbumExistsValidator albumExistsValidator, + RootFolderExistsValidator rootFolderExistsValidator, QualityProfileExistsValidator qualityProfileExistsValidator, MetadataProfileExistsValidator metadataProfileExistsValidator) @@ -51,11 +59,34 @@ public AlbumController(IArtistService artistService, _releaseService = releaseService; _addAlbumService = addAlbumService; - PostValidator.RuleFor(s => s.ForeignAlbumId).NotEmpty(); - PostValidator.RuleFor(s => s.Artist.QualityProfileId).SetValidator(qualityProfileExistsValidator); - PostValidator.RuleFor(s => s.Artist.MetadataProfileId).SetValidator(metadataProfileExistsValidator); - PostValidator.RuleFor(s => s.Artist.RootFolderPath).IsValidPath().When(s => s.Artist.Path.IsNullOrWhiteSpace()); - PostValidator.RuleFor(s => s.Artist.ForeignArtistId).NotEmpty(); + PostValidator.RuleFor(s => s.ForeignAlbumId).NotEmpty().SetValidator(albumExistsValidator); + PostValidator.RuleFor(s => s.Artist).NotNull(); + PostValidator.RuleFor(s => s.Artist.ForeignArtistId).NotEmpty().When(s => s.Artist != null); + + PostValidator.RuleFor(s => s.Artist.QualityProfileId).Cascade(CascadeMode.Stop) + .ValidId() + .SetValidator(qualityProfileExistsValidator) + .When(s => s.Artist != null); + + PostValidator.RuleFor(s => s.Artist.MetadataProfileId).Cascade(CascadeMode.Stop) + .ValidId() + .SetValidator(metadataProfileExistsValidator) + .When(s => s.Artist != null); + + PostValidator.RuleFor(s => s.Artist.Path).Cascade(CascadeMode.Stop) + .IsValidPath() + .SetValidator(rootFolderValidator) + .SetValidator(mappedNetworkDriveValidator) + .SetValidator(artistPathValidator) + .SetValidator(artistAncestorValidator) + .SetValidator(recycleBinValidator) + .SetValidator(systemFolderValidator) + .When(s => s.Artist != null && s.Artist.Path.IsNotNullOrWhiteSpace()); + + PostValidator.RuleFor(s => s.Artist.RootFolderPath) + .IsValidPath() + .SetValidator(rootFolderExistsValidator) + .When(s => s.Artist != null && s.Artist.Path.IsNullOrWhiteSpace()); } [HttpGet] diff --git a/src/Lidarr.Api.V1/Albums/AlbumResource.cs b/src/Lidarr.Api.V1/Albums/AlbumResource.cs index 072fb2d27..33ff026c9 100644 --- a/src/Lidarr.Api.V1/Albums/AlbumResource.cs +++ b/src/Lidarr.Api.V1/Albums/AlbumResource.cs @@ -110,8 +110,8 @@ public static Album ToModel(this AlbumResource resource) AlbumType = resource.AlbumType, Monitored = resource.Monitored, AnyReleaseOk = resource.AnyReleaseOk, - AlbumReleases = resource.Releases.ToModel(), - AddOptions = resource.AddOptions, + AlbumReleases = resource.Releases?.ToModel() ?? new List(), + AddOptions = resource.AddOptions ?? new AddAlbumOptions(), Artist = artist, ArtistMetadata = artist.Metadata.Value }; diff --git a/src/NzbDrone.Core/Validation/Paths/AlbumExistsValidator.cs b/src/NzbDrone.Core/Validation/Paths/AlbumExistsValidator.cs new file mode 100644 index 000000000..6b583cbf0 --- /dev/null +++ b/src/NzbDrone.Core/Validation/Paths/AlbumExistsValidator.cs @@ -0,0 +1,29 @@ +using FluentValidation.Validators; +using NzbDrone.Core.Music; + +namespace NzbDrone.Core.Validation.Paths +{ + public class AlbumExistsValidator : PropertyValidator + { + private readonly IAlbumService _albumService; + + public AlbumExistsValidator(IAlbumService albumService) + { + _albumService = albumService; + } + + protected override string GetDefaultMessageTemplate() => "This album has already been added."; + + protected override bool IsValid(PropertyValidatorContext context) + { + if (context.PropertyValue == null) + { + return true; + } + + var foreignAlbumId = context.PropertyValue.ToString(); + + return _albumService.FindById(foreignAlbumId) == null; + } + } +}