From 7f2cfdafd1170450693568282b7c3cf7f7441d3f Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sat, 27 May 2017 23:01:13 +0100 Subject: [PATCH] Rules #865 --- src/Ombi.Core/Claims/OmbiClaims.cs | 2 + src/Ombi.Core/Engine/TvRequestEngine.cs | 20 +++++++-- .../Models/Requests/BaseRequestModel.cs | 8 +--- src/Ombi.Core/Rule/BaseRule.cs | 17 ++++++++ src/Ombi.Core/Rule/IRequestRules.cs | 9 ++++ src/Ombi.Core/Rule/IRuleEvaluator.cs | 10 +++++ src/Ombi.Core/Rule/RuleEvaluator.cs | 43 +++++++++++++++++++ src/Ombi.Core/Rule/RuleResult.cs | 12 ++++++ src/Ombi.Core/Rule/Rules/CanRequestRule.cs | 36 ++++++++++++++++ src/Ombi.DependencyInjection/IocExtensions.cs | 2 + 10 files changed, 149 insertions(+), 10 deletions(-) create mode 100644 src/Ombi.Core/Rule/BaseRule.cs create mode 100644 src/Ombi.Core/Rule/IRequestRules.cs create mode 100644 src/Ombi.Core/Rule/IRuleEvaluator.cs create mode 100644 src/Ombi.Core/Rule/RuleEvaluator.cs create mode 100644 src/Ombi.Core/Rule/RuleResult.cs create mode 100644 src/Ombi.Core/Rule/Rules/CanRequestRule.cs diff --git a/src/Ombi.Core/Claims/OmbiClaims.cs b/src/Ombi.Core/Claims/OmbiClaims.cs index 97bef2d35..7491c3bdd 100644 --- a/src/Ombi.Core/Claims/OmbiClaims.cs +++ b/src/Ombi.Core/Claims/OmbiClaims.cs @@ -32,5 +32,7 @@ namespace Ombi.Core.Claims public const string AutoApproveMovie = nameof(AutoApproveMovie); public const string AutoApproveTv = nameof(AutoApproveTv); public const string PowerUser = nameof(PowerUser); + public const string RequestTv = nameof(RequestTv); + public const string RequestMovie = nameof(RequestMovie); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index d288737d3..639e9cdd0 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -13,24 +13,27 @@ using Ombi.Store.Entities; using Ombi.Helpers; using Ombi.Notifications; using Ombi.Notifications.Models; +using Ombi.Core.Rules; namespace Ombi.Core.Engine { public class TvRequestEngine : BaseMediaEngine, ITvRequestEngine { - public TvRequestEngine(ITvMazeApi tvApi, IRequestServiceMain requestService, IPrincipal user, INotificationService notificationService, IMapper map) : base(user, requestService) + public TvRequestEngine(ITvMazeApi tvApi, IRequestServiceMain requestService, IPrincipal user, INotificationService notificationService, IMapper map, + IRuleEvaluator rule) : base(user, requestService) { TvApi = tvApi; NotificationService = notificationService; Mapper = map; + Rules = rule; } private INotificationService NotificationService { get; } private ITvMazeApi TvApi { get; } private IMapper Mapper { get; } + private IRuleEvaluator Rules { get; } public async Task RequestTvShow(SearchTvShowViewModel tv) { - var showInfo = await TvApi.ShowLookupByTheTvDbId(tv.Id); DateTime.TryParse(showInfo.premiered, out DateTime firstAir); @@ -68,7 +71,7 @@ namespace Ombi.Core.Engine ImdbId = showInfo.externals?.imdb ?? string.Empty, TvDbId = tv.Id.ToString(), ProviderId = tv.Id, - + }; model.ChildRequests.Add(childRequest); @@ -120,6 +123,15 @@ namespace Ombi.Core.Engine } + var ruleResults = Rules.StartRequestRules(model); + if (ruleResults.Any(x => !x.Success)) + { + return new RequestEngineResult() + { + ErrorMessage = ruleResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.Message)).Message, + }; + } + var existingRequest = await TvRequestService.CheckRequestAsync(model.Id); if (existingRequest != null) { @@ -146,7 +158,7 @@ namespace Ombi.Core.Engine var allRequests = await TvRequestService.GetAllAsync(); var results = allRequests.FirstOrDefault(x => x.Id == request.Id); results = Mapper.Map(request); - + var model = TvRequestService.UpdateRequest(results); return model; } diff --git a/src/Ombi.Core/Models/Requests/BaseRequestModel.cs b/src/Ombi.Core/Models/Requests/BaseRequestModel.cs index 41b044a6c..99099856f 100644 --- a/src/Ombi.Core/Models/Requests/BaseRequestModel.cs +++ b/src/Ombi.Core/Models/Requests/BaseRequestModel.cs @@ -7,11 +7,7 @@ using Ombi.Store.Entities; namespace Ombi.Core.Models.Requests { public class BaseRequestModel : Entity - { - public BaseRequestModel() - { - RequestedUsers = new List(); - } + { public int ProviderId { get; set; } public string Overview { get; set; } public string Title { get; set; } @@ -26,7 +22,7 @@ namespace Ombi.Core.Models.Requests public IssueState Issues { get; set; } public string OtherMessage { get; set; } public string AdminNote { get; set; } - public List RequestedUsers { get; set; } + public List RequestedUsers { get; set; } = new List(); public int IssueId { get; set; } public bool Denied { get; set; } public string DeniedReason { get; set; } diff --git a/src/Ombi.Core/Rule/BaseRule.cs b/src/Ombi.Core/Rule/BaseRule.cs new file mode 100644 index 000000000..21b1dafd8 --- /dev/null +++ b/src/Ombi.Core/Rule/BaseRule.cs @@ -0,0 +1,17 @@ +using Ombi.Core.Rules; + +namespace Ombi.Core.Rule +{ + public abstract class BaseRule + { + public RuleResult Success() + { + return new RuleResult { Success = true }; + } + + public RuleResult Fail(string message) + { + return new RuleResult { Message = message }; + } + } +} diff --git a/src/Ombi.Core/Rule/IRequestRules.cs b/src/Ombi.Core/Rule/IRequestRules.cs new file mode 100644 index 000000000..ba5a79116 --- /dev/null +++ b/src/Ombi.Core/Rule/IRequestRules.cs @@ -0,0 +1,9 @@ +using Ombi.Core.Models.Requests; + +namespace Ombi.Core.Rules +{ + public interface IRequestRules where T : BaseRequestModel + { + RuleResult Execute(T obj); + } +} diff --git a/src/Ombi.Core/Rule/IRuleEvaluator.cs b/src/Ombi.Core/Rule/IRuleEvaluator.cs new file mode 100644 index 000000000..a67b3ffc7 --- /dev/null +++ b/src/Ombi.Core/Rule/IRuleEvaluator.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; +using Ombi.Core.Models.Requests; + +namespace Ombi.Core.Rules +{ + public interface IRuleEvaluator + { + IEnumerable StartRequestRules(BaseRequestModel obj); + } +} \ No newline at end of file diff --git a/src/Ombi.Core/Rule/RuleEvaluator.cs b/src/Ombi.Core/Rule/RuleEvaluator.cs new file mode 100644 index 000000000..4bc9ab955 --- /dev/null +++ b/src/Ombi.Core/Rule/RuleEvaluator.cs @@ -0,0 +1,43 @@ +using Ombi.Core.Models.Requests; +using Ombi.Core.Rule; +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace Ombi.Core.Rules +{ + public class RuleEvaluator : IRuleEvaluator + { + public RuleEvaluator(IServiceProvider provider) + { + RequestRules = new List>(); + var baseType = typeof(BaseRule).FullName; + + System.Reflection.Assembly ass = typeof(RuleEvaluator).GetTypeInfo().Assembly; + + foreach (TypeInfo ti in ass.DefinedTypes) + { + if (ti?.BaseType?.FullName == baseType) + { + var type = ti.GetType(); + var item = Activator.CreateInstance(ti.GetType(), provider.GetService(type));// ti.GetType is wrong + RequestRules.Add((IRequestRules)item); + } + } + } + + private List> RequestRules { get; } + + public IEnumerable StartRequestRules(BaseRequestModel obj) + { + var results = new List(); + foreach (var rule in RequestRules) + { + var result = rule.Execute(obj); + results.Add(result); + } + + return results; + } + } +} diff --git a/src/Ombi.Core/Rule/RuleResult.cs b/src/Ombi.Core/Rule/RuleResult.cs new file mode 100644 index 000000000..b8c07bf63 --- /dev/null +++ b/src/Ombi.Core/Rule/RuleResult.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ombi.Core.Rules +{ + public class RuleResult + { + public bool Success { get; set; } + public string Message { get; set; } + } +} diff --git a/src/Ombi.Core/Rule/Rules/CanRequestRule.cs b/src/Ombi.Core/Rule/Rules/CanRequestRule.cs new file mode 100644 index 000000000..e99908c07 --- /dev/null +++ b/src/Ombi.Core/Rule/Rules/CanRequestRule.cs @@ -0,0 +1,36 @@ +using Ombi.Core.Claims; +using Ombi.Core.Models.Requests; +using Ombi.Core.Rules; +using System.Security.Principal; + +namespace Ombi.Core.Rule.Rules +{ + public class CanRequestRule : BaseRule where T : BaseRequestModel, IRequestRules + { + public CanRequestRule(IPrincipal principal) + { + User = principal; + } + + private IPrincipal User { get; } + public RuleResult Execute(T obj) + { + if (obj.Type == Store.Entities.RequestType.Movie) + { + if (User.IsInRole(OmbiClaims.RequestMovie)) + { + return Success(); + } + return Fail("You do not have permissions to Request a Movie"); + } + else + { + if (User.IsInRole(OmbiClaims.RequestTv)) + { + return Success(); + } + return Fail("You do not have permissions to Request a Movie"); + } + } + } +} diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 004ec8784..e7245b743 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -21,6 +21,7 @@ using Ombi.Schedule.Jobs; using Ombi.Settings.Settings; using Ombi.Store.Context; using Ombi.Store.Repository; +using Ombi.Core.Rules; namespace Ombi.DependencyInjection { @@ -43,6 +44,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); } public static void RegisterApi(this IServiceCollection services)