Add moderation cases log page

This commit is contained in:
jvyden 2022-06-10 21:21:27 -04:00
parent b51561e943
commit 6c6a7f01f9
No known key found for this signature in database
GPG key ID: 18BCF2BE0262B278
14 changed files with 181 additions and 10 deletions

View file

@ -48,7 +48,7 @@ public class AdminReportController : ControllerBase
await this.database.SaveChangesAsync(); await this.database.SaveChangesAsync();
return this.Redirect("~/admin/reports/0"); return this.Redirect("~/modPanel/reports/0");
} }
[HttpGet("dismiss")] [HttpGet("dismiss")]

View file

@ -5,7 +5,7 @@
@{ @{
Layout = "Layouts/BaseLayout"; Layout = "Layouts/BaseLayout";
Model.Title = "Moderator Panel"; Model.Title = "Moderation Panel";
} }
@if (!this.Request.IsMobile()) @if (!this.Request.IsMobile())

View file

@ -20,6 +20,7 @@ public class ModPanelPage : BaseLayout
if (!user.IsModerator) return this.NotFound(); if (!user.IsModerator) return this.NotFound();
this.Statistics.Add(new AdminPanelStatistic("Reports", await StatisticsHelper.ReportCount(), "/modPanel/reports/0")); this.Statistics.Add(new AdminPanelStatistic("Reports", await StatisticsHelper.ReportCount(), "/modPanel/reports/0"));
this.Statistics.Add(new AdminPanelStatistic("Cases", await StatisticsHelper.CaseCount(), "/modPanel/cases/0"));
return this.Page(); return this.Page();
} }

View file

@ -1,6 +1,6 @@
@page "/modPanel/reports/{pageNumber:int}" @page "/modPanel/reports/{pageNumber:int}"
@using LBPUnion.ProjectLighthouse.Administration.Reports @using LBPUnion.ProjectLighthouse.Administration.Reports
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.ReportsPage @model LBPUnion.ProjectLighthouse.Servers.Website.Pages.Admin.ReportsPage
@{ @{
Layout = "Layouts/BaseLayout"; Layout = "Layouts/BaseLayout";

View file

@ -4,15 +4,13 @@ using LBPUnion.ProjectLighthouse.Administration.Reports;
using LBPUnion.ProjectLighthouse.Configuration; using LBPUnion.ProjectLighthouse.Configuration;
using LBPUnion.ProjectLighthouse.PlayerData.Profiles; using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts; using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
using LBPUnion.ProjectLighthouse.Types;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages; namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages.Admin;
public class ReportsPage : BaseLayout public class ReportsPage : BaseLayout
{ {
public int PageAmount; public int PageAmount;
public int PageNumber; public int PageNumber;
@ -42,7 +40,7 @@ public class ReportsPage : BaseLayout
this.PageAmount = Math.Max(1, (int)Math.Ceiling((double)this.ReportCount / ServerStatics.PageSize)); this.PageAmount = Math.Max(1, (int)Math.Ceiling((double)this.ReportCount / ServerStatics.PageSize));
if (this.PageNumber < 0 || this.PageNumber >= this.PageAmount) if (this.PageNumber < 0 || this.PageNumber >= this.PageAmount)
return this.Redirect($"/admin/reports/{Math.Clamp(this.PageNumber, 0, this.PageAmount - 1)}"); return this.Redirect($"/modPanel/reports/{Math.Clamp(this.PageNumber, 0, this.PageAmount - 1)}");
this.Reports = await this.Database.Reports.Include(r => r.ReportingPlayer) this.Reports = await this.Database.Reports.Include(r => r.ReportingPlayer)
.Where(r => r.ReportingPlayer.Username.Contains(this.SearchValue)) .Where(r => r.ReportingPlayer.Username.Contains(this.SearchValue))

View file

@ -0,0 +1,13 @@
@page "/modPanel/cases/{pageNumber:int}"
@using LBPUnion.ProjectLighthouse.Administration
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.CasePage
@{
Layout = "Layouts/BaseLayout";
Model.Title = "Cases";
}
@foreach (ModerationCase @case in Model.Cases)
{
@(await Html.PartialAsync("Partials/ModerationCasePartial", @case))
}

View file

@ -0,0 +1,36 @@
using LBPUnion.ProjectLighthouse.Administration;
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages;
public class CasePage : BaseLayout
{
public CasePage(Database database) : base(database)
{}
public List<ModerationCase> Cases = new();
public async Task<IActionResult> OnGet(int pageNumber)
{
User? user = this.Database.UserFromWebRequest(this.Request);
if (user == null) return this.NotFound();
if (!user.IsModerator) return this.NotFound();
this.Cases.Add(new ModerationCase
{
CaseId = 1,
CaseCreated = DateTime.Now,
CaseExpires = new DateTime(2023, 11, 17),
CaseCreatorId = user.UserId,
CaseCreator = user,
CaseDescription = "Being a dumbass",
CaseType = CaseType.UserBan,
AffectedId = user.UserId,
});
return this.Page();
}
}

View file

@ -0,0 +1,35 @@
@using LBPUnion.ProjectLighthouse
@using LBPUnion.ProjectLighthouse.Administration
@using LBPUnion.ProjectLighthouse.Configuration
@using LBPUnion.ProjectLighthouse.Levels
@using LBPUnion.ProjectLighthouse.PlayerData.Profiles
@model LBPUnion.ProjectLighthouse.Administration.ModerationCase
@{
Database database = new();
}
<div class="ui yellow segment">
<h2>Case #@Model.CaseId: @Model.CaseType</h2>
<p><i>Created by <strong>@Model.CaseCreator?.Username</strong></i></p>
<p><strong>Description:</strong> @Model.CaseDescription</p>
@if (Model.CaseType.AffectsLevel())
{
Slot slot = await Model.GetSlotAsync(database);
<p><strong>Affected level:</strong> <a href="/slot/@slot.SlotId">@slot.Name</a></p>
}
@if (Model.CaseType.AffectsUser())
{
User user = await Model.GetUserAsync(database);
<p><strong>Affected user:</strong> <a href="/user/@user.UserId">@user.Username</a></p>
}
@if (ServerStatics.IsDebug)
{
<p style="background-color: red; color: white">
<strong>DEBUG SHIT</strong><br>
<b>Affects level:</b> @Model.CaseType.AffectsLevel()<br>
<b>Affects user:</b> @Model.CaseType.AffectsUser()
</p>
}
</div>

View file

@ -113,6 +113,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=brun/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=brun/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=deflater/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=deflater/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=dpadrate/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=dpadrate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=dumbass/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ezoiar/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=ezoiar/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=farc/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=farc/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=FLUSHALL/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=FLUSHALL/@EntryIndexedValue">True</s:Boolean>

View file

@ -28,4 +28,36 @@ public enum CaseType
HashModeration = 14, HashModeration = 14,
IpAddressBan = 15, IpAddressBan = 15,
}
public static class CaseTypeExtensions
{
public static bool AffectsUser(this CaseType type)
{
return type switch
{
CaseType.UserSilence => true,
CaseType.UserRestriction => true,
CaseType.UserBan => true,
CaseType.UserDeletion => true,
CaseType.UserCommentsDisabled => true,
CaseType.UserDetailsEdited => true,
CaseType.UserEarthDeletion => true,
_ => false,
};
}
public static bool AffectsLevel(this CaseType type)
{
return type switch
{
CaseType.LevelDeletion => true,
CaseType.LevelLock => true,
CaseType.LevelCommentsDisabled => true,
CaseType.LevelDetailsEdited => true,
CaseType.LevelTeamPickAdded => true,
CaseType.LevelTeamPickRemoved => true,
_ => false,
};
}
} }

View file

@ -1,7 +1,11 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics;
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Levels;
using LBPUnion.ProjectLighthouse.PlayerData.Profiles; using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
using Microsoft.EntityFrameworkCore;
namespace LBPUnion.ProjectLighthouse.Administration; namespace LBPUnion.ProjectLighthouse.Administration;
#nullable enable #nullable enable
@ -23,4 +27,20 @@ public class ModerationCase
[ForeignKey(nameof(CaseCreatorId))] [ForeignKey(nameof(CaseCreatorId))]
public User? CaseCreator { get; set; } public User? CaseCreator { get; set; }
public int AffectedId { get; set; }
#region Get affected id result
public Task<User> GetUserAsync(Database database)
{
Debug.Assert(CaseType.AffectsUser());
return database.Users.FirstOrDefaultAsync(u => u.UserId == this.AffectedId)!;
}
public Task<Slot> GetSlotAsync(Database database)
{
Debug.Assert(CaseType.AffectsLevel());
return database.Slots.FirstOrDefaultAsync(u => u.SlotId == this.AffectedId)!;
}
#endregion
} }

View file

@ -13,8 +13,7 @@ public static class StatisticsHelper
public static async Task<int> RecentMatches() => await database.LastContacts.Where(l => TimeHelper.Timestamp - l.Timestamp < 300).CountAsync(); public static async Task<int> RecentMatches() => await database.LastContacts.Where(l => TimeHelper.Timestamp - l.Timestamp < 300).CountAsync();
public static async Task<int> RecentMatchesForGame public static async Task<int> RecentMatchesForGame(GameVersion gameVersion)
(GameVersion gameVersion)
=> await database.LastContacts.Where(l => TimeHelper.Timestamp - l.Timestamp < 300 && l.GameVersion == gameVersion).CountAsync(); => await database.LastContacts.Where(l => TimeHelper.Timestamp - l.Timestamp < 300 && l.GameVersion == gameVersion).CountAsync();
public static async Task<int> SlotCount() => await database.Slots.CountAsync(); public static async Task<int> SlotCount() => await database.Slots.CountAsync();
@ -24,6 +23,9 @@ public static class StatisticsHelper
public static async Task<int> TeamPickCount() => await database.Slots.CountAsync(s => s.TeamPick); public static async Task<int> TeamPickCount() => await database.Slots.CountAsync(s => s.TeamPick);
public static async Task<int> PhotoCount() => await database.Photos.CountAsync(); public static async Task<int> PhotoCount() => await database.Photos.CountAsync();
#region Moderator/Admin specific
public static async Task<int> ReportCount() => await database.Reports.CountAsync(); public static async Task<int> ReportCount() => await database.Reports.CountAsync();
public static async Task<int> CaseCount() => await database.Cases.CountAsync();
#endregion
} }

View file

@ -0,0 +1,30 @@
using LBPUnion.ProjectLighthouse;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ProjectLighthouse.Migrations
{
[DbContext(typeof(Database))]
[Migration("20220611012037_AddAffectedIdToCases")]
public class AddAffectedIdToCases : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "AffectedId",
table: "Cases",
type: "int",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AffectedId",
table: "Cases");
}
}
}

View file

@ -38,6 +38,9 @@ namespace ProjectLighthouse.Migrations
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("int"); .HasColumnType("int");
b.Property<int>("AffectedId")
.HasColumnType("int");
b.Property<DateTime>("CaseCreated") b.Property<DateTime>("CaseCreated")
.HasColumnType("datetime(6)"); .HasColumnType("datetime(6)");