diff --git a/SS14.Admin/Helpers/BanExemptions.cs b/SS14.Admin/Helpers/BanExemptions.cs new file mode 100644 index 0000000..5629d0d --- /dev/null +++ b/SS14.Admin/Helpers/BanExemptions.cs @@ -0,0 +1,31 @@ +using Content.Server.Database; + +namespace SS14.Admin.Helpers; + +public static class BanExemptions +{ + public static (ServerBanExemptFlags Value, string DisplayName)[] GetExemptions() + { + return + [ + (ServerBanExemptFlags.Datacenter, "Datacenter"), + (ServerBanExemptFlags.IP, "Only matches IP"), + (ServerBanExemptFlags.BlacklistedRange, "Blacklisted range"), + ]; + } + + public static ServerBanExemptFlags GetExemptionFromForm(IFormCollection formCollection) + { + var flags = ServerBanExemptFlags.None; + + foreach (var (value, _) in GetExemptions()) + { + if (formCollection.TryGetValue($"exemption_{value}", out var checkValue) && checkValue == "on") + { + flags |= value; + } + } + + return flags; + } +} diff --git a/SS14.Admin/Helpers/NoteSeverityHelper.cs b/SS14.Admin/Helpers/NoteSeverityHelper.cs new file mode 100644 index 0000000..b6a1655 --- /dev/null +++ b/SS14.Admin/Helpers/NoteSeverityHelper.cs @@ -0,0 +1,15 @@ +using Content.Shared.Database; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace SS14.Admin.Helpers; + +public static class NoteSeverityHelper +{ + public static SelectListItem[] SeverityItems => + [ + new SelectListItem("None", NoteSeverity.None.ToString()), + new SelectListItem("Minor", NoteSeverity.Minor.ToString()), + new SelectListItem("Medium", NoteSeverity.Medium.ToString()), + new SelectListItem("High", NoteSeverity.High.ToString()), + ]; +} diff --git a/SS14.Admin/Pages/Bans/BanTemplates/Create.cshtml b/SS14.Admin/Pages/Bans/BanTemplates/Create.cshtml new file mode 100644 index 0000000..b43f042 --- /dev/null +++ b/SS14.Admin/Pages/Bans/BanTemplates/Create.cshtml @@ -0,0 +1,23 @@ +@page +@model SS14.Admin.Pages.Bans.BanTemplates.Create + + +@{ + ViewData["Title"] = "Create new ban template"; +} + + + +
+

@ViewData["Title"]

+ +
+ +
+ +
+ +
+
+ +
diff --git a/SS14.Admin/Pages/Bans/BanTemplates/Create.cshtml.cs b/SS14.Admin/Pages/Bans/BanTemplates/Create.cshtml.cs new file mode 100644 index 0000000..bd9f40d --- /dev/null +++ b/SS14.Admin/Pages/Bans/BanTemplates/Create.cshtml.cs @@ -0,0 +1,38 @@ +using Content.Server.Database; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace SS14.Admin.Pages.Bans.BanTemplates; + +[Authorize(Roles = "BAN")] +[ValidateAntiForgeryToken] +public class Create(PostgresServerDbContext dbContext) : PageModel +{ + [BindProperty] public string Title { get; set; } = ""; + + public void OnGet() + { + + } + + public async Task OnPostCreateAsync() + { + if (string.IsNullOrWhiteSpace(Title)) + { + TempData["StatusMessage"] = "Error: name must not be empty"; + return Page(); + } + + var template = new BanTemplate + { + Title = Title, + }; + + dbContext.BanTemplate.Add(template); + + await dbContext.SaveChangesAsync(); + + return RedirectToPage("View", new { id = template.Id }); + } +} diff --git a/SS14.Admin/Pages/Bans/BanTemplates/View.cshtml b/SS14.Admin/Pages/Bans/BanTemplates/View.cshtml new file mode 100644 index 0000000..f6624cf --- /dev/null +++ b/SS14.Admin/Pages/Bans/BanTemplates/View.cshtml @@ -0,0 +1,87 @@ +@page +@using SS14.Admin.Helpers +@model SS14.Admin.Pages.Bans.BanTemplates.View + +@{ + ViewData["Title"] = $"Ban template: {Model.Template.Title}"; +} + + + +
+

@ViewData["Title"]

+ +
+ +
+ +
+ +
+
+ +
+ +
+
+
+ +
+
+
+ + + + +
+
+
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ Settings +
+
+ + +
+
+ + +
+
+
+ +
+ Exemption flags +
+ @foreach (var (value, display) in BanExemptions.GetExemptions()) + { +
+ + +
+ } +
+
+ + +
+ + diff --git a/SS14.Admin/Pages/Bans/BanTemplates/View.cshtml.cs b/SS14.Admin/Pages/Bans/BanTemplates/View.cshtml.cs new file mode 100644 index 0000000..822bfa3 --- /dev/null +++ b/SS14.Admin/Pages/Bans/BanTemplates/View.cshtml.cs @@ -0,0 +1,88 @@ +using System.ComponentModel.DataAnnotations; +using Content.Server.Database; +using Content.Shared.Database; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.EntityFrameworkCore; +using SS14.Admin.Helpers; + +namespace SS14.Admin.Pages.Bans.BanTemplates; + +[Authorize(Roles = "BAN")] +[ValidateAntiForgeryToken] +public class View(PostgresServerDbContext dbContext) : PageModel +{ + public BanTemplate Template = default!; + + [BindProperty] public InputModel Input { get; set; } = new(); + + public sealed class InputModel + { + [Required] public string Title { get; set; } = ""; + public int LengthMinutes { get; set; } + public string? Reason { get; set; } + + [Display(Name = "Delete ban when expired")] + public bool AutoDelete { get; set; } + + [Display(Name = "Hidden from player")] public bool Hidden { get; set; } + public NoteSeverity Severity { get; set; } + } + + public async Task OnGetAsync(int id) + { + var template = await dbContext.BanTemplate.SingleOrDefaultAsync(t => t.Id == id); + if (template == null) + return NotFound(); + + Input.Hidden = template.Hidden; + Input.Severity = template.Severity; + Input.Reason = template.Reason; + Input.Title = template.Title; + Input.LengthMinutes = (int)template.Length.TotalMinutes; + Input.AutoDelete = template.AutoDelete; + + Template = template; + return Page(); + } + + public async Task OnPostEditAsync(int id) + { + if (!ModelState.IsValid) + return RedirectToPage(new { id }); + + var template = await dbContext.BanTemplate.SingleOrDefaultAsync(t => t.Id == id); + if (template == null) + return NotFound(); + + if (string.IsNullOrWhiteSpace(Input.Title)) + { + TempData["StatusMessage"] = "Error: title is empty"; + return RedirectToPage(new { id }); + } + + template.Title = Input.Title; + template.Length = TimeSpan.FromMinutes(Input.LengthMinutes); + template.Reason = Input.Reason ?? ""; + template.AutoDelete = Input.AutoDelete; + template.Hidden = Input.Hidden; + template.Severity = Input.Severity; + + var flags = ServerBanExemptFlags.None; + foreach (var (value, _) in BanExemptions.GetExemptions()) + { + if (Request.Form.TryGetValue($"exemption_{value}", out var checkValue) && checkValue == "on") + { + flags |= value; + } + } + + template.ExemptFlags = flags; + + await dbContext.SaveChangesAsync(); + + return RedirectToPage(new { id }); + } +} diff --git a/SS14.Admin/Pages/Bans/Create.cshtml b/SS14.Admin/Pages/Bans/Create.cshtml index 50f7f78..109c18d 100644 --- a/SS14.Admin/Pages/Bans/Create.cshtml +++ b/SS14.Admin/Pages/Bans/Create.cshtml @@ -1,4 +1,6 @@ @page +@using Microsoft.AspNetCore.Mvc.TagHelpers +@using SS14.Admin.Helpers @model SS14.Admin.Pages.Bans.Create @{ @@ -7,97 +9,137 @@ -
-
- -
- + +
+

@ViewData["Title"]

+ +
+ +
+ +
-
-
- -
-
-
- -
-
- - +
+ +
+
+
+ +
+
+ + +
-
-
- -
-
-
- -
-
- - +
+ +
+
+
+ +
+
+ + +
-
-
- -
-
-
- -
-
-
- - - - +
+ +
+
+
+ +
+
+
+ + + + +
-
-
- -
- +
+ +
+ +
-
- - +
+ +
+ +
+
- + diff --git a/SS14.Admin/Pages/Bans/Create.cshtml.cs b/SS14.Admin/Pages/Bans/Create.cshtml.cs index 538e67e..deef6a2 100644 --- a/SS14.Admin/Pages/Bans/Create.cshtml.cs +++ b/SS14.Admin/Pages/Bans/Create.cshtml.cs @@ -1,8 +1,10 @@ using System.ComponentModel.DataAnnotations; using Content.Server.Database; +using Content.Shared.Database; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.EntityFrameworkCore; using SS14.Admin.Helpers; namespace SS14.Admin.Pages.Bans @@ -16,6 +18,10 @@ public class Create : PageModel [BindProperty] public InputModel Input { get; set; } = new(); + public ServerBanExemptFlags ExemptFlags; + + public List Templates = []; + public Create(PostgresServerDbContext dbContext, BanHelper banHelper) { _dbContext = dbContext; @@ -31,15 +37,34 @@ public sealed class InputModel public bool UseLatestHwid { get; set; } public int LengthMinutes { get; set; } [Required] public string Reason { get; set; } = ""; + [Display(Name = "Delete ban when expired")] + public bool AutoDelete { get; set; } + + [Display(Name = "Hidden from player")] public bool Hidden { get; set; } + public NoteSeverity Severity { get; set; } + } + + public async Task OnGetAsync() + { + await LoadTemplates(); } public async Task OnPostCreateAsync() { + await LoadTemplates(); + + ExemptFlags = BanExemptions.GetExemptionFromForm(Request.Form); + var ban = new ServerBan(); var ipAddr = Input.IP; var hwid = Input.HWid; + ban.ExemptFlags = ExemptFlags; + ban.AutoDelete = Input.AutoDelete; + ban.Hidden = Input.Hidden; + ban.Severity = Input.Severity; + if (Input.UseLatestHwid || Input.UseLatestIp) { if (string.IsNullOrWhiteSpace(Input.NameOrUid)) @@ -79,5 +104,34 @@ public async Task OnPostCreateAsync() TempData["StatusMessage"] = "Ban created"; return RedirectToPage("./Index"); } + + public async Task OnPostUseTemplateAsync(int templateId) + { + await LoadTemplates(); + + var template = await _dbContext.BanTemplate.SingleOrDefaultAsync(t => t.Id == templateId); + if (template == null) + { + TempData.SetStatusError("That template does not exist!"); + return Page(); + } + + // Avoid errors causing params to not be passed through. + ModelState.Clear(); + + Input.Reason = template.Reason; + Input.LengthMinutes = (int)template.Length.TotalMinutes; + Input.Severity = template.Severity; + Input.AutoDelete = template.AutoDelete; + Input.Hidden = template.Hidden; + ExemptFlags = template.ExemptFlags; + + return Page(); + } + + private async Task LoadTemplates() + { + Templates = await _dbContext.BanTemplate.ToListAsync(); + } } } diff --git a/SS14.Admin/Pages/Shared/BanTimeButtonScript.cshtml b/SS14.Admin/Pages/Shared/BanTimeButtonScript.cshtml new file mode 100644 index 0000000..aec8f64 --- /dev/null +++ b/SS14.Admin/Pages/Shared/BanTimeButtonScript.cshtml @@ -0,0 +1,30 @@ +