From 26bea141374cdcce091c320e700bc8e569c3c2be Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 23 Feb 2023 07:01:36 +0200 Subject: [PATCH] Fixed: (GreatPosterWall) Use cookies for 2FA Co-authored-by: ilike2burnthing <59480337+ilike2burnthing@users.noreply.github.com> --- .../Definitions/Gazelle/GazelleBase.cs | 16 ++++++++++ .../Definitions/Gazelle/GazelleSettings.cs | 5 +-- .../GazelleUserPassOrCookieSettings.cs | 31 +++++++++++++++++++ .../Indexers/Definitions/GreatPosterWall.cs | 10 +++++- .../Settings/CookieTorrentBaseSettings.cs | 22 ++++--------- .../Settings/NoAuthTorrentBaseSettings.cs | 8 ++--- .../Settings/UserPassTorrentBaseSettings.cs | 17 ++-------- 7 files changed, 72 insertions(+), 37 deletions(-) create mode 100644 src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleUserPassOrCookieSettings.cs diff --git a/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleBase.cs b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleBase.cs index 6d81b33ac..67dee072f 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleBase.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleBase.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading.Tasks; @@ -106,8 +107,23 @@ public abstract class GazelleBase : TorrentIndexerBase return response; } + protected override IDictionary GetCookies() + { + if (Settings is GazelleUserPassOrCookieSettings cookieSettings && !string.IsNullOrWhiteSpace(cookieSettings.Cookie)) + { + return CookieUtil.CookieHeaderToDictionary(cookieSettings.Cookie); + } + + return base.GetCookies(); + } + protected override bool CheckIfLoginNeeded(HttpResponse response) { + if (Settings is GazelleUserPassOrCookieSettings cookieSettings && !string.IsNullOrWhiteSpace(cookieSettings.Cookie)) + { + return false; + } + var invalidResponses = new[] { "\"bad credentials\"", "\"groupName\":\"wrong-creds\"" }; return response.HasHttpRedirect || (response.Content != null && invalidResponses.Any(response.Content.Contains)); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleSettings.cs b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleSettings.cs index b5d652f1c..64a394a77 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleSettings.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleSettings.cs @@ -4,13 +4,14 @@ using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers.Definitions.Gazelle; -public class GazelleSettingsValidator : UserPassBaseSettingsValidator +public class GazelleSettingsValidator : UserPassBaseSettingsValidator + where T : GazelleSettings { } public class GazelleSettings : UserPassTorrentBaseSettings { - private static readonly GazelleSettingsValidator Validator = new (); + private static readonly GazelleSettingsValidator Validator = new (); public string AuthKey { get; set; } public string PassKey { get; set; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleUserPassOrCookieSettings.cs b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleUserPassOrCookieSettings.cs new file mode 100644 index 000000000..9413d897d --- /dev/null +++ b/src/NzbDrone.Core/Indexers/Definitions/Gazelle/GazelleUserPassOrCookieSettings.cs @@ -0,0 +1,31 @@ +using FluentValidation; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Annotations; +using NzbDrone.Core.Indexers.Settings; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.Indexers.Definitions.Gazelle; + +public class GazelleUserPassOrCookieValidator : NoAuthSettingsValidator + where T : GazelleUserPassOrCookieSettings +{ + public GazelleUserPassOrCookieValidator() + { + RuleFor(c => c.Username).NotEmpty().When(c => c.Cookie.IsNullOrWhiteSpace()); + RuleFor(c => c.Password).NotEmpty().When(c => c.Cookie.IsNullOrWhiteSpace()); + RuleFor(c => c.Cookie).NotEmpty().When(c => c.Username.IsNullOrWhiteSpace() && c.Password.IsNullOrWhiteSpace()); + } +} + +public class GazelleUserPassOrCookieSettings : GazelleSettings +{ + private static readonly GazelleUserPassOrCookieValidator Validator = new (); + + [FieldDefinition(4, Label = "Cookie", HelpText = "Use the Cookie field only if 2FA is enabled for your account, leave it empty otherwise.", Privacy = PrivacyLevel.Password)] + public string Cookie { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } +} diff --git a/src/NzbDrone.Core/Indexers/Definitions/GreatPosterWall.cs b/src/NzbDrone.Core/Indexers/Definitions/GreatPosterWall.cs index 604a4fc30..5112ee634 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/GreatPosterWall.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/GreatPosterWall.cs @@ -15,6 +15,7 @@ using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers.Definitions; @@ -237,10 +238,17 @@ public class GreatPosterWallParser : GazelleParser } } -public class GreatPosterWallSettings : GazelleSettings +public class GreatPosterWallSettings : GazelleUserPassOrCookieSettings { + private static readonly GazelleUserPassOrCookieValidator Validator = new (); + [FieldDefinition(6, Label = "Freeleech Only", Type = FieldType.Checkbox, HelpText = "Search freeleech torrents only")] public bool FreeleechOnly { get; set; } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } } public class GreatPosterWallResponse diff --git a/src/NzbDrone.Core/Indexers/Settings/CookieTorrentBaseSettings.cs b/src/NzbDrone.Core/Indexers/Settings/CookieTorrentBaseSettings.cs index a4970a17e..c261a305f 100644 --- a/src/NzbDrone.Core/Indexers/Settings/CookieTorrentBaseSettings.cs +++ b/src/NzbDrone.Core/Indexers/Settings/CookieTorrentBaseSettings.cs @@ -4,38 +4,28 @@ using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers.Settings { - public class CookieBaseSettingsValidator : AbstractValidator + public class CookieBaseSettingsValidator : NoAuthSettingsValidator + where T : CookieTorrentBaseSettings { public CookieBaseSettingsValidator() { RuleFor(c => c.Cookie).NotEmpty(); - RuleFor(x => x.BaseSettings).SetValidator(new IndexerCommonSettingsValidator()); - RuleFor(x => x.TorrentBaseSettings).SetValidator(new IndexerTorrentSettingsValidator()); } } - public class CookieTorrentBaseSettings : ITorrentIndexerSettings + public class CookieTorrentBaseSettings : NoAuthTorrentBaseSettings { - private static readonly CookieBaseSettingsValidator Validator = new (); + private static readonly CookieBaseSettingsValidator Validator = new (); public CookieTorrentBaseSettings() { Cookie = ""; } - [FieldDefinition(1, Label = "Base Url", HelpText = "Select which baseurl Prowlarr will use for requests to the site", Type = FieldType.Select, SelectOptionsProviderAction = "getUrls")] - public string BaseUrl { get; set; } - - [FieldDefinition(2, Label = "Cookie", HelpText = "Site Cookie", Privacy = PrivacyLevel.Password, Type = FieldType.Password)] + [FieldDefinition(2, Label = "Cookie", HelpText = "Site Cookie", Privacy = PrivacyLevel.Password)] public string Cookie { get; set; } - [FieldDefinition(10)] - public IndexerBaseSettings BaseSettings { get; set; } = new (); - - [FieldDefinition(11)] - public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new (); - - public virtual NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); } diff --git a/src/NzbDrone.Core/Indexers/Settings/NoAuthTorrentBaseSettings.cs b/src/NzbDrone.Core/Indexers/Settings/NoAuthTorrentBaseSettings.cs index 14eefa481..5c9a8bea9 100644 --- a/src/NzbDrone.Core/Indexers/Settings/NoAuthTorrentBaseSettings.cs +++ b/src/NzbDrone.Core/Indexers/Settings/NoAuthTorrentBaseSettings.cs @@ -9,8 +9,8 @@ namespace NzbDrone.Core.Indexers.Settings { public NoAuthSettingsValidator() { - RuleFor(x => x.BaseSettings).SetValidator(new IndexerCommonSettingsValidator()); - RuleFor(x => x.TorrentBaseSettings).SetValidator(new IndexerTorrentSettingsValidator()); + RuleFor(c => c.BaseSettings).SetValidator(new IndexerCommonSettingsValidator()); + RuleFor(c => c.TorrentBaseSettings).SetValidator(new IndexerTorrentSettingsValidator()); } } @@ -21,10 +21,10 @@ namespace NzbDrone.Core.Indexers.Settings [FieldDefinition(1, Label = "Base Url", Type = FieldType.Select, SelectOptionsProviderAction = "getUrls", HelpText = "Select which baseurl Prowlarr will use for requests to the site")] public string BaseUrl { get; set; } - [FieldDefinition(10)] + [FieldDefinition(20)] public IndexerBaseSettings BaseSettings { get; set; } = new (); - [FieldDefinition(11)] + [FieldDefinition(21)] public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new (); public virtual NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Indexers/Settings/UserPassTorrentBaseSettings.cs b/src/NzbDrone.Core/Indexers/Settings/UserPassTorrentBaseSettings.cs index 8992fa6f7..00a03ad8c 100644 --- a/src/NzbDrone.Core/Indexers/Settings/UserPassTorrentBaseSettings.cs +++ b/src/NzbDrone.Core/Indexers/Settings/UserPassTorrentBaseSettings.cs @@ -4,19 +4,17 @@ using NzbDrone.Core.Validation; namespace NzbDrone.Core.Indexers.Settings { - public class UserPassBaseSettingsValidator : AbstractValidator + public class UserPassBaseSettingsValidator : NoAuthSettingsValidator where T : UserPassTorrentBaseSettings { public UserPassBaseSettingsValidator() { RuleFor(c => c.Username).NotEmpty(); RuleFor(c => c.Password).NotEmpty(); - RuleFor(x => x.BaseSettings).SetValidator(new IndexerCommonSettingsValidator()); - RuleFor(x => x.TorrentBaseSettings).SetValidator(new IndexerTorrentSettingsValidator()); } } - public class UserPassTorrentBaseSettings : ITorrentIndexerSettings + public class UserPassTorrentBaseSettings : NoAuthTorrentBaseSettings { private static readonly UserPassBaseSettingsValidator Validator = new (); @@ -26,22 +24,13 @@ namespace NzbDrone.Core.Indexers.Settings Password = ""; } - [FieldDefinition(1, Label = "Base Url", HelpText = "Select which baseurl Prowlarr will use for requests to the site", Type = FieldType.Select, SelectOptionsProviderAction = "getUrls")] - public string BaseUrl { get; set; } - [FieldDefinition(2, Label = "Username", HelpText = "Site Username", Privacy = PrivacyLevel.UserName)] public string Username { get; set; } [FieldDefinition(3, Label = "Password", HelpText = "Site Password", Privacy = PrivacyLevel.Password, Type = FieldType.Password)] public string Password { get; set; } - [FieldDefinition(10)] - public IndexerBaseSettings BaseSettings { get; set; } = new (); - - [FieldDefinition(11)] - public IndexerTorrentBaseSettings TorrentBaseSettings { get; set; } = new (); - - public virtual NzbDroneValidationResult Validate() + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); }