From aeee02dae4935566ca7e92ab061591a1076b7424 Mon Sep 17 00:00:00 2001 From: feos Date: Fri, 5 Jan 2024 17:15:36 +0300 Subject: [PATCH 1/6] fix #1709 --- TASVideos.Core/Settings/AppSettings.cs | 9 + TASVideos/Pages/Submissions/Submit.cshtml | 287 ++++++++++--------- TASVideos/Pages/Submissions/Submit.cshtml.cs | 29 +- TASVideos/appsettings.Production.json | 2 +- TASVideos/appsettings.json | 4 + 5 files changed, 194 insertions(+), 137 deletions(-) diff --git a/TASVideos.Core/Settings/AppSettings.cs b/TASVideos.Core/Settings/AppSettings.cs index 3c97db62e..b4b918f0c 100644 --- a/TASVideos.Core/Settings/AppSettings.cs +++ b/TASVideos.Core/Settings/AppSettings.cs @@ -11,6 +11,8 @@ public class AppSettings public Connections ConnectionStrings { get; set; } = new(); + public SubmissionRateLimit SubmissionRate { get; set; } = new (); + public IrcConnection Irc { get; set; } = new(); public DiscordConnection Discord { get; set; } = new(); @@ -24,6 +26,13 @@ public class AppSettings // Minimum number of hours before a judge can set a submission to accepted/rejected public int MinimumHoursBeforeJudgment { get; set; } + // User is only allowed to submit X submissions in Y days + public class SubmissionRateLimit + { + public int Submissions { get; set; } + public int Days { get; set; } + } + public class IrcConnection : DistributorConnection { public string Server { get; set; } = ""; diff --git a/TASVideos/Pages/Submissions/Submit.cshtml b/TASVideos/Pages/Submissions/Submit.cshtml index ca99e4f17..62b1c77bf 100644 --- a/TASVideos/Pages/Submissions/Submit.cshtml +++ b/TASVideos/Pages/Submissions/Submit.cshtml @@ -5,143 +5,160 @@ ViewData.SetTitle("Submit Movie"); var notSupportedError = ViewData.ModelState.Values.Any(v => v.Errors.Any(e => e.ErrorMessage.Contains("not currently supported"))); // TODO: a less brittle check var parseErrors = !notSupportedError && ViewData.ModelState.Keys.Any(e => e == "Parser"); + var submissionAllowed = Model.SubmissionAllowed(User.GetUserId()); + var notice = Model.Notice(User.GetUserId()); } - - @await Component.RenderWiki(SystemWiki.SubmitMovieHeader) - -
- - - @await Component.RenderWiki(SystemWiki.SupportedMovieTypes) - - - @await Component.RenderWiki(SystemWiki.SubmissionZipFailure) - -@Model.BackupSubmissionDeterminator -
- - -
- - -
@Html.DescriptionFor(m => m.Create.MovieFile)
- -
-
- -
- - - -
-
- - -
@Html.DescriptionFor(m => m.Create.AdditionalAuthors)
- -
-
-
- - -
- - - -
-
- - - -
-
- - - -
-
- -
- - - -
-
- - - -
-
- - - -
-
-
- -
- - - @await Component.RenderWiki(SystemWiki.SubmissionImportant) - - - - - - - + +@{ + if (!submissionAllowed) + { + + +
@notice[0]
+
@notice[1]
+
+
+ } + else + { + + @await Component.RenderWiki(SystemWiki.SubmitMovieHeader) + +
+ + + @await Component.RenderWiki(SystemWiki.SupportedMovieTypes) + + + @await Component.RenderWiki(SystemWiki.SubmissionZipFailure) + + @Model.BackupSubmissionDeterminator + + + +
+ + +
@Html.DescriptionFor(m => m.Create.MovieFile)
+ +
+
+ +
+ + + +
+
+ + +
@Html.DescriptionFor(m => m.Create.AdditionalAuthors)
+ +
+
+
+ + +
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+ + + +
+
+ + + +
+
+ + + +
+
+
+ +
+ + + @await Component.RenderWiki(SystemWiki.SubmissionImportant) + + + + + + + + +
+ +
+
-
- -
-
-
- -
-
- - -
- -
-
-
- -
-
- - -
- -
-
-
- - - Submit - -
+ +
+
+ + +
+ +
+
+
+ +
+
+ + +
+ +
+
+
+ + + Submit + + - -@section Scripts { - - - -} + + + } + } +} \ No newline at end of file diff --git a/TASVideos/Pages/Submissions/Submit.cshtml.cs b/TASVideos/Pages/Submissions/Submit.cshtml.cs index be93b4288..e36ccf05b 100644 --- a/TASVideos/Pages/Submissions/Submit.cshtml.cs +++ b/TASVideos/Pages/Submissions/Submit.cshtml.cs @@ -3,6 +3,7 @@ using TASVideos.Core.Services.ExternalMediaPublisher; using TASVideos.Core.Services.Wiki; using TASVideos.Core.Services.Youtube; +using TASVideos.Core.Settings; using TASVideos.Data; using TASVideos.Data.Entity; using TASVideos.MovieParsers; @@ -23,6 +24,8 @@ public class SubmitModel : BasePageModel private readonly IYoutubeSync _youtubeSync; private readonly IMovieFormatDeprecator _deprecator; private readonly IQueueService _queueService; + private readonly AppSettings _settings; + private DateTime _earliestTimestamp; public SubmitModel( ApplicationDbContext db, @@ -33,7 +36,8 @@ public SubmitModel( ITASVideoAgent tasVideoAgent, IYoutubeSync youtubeSync, IMovieFormatDeprecator deprecator, - IQueueService queueService) + IQueueService queueService, + AppSettings settings) { _db = db; _publisher = publisher; @@ -44,6 +48,7 @@ public SubmitModel( _youtubeSync = youtubeSync; _deprecator = deprecator; _queueService = queueService; + _settings = settings; } [BindProperty] @@ -183,4 +188,26 @@ private async Task ValidateModel() } } } + + public string[] Notice(int userId) => new string[] + { + "We limit submissions to " + + _settings.SubmissionRate.Submissions + + " in " + + _settings.SubmissionRate.Days + + " days per user. ", + "You will be able to submit again on " + + _earliestTimestamp.AddDays(_settings.SubmissionRate.Days) + }; + + public bool SubmissionAllowed(int userId) + { + _earliestTimestamp = _db.Submissions + .Where(s => s.Submitter != null && s.SubmitterId == userId) + .OrderByDescending(s => s.CreateTimestamp) + .ToList() + .ElementAt(_settings.SubmissionRate.Submissions - 1) + .CreateTimestamp; + return _earliestTimestamp < DateTime.UtcNow.AddDays(-_settings.SubmissionRate.Days); + } } diff --git a/TASVideos/appsettings.Production.json b/TASVideos/appsettings.Production.json index ce3676758..09988d50f 100644 --- a/TASVideos/appsettings.Production.json +++ b/TASVideos/appsettings.Production.json @@ -15,7 +15,7 @@ "Microsoft.AspNetCore.Identity": "Error", "Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.AutoValidateAntiforgeryTokenAuthorizationFilter": "Information" } - }, + }, "WriteTo": [ { "Name": "Console" }, { diff --git a/TASVideos/appsettings.json b/TASVideos/appsettings.json index 01c911109..cd474fe95 100644 --- a/TASVideos/appsettings.json +++ b/TASVideos/appsettings.json @@ -1,6 +1,10 @@ { "StartupStrategy": "Minimal", "EnableGzipCompression": "True", + "SubmissionRate": { + "Submissions": 3, + "Days": 7 + }, "CacheSettings": { "CacheType": "Memory", "CacheDurationInSeconds": "3600" From d4f091abeee559b787943002091316e7b536d555 Mon Sep 17 00:00:00 2001 From: feos Date: Fri, 5 Jan 2024 22:25:57 +0300 Subject: [PATCH 2/6] only pull subs from db that are newer than the cutoff decide if allowed to submit by count of those --- TASVideos/Pages/Submissions/Submit.cshtml.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/TASVideos/Pages/Submissions/Submit.cshtml.cs b/TASVideos/Pages/Submissions/Submit.cshtml.cs index e36ccf05b..441f48199 100644 --- a/TASVideos/Pages/Submissions/Submit.cshtml.cs +++ b/TASVideos/Pages/Submissions/Submit.cshtml.cs @@ -202,12 +202,9 @@ private async Task ValidateModel() public bool SubmissionAllowed(int userId) { - _earliestTimestamp = _db.Submissions - .Where(s => s.Submitter != null && s.SubmitterId == userId) - .OrderByDescending(s => s.CreateTimestamp) - .ToList() - .ElementAt(_settings.SubmissionRate.Submissions - 1) - .CreateTimestamp; - return _earliestTimestamp < DateTime.UtcNow.AddDays(-_settings.SubmissionRate.Days); + var subs = _db.Submissions.Where(s => s.Submitter != null && s.SubmitterId == userId + && s.CreateTimestamp > DateTime.UtcNow.AddDays(-_settings.SubmissionRate.Days)); + _earliestTimestamp = subs.Select(s => s.CreateTimestamp).Min(); + return subs.Count() < _settings.SubmissionRate.Submissions; } } From d7a2ee041467e62c33a855244b657eff391539ab Mon Sep 17 00:00:00 2001 From: feos Date: Fri, 5 Jan 2024 22:59:18 +0300 Subject: [PATCH 3/6] bail if the user happened to have the form opened and still pressed Submit probably needs to tell them it didn't go through? --- TASVideos/Pages/Submissions/Submit.cshtml.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TASVideos/Pages/Submissions/Submit.cshtml.cs b/TASVideos/Pages/Submissions/Submit.cshtml.cs index 441f48199..f2fad19ef 100644 --- a/TASVideos/Pages/Submissions/Submit.cshtml.cs +++ b/TASVideos/Pages/Submissions/Submit.cshtml.cs @@ -71,6 +71,11 @@ public async Task OnGet() public async Task OnPost() { + if (!SubmissionAllowed(User.GetUserId())) + { + return RedirectToPage("/Submissions/Submit"); + } + await ValidateModel(); if (!ModelState.IsValid) From da58fdf8e0c5fb8393ce36da0135f6bf2d9fd747 Mon Sep 17 00:00:00 2001 From: feos Date: Fri, 5 Jan 2024 23:06:36 +0300 Subject: [PATCH 4/6] clearer message about the bail stop hardcoding notice lines --- TASVideos/Pages/Submissions/Submit.cshtml | 6 ++++-- TASVideos/Pages/Submissions/Submit.cshtml.cs | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/TASVideos/Pages/Submissions/Submit.cshtml b/TASVideos/Pages/Submissions/Submit.cshtml index 62b1c77bf..02ee2bf3b 100644 --- a/TASVideos/Pages/Submissions/Submit.cshtml +++ b/TASVideos/Pages/Submissions/Submit.cshtml @@ -14,8 +14,10 @@ { -
@notice[0]
-
@notice[1]
+ @foreach (var n in notice) + { +
@n
+ }
} diff --git a/TASVideos/Pages/Submissions/Submit.cshtml.cs b/TASVideos/Pages/Submissions/Submit.cshtml.cs index f2fad19ef..7dd7d37b2 100644 --- a/TASVideos/Pages/Submissions/Submit.cshtml.cs +++ b/TASVideos/Pages/Submissions/Submit.cshtml.cs @@ -196,6 +196,7 @@ private async Task ValidateModel() public string[] Notice(int userId) => new string[] { + "Sorry, you can not submit at this time.", "We limit submissions to " + _settings.SubmissionRate.Submissions + " in " + From 6fe07a27890f1ff3880e45ebf4d01fd55ae66534 Mon Sep 17 00:00:00 2001 From: feos Date: Fri, 5 Jan 2024 23:40:23 +0300 Subject: [PATCH 5/6] async? --- TASVideos/Pages/Submissions/Submit.cshtml | 6 +++--- TASVideos/Pages/Submissions/Submit.cshtml.cs | 11 +++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/TASVideos/Pages/Submissions/Submit.cshtml b/TASVideos/Pages/Submissions/Submit.cshtml index 02ee2bf3b..dd2235f44 100644 --- a/TASVideos/Pages/Submissions/Submit.cshtml +++ b/TASVideos/Pages/Submissions/Submit.cshtml @@ -5,13 +5,13 @@ ViewData.SetTitle("Submit Movie"); var notSupportedError = ViewData.ModelState.Values.Any(v => v.Errors.Any(e => e.ErrorMessage.Contains("not currently supported"))); // TODO: a less brittle check var parseErrors = !notSupportedError && ViewData.ModelState.Keys.Any(e => e == "Parser"); - var submissionAllowed = Model.SubmissionAllowed(User.GetUserId()); + var submissionAllowed = await Model.SubmissionAllowed(User.GetUserId()); var notice = Model.Notice(User.GetUserId()); } @{ - if (!submissionAllowed) - { + if (!submissionAllowed) + { @foreach (var n in notice) diff --git a/TASVideos/Pages/Submissions/Submit.cshtml.cs b/TASVideos/Pages/Submissions/Submit.cshtml.cs index 7dd7d37b2..9ebb1393a 100644 --- a/TASVideos/Pages/Submissions/Submit.cshtml.cs +++ b/TASVideos/Pages/Submissions/Submit.cshtml.cs @@ -71,7 +71,7 @@ public async Task OnGet() public async Task OnPost() { - if (!SubmissionAllowed(User.GetUserId())) + if (!await SubmissionAllowed(User.GetUserId())) { return RedirectToPage("/Submissions/Submit"); } @@ -206,10 +206,13 @@ private async Task ValidateModel() _earliestTimestamp.AddDays(_settings.SubmissionRate.Days) }; - public bool SubmissionAllowed(int userId) + public async Task SubmissionAllowed(int userId) { - var subs = _db.Submissions.Where(s => s.Submitter != null && s.SubmitterId == userId - && s.CreateTimestamp > DateTime.UtcNow.AddDays(-_settings.SubmissionRate.Days)); + var subs = await _db.Submissions + .Where(s => s.Submitter != null + && s.SubmitterId == userId + && s.CreateTimestamp > DateTime.UtcNow.AddDays(-_settings.SubmissionRate.Days)) + .ToListAsync(); _earliestTimestamp = subs.Select(s => s.CreateTimestamp).Min(); return subs.Count() < _settings.SubmissionRate.Submissions; } From de34ffdf15363c5700a73a343e8859ad50af2cc9 Mon Sep 17 00:00:00 2001 From: feos Date: Fri, 5 Jan 2024 23:45:47 +0300 Subject: [PATCH 6/6] prod settings --- TASVideos/appsettings.Production.json | 4 ++++ TASVideos/appsettings.json | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/TASVideos/appsettings.Production.json b/TASVideos/appsettings.Production.json index 09988d50f..036014fa7 100644 --- a/TASVideos/appsettings.Production.json +++ b/TASVideos/appsettings.Production.json @@ -2,6 +2,10 @@ "BaseUrl": "https://tasvideos.org", "EnableGzipCompression": "False", "MinimumHoursBeforeJudgment": 72, + "SubmissionRate": { + "Submissions": 3, + "Days": 7 + }, "StartupStrategy": "Minimal", "CacheSettings": { "CacheType": "Redis", diff --git a/TASVideos/appsettings.json b/TASVideos/appsettings.json index cd474fe95..1375b094b 100644 --- a/TASVideos/appsettings.json +++ b/TASVideos/appsettings.json @@ -1,13 +1,13 @@ { "StartupStrategy": "Minimal", "EnableGzipCompression": "True", - "SubmissionRate": { - "Submissions": 3, - "Days": 7 - }, "CacheSettings": { "CacheType": "Memory", "CacheDurationInSeconds": "3600" - }, - "MinimumHoursBeforeJudgment": 0 + }, + "MinimumHoursBeforeJudgment": 0, + "SubmissionRate": { + "Submissions": 3, + "Days": 7 + } }