From dd046d8a684bcae3ea3a09ab8fba031cea3e2c45 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 11 Oct 2024 19:21:40 +0300 Subject: [PATCH] Fixed: (Cardigann) Validate definition file and setting fields existence Towards #2245 --- .../IndexerDefinitionUpdateService.cs | 26 +++++++++++++--- .../Cardigann/CardigannSettings.cs | 17 ++++++++++ .../Indexers/IndexerResource.cs | 31 ++++++++++++------- 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/NzbDrone.Core/IndexerVersions/IndexerDefinitionUpdateService.cs b/src/NzbDrone.Core/IndexerVersions/IndexerDefinitionUpdateService.cs index b4f58222a..bf886d02f 100644 --- a/src/NzbDrone.Core/IndexerVersions/IndexerDefinitionUpdateService.cs +++ b/src/NzbDrone.Core/IndexerVersions/IndexerDefinitionUpdateService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; +using System.Net; using NLog; using NzbDrone.Common.Cache; using NzbDrone.Common.Disk; @@ -118,7 +119,7 @@ namespace NzbDrone.Core.IndexerVersions public CardigannDefinition GetCachedDefinition(string fileKey) { - if (string.IsNullOrEmpty(fileKey)) + if (string.IsNullOrWhiteSpace(fileKey)) { throw new ArgumentNullException(nameof(fileKey)); } @@ -174,7 +175,7 @@ namespace NzbDrone.Core.IndexerVersions private CardigannDefinition GetUncachedDefinition(string fileKey) { - if (string.IsNullOrEmpty(fileKey)) + if (string.IsNullOrWhiteSpace(fileKey)) { throw new ArgumentNullException(nameof(fileKey)); } @@ -222,9 +223,24 @@ namespace NzbDrone.Core.IndexerVersions private CardigannDefinition GetHttpDefinition(string id) { - var request = new HttpRequest($"https://indexers.prowlarr.com/{DEFINITION_BRANCH}/{DEFINITION_VERSION}/{id}"); - var response = _httpClient.Get(request); - var definition = _deserializer.Deserialize(response.Content); + if (string.IsNullOrWhiteSpace(id)) + { + throw new ArgumentNullException(nameof(id)); + } + + CardigannDefinition definition; + + try + { + var request = new HttpRequest($"https://indexers.prowlarr.com/{DEFINITION_BRANCH}/{DEFINITION_VERSION}/{id}"); + var response = _httpClient.Get(request); + + definition = _deserializer.Deserialize(response.Content); + } + catch (HttpException ex) when (ex.Response.StatusCode == HttpStatusCode.NotFound) + { + throw new Exception($"Indexer definition for '{id}' does not exist.", ex); + } return CleanIndexerDefinition(definition); } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannSettings.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannSettings.cs index 0e6912ad2..51d352649 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannSettings.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannSettings.cs @@ -1,11 +1,23 @@ using System.Collections.Generic; +using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Indexers.Settings; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers.Definitions.Cardigann { + public class CardigannSettingsValidator : NoAuthSettingsValidator + { + public CardigannSettingsValidator() + { + RuleFor(c => c.DefinitionFile).NotEmpty(); + } + } + public class CardigannSettings : NoAuthTorrentBaseSettings { + private static readonly CardigannSettingsValidator Validator = new (); + public CardigannSettings() { ExtraFieldData = new Dictionary(); @@ -15,5 +27,10 @@ namespace NzbDrone.Core.Indexers.Definitions.Cardigann public string DefinitionFile { get; set; } public Dictionary ExtraFieldData { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } } diff --git a/src/Prowlarr.Api.V1/Indexers/IndexerResource.cs b/src/Prowlarr.Api.V1/Indexers/IndexerResource.cs index 3dc9a2979..57ce76f3a 100644 --- a/src/Prowlarr.Api.V1/Indexers/IndexerResource.cs +++ b/src/Prowlarr.Api.V1/Indexers/IndexerResource.cs @@ -119,20 +119,29 @@ namespace Prowlarr.Api.V1.Indexers var settings = (CardigannSettings)definition.Settings; - var cardigannDefinition = _definitionService.GetCachedDefinition(settings.DefinitionFile); - - foreach (var field in resource.Fields) + if (settings.DefinitionFile.IsNotNullOrWhiteSpace()) { - if (!standardFields.Contains(field.Name)) + var cardigannDefinition = _definitionService.GetCachedDefinition(settings.DefinitionFile); + + foreach (var field in resource.Fields) { - if (field.Name == "cardigannCaptcha") - { - settings.ExtraFieldData["CAPTCHA"] = field.Value?.ToString() ?? string.Empty; - } - else + if (!standardFields.Contains(field.Name)) { - var cardigannSetting = cardigannDefinition.Settings.FirstOrDefault(x => x.Name == field.Name); - settings.ExtraFieldData[field.Name] = MapValue(cardigannSetting, field.Value); + if (field.Name == "cardigannCaptcha") + { + settings.ExtraFieldData["CAPTCHA"] = field.Value?.ToString() ?? string.Empty; + } + else + { + var cardigannSetting = cardigannDefinition.Settings.FirstOrDefault(x => x.Name == field.Name); + + if (cardigannSetting == null) + { + throw new ArgumentOutOfRangeException(field.Name, "Unknown Cardigann setting."); + } + + settings.ExtraFieldData[field.Name] = MapValue(cardigannSetting, field.Value); + } } } }