Some fixes from last release (#1884)

* Removed SecurityEvent middleware solution. It was out of scope originally.

* Fixed manage users still calling pending when the api is no more

* Added back the online indicator on manage users
This commit is contained in:
Joe Milazzo 2023-03-16 19:03:56 -05:00 committed by GitHub
parent 93bd7d7c19
commit d070da2834
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 1940 additions and 177 deletions

View file

@ -47,7 +47,6 @@ public sealed class DataContext : IdentityDbContext<AppUser, AppRole, int,
public DbSet<FolderPath> FolderPath { get; set; } = null!;
public DbSet<Device> Device { get; set; } = null!;
public DbSet<ServerStatistics> ServerStatistics { get; set; } = null!;
public DbSet<SecurityEvent> SecurityEvent { get; set; } = null!;
protected override void OnModelCreating(ModelBuilder builder)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,40 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace API.Data.Migrations
{
/// <inheritdoc />
public partial class RemoveSecurityEvent : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "SecurityEvent");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "SecurityEvent",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
CreatedAtUtc = table.Column<DateTime>(type: "TEXT", nullable: false),
IpAddress = table.Column<string>(type: "TEXT", nullable: true),
RequestMethod = table.Column<string>(type: "TEXT", nullable: true),
RequestPath = table.Column<string>(type: "TEXT", nullable: true),
UserAgent = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_SecurityEvent", x => x.Id);
});
}
}
}

View file

@ -944,35 +944,6 @@ namespace API.Data.Migrations
b.ToTable("ReadingListItem");
});
modelBuilder.Entity("API.Entities.SecurityEvent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("CreatedAt")
.HasColumnType("TEXT");
b.Property<DateTime>("CreatedAtUtc")
.HasColumnType("TEXT");
b.Property<string>("IpAddress")
.HasColumnType("TEXT");
b.Property<string>("RequestMethod")
.HasColumnType("TEXT");
b.Property<string>("RequestPath")
.HasColumnType("TEXT");
b.Property<string>("UserAgent")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("SecurityEvent");
});
modelBuilder.Entity("API.Entities.Series", b =>
{
b.Property<int>("Id")

View file

@ -1,27 +0,0 @@
using API.Entities;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
namespace API.Data.Repositories;
public interface ISecurityEventRepository
{
void Add(SecurityEvent securityEvent);
}
public class SecurityEventRepository : ISecurityEventRepository
{
private readonly DataContext _context;
private readonly IMapper _mapper;
public SecurityEventRepository(DataContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
public void Add(SecurityEvent securityEvent)
{
_context.SecurityEvent.Add(securityEvent);
}
}

View file

@ -25,7 +25,6 @@ public interface IUnitOfWork
ISiteThemeRepository SiteThemeRepository { get; }
IMangaFileRepository MangaFileRepository { get; }
IDeviceRepository DeviceRepository { get; }
ISecurityEventRepository SecurityEventRepository { get; }
bool Commit();
Task<bool> CommitAsync();
bool HasChanges();
@ -63,7 +62,6 @@ public class UnitOfWork : IUnitOfWork
public ISiteThemeRepository SiteThemeRepository => new SiteThemeRepository(_context, _mapper);
public IMangaFileRepository MangaFileRepository => new MangaFileRepository(_context);
public IDeviceRepository DeviceRepository => new DeviceRepository(_context, _mapper);
public ISecurityEventRepository SecurityEventRepository => new SecurityEventRepository(_context, _mapper);
/// <summary>
/// Commits changes to the DB. Completes the open transaction.

View file

@ -1,14 +0,0 @@
using System;
namespace API.Entities;
public class SecurityEvent
{
public int Id { get; set; }
public string IpAddress { get; set; }
public string RequestMethod { get; set; }
public string RequestPath { get; set; }
public string UserAgent { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime CreatedAtUtc { get; set; }
}

View file

@ -13,7 +13,6 @@ namespace API.Logging;
public static class LogLevelOptions
{
public const string LogFile = "config/logs/kavita.log";
public const string SecurityLogFile = "config/logs/security.log";
public const bool LogRollingEnabled = true;
/// <summary>
/// Controls the Logging Level of the Application
@ -59,7 +58,7 @@ public static class LogLevelOptions
.Filter.ByIncludingOnly(ShouldIncludeLogStatement);
}
private static bool ShouldIncludeLogStatement(LogEvent e)
private static bool ShouldIncludeLogStatement(LogEvent e)
{
var isRequestLoggingMiddleware = e.Properties.ContainsKey("SourceContext") &&
e.Properties["SourceContext"].ToString().Replace("\"", string.Empty) ==

View file

@ -1,62 +0,0 @@
using System;
using System.IO;
using System.Security.AccessControl;
using System.Threading.Tasks;
using API.Data;
using API.DTOs;
using API.Entities;
using API.Logging;
using API.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Core;
using ILogger = Serilog.ILogger;
namespace API.Middleware;
public class SecurityEventMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public SecurityEventMiddleware(RequestDelegate next)
{
_next = next;
_logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(Path.Join(Directory.GetCurrentDirectory(), "config/logs/", "security.log"), rollingInterval: RollingInterval.Day)
.CreateLogger();
}
public async Task InvokeAsync(HttpContext context)
{
var ipAddress = context.Connection.RemoteIpAddress?.ToString();
var requestMethod = context.Request.Method;
var requestPath = context.Request.Path;
var userAgent = context.Request.Headers["User-Agent"];
var securityEvent = new SecurityEvent
{
IpAddress = ipAddress,
RequestMethod = requestMethod,
RequestPath = requestPath,
UserAgent = userAgent,
CreatedAt = DateTime.Now,
CreatedAtUtc = DateTime.UtcNow,
};
using (var scope = context.RequestServices.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<DataContext>();
dbContext.Add(securityEvent);
await dbContext.SaveChangesAsync();
_logger.Debug("Request Processed: {@SecurityEvent}", securityEvent);
}
await _next(context);
}
}

View file

@ -274,7 +274,6 @@ public class Startup
app.UseMiddleware<ExceptionMiddleware>();
app.UseMiddleware<SecurityEventMiddleware>();
if (env.IsDevelopment())
{