[fix] Exception capture mechanism

This commit is contained in:
acite
2025-09-17 19:45:11 +08:00
parent 40c041444a
commit a228d523a2
5 changed files with 64 additions and 50 deletions

View File

@@ -10,19 +10,10 @@
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="bf317275-3039-49bb-a475-725a800a0cce" name="Changes" comment=""> <list default="true" id="bf317275-3039-49bb-a475-725a800a0cce" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Middleware/BadRequestExceptionMiddleware.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.Abyss/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Abyss.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Abyss.csproj" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/LiveController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/LiveController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Media/VideoController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/ResourceService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/ResourceService.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/TaskService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/TaskService.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Services/UserService.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Components/Static/Helpers.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Components/Static/Helpers.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Model/ResourceAttribute.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/ResourceAttribute.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Model/Task.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/Task.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Model/User.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/User.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Model/UserCreating.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Model/UserCreating.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Abyss/Program.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Program.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Abyss/Program.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Abyss/Program.cs" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
@@ -47,7 +38,14 @@
<setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/f09ccaeb94c34c2299acd3efee0facee1a400/81/137b58b4/Key.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$APPLICATION_CONFIG_DIR$/resharper-host/DecompilerCache/decompiler/f09ccaeb94c34c2299acd3efee0facee1a400/81/137b58b4/Key.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/AbyssController.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/AbyssController.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Media/LiveController.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Media/LiveController.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Middleware/BadRequestExceptionMiddleware.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Security/UserController.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="mock:///home/acite/embd/WebProjects/Abyss/Abyss/Components/Controllers/Security/UserController.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///home/acite/embd/WebProjects/Abyss/Abyss/Components/Controllers/Security/UserController.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///home/acite/embd/WebProjects/Abyss/Abyss/Components/Controllers/Security/UserController.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///home/acite/embd/WebProjects/Abyss/Abyss/Components/Controllers/Security/UserController.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///home/acite/embd/WebProjects/Abyss/Abyss/Components/Controllers/Security/UserController.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="mock:///home/acite/embd/WebProjects/Abyss/Abyss/Components/Controllers/Security/UserController.cs" root0="SKIP_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Task/TaskController.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Components/Controllers/Task/TaskController.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/AbyssService.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Components/Services/AbyssService.cs" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Abyss/Components/Services/ConfigureService.cs" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Abyss/Components/Services/ConfigureService.cs" root0="FORCE_HIGHLIGHTING" />
@@ -226,7 +224,7 @@
<workItem from="1758040123892" duration="21000" /> <workItem from="1758040123892" duration="21000" />
<workItem from="1758040188148" duration="1000" /> <workItem from="1758040188148" duration="1000" />
<workItem from="1758049713959" duration="86000" /> <workItem from="1758049713959" duration="86000" />
<workItem from="1758084310862" duration="14054000" /> <workItem from="1758084310862" duration="16767000" />
</task> </task>
<servers /> <servers />
</component> </component>

View File

@@ -1,4 +1,4 @@
using System.Diagnostics;
using Abyss.Components.Services; using Abyss.Components.Services;
using Abyss.Components.Static; using Abyss.Components.Static;
using Abyss.Components.Tools; using Abyss.Components.Tools;
@@ -15,7 +15,6 @@ using Task = System.Threading.Tasks.Task;
public class VideoController(ILogger<VideoController> logger, ResourceService rs, ConfigureService config) : BaseController public class VideoController(ILogger<VideoController> logger, ResourceService rs, ConfigureService config) : BaseController
{ {
private ILogger<VideoController> _logger = logger; private ILogger<VideoController> _logger = logger;
public readonly string VideoFolder = Path.Combine(config.MediaRoot, "Videos"); public readonly string VideoFolder = Path.Combine(config.MediaRoot, "Videos");
[HttpPost("init")] [HttpPost("init")]
@@ -78,8 +77,6 @@ public class VideoController(ILogger<VideoController> logger, ResourceService rs
[HttpPost("{klass}/bulkquery")] [HttpPost("{klass}/bulkquery")]
public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id, [FromRoute] string klass) public async Task<IActionResult> QueryBulk([FromQuery] string token, [FromBody] string[] id, [FromRoute] string klass)
{ {
List<string> result = new List<string>();
var db = id.Select(x => Helpers.SafePathCombine(VideoFolder, [klass, x, "summary.json"])).ToArray(); var db = id.Select(x => Helpers.SafePathCombine(VideoFolder, [klass, x, "summary.json"])).ToArray();
if(db.Any(x => x == null)) if(db.Any(x => x == null))
return BadRequest(); return BadRequest();

View File

@@ -0,0 +1,18 @@
namespace Abyss.Components.Controllers.Middleware;
public class BadRequestExceptionMiddleware(RequestDelegate next, ILogger<BadRequestExceptionMiddleware> logger)
{
public async System.Threading.Tasks.Task Invoke(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{
logger.LogError(ex.Message);
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync("Bad Request");
}
}
}

View File

@@ -1,4 +1,3 @@
// UserController.cs // UserController.cs
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@@ -13,53 +12,52 @@ namespace Abyss.Components.Controllers.Security;
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
[EnableRateLimiting("Fixed")] [EnableRateLimiting("Fixed")]
public class UserController(UserService user, ILogger<UserController> logger) : BaseController public class UserController(UserService userService, ILogger<UserController> logger) : BaseController
{ {
private readonly ILogger<UserController> _logger = logger; private readonly ILogger<UserController> _logger = logger;
private readonly UserService _user = user; private readonly UserService _userService = userService;
[HttpGet("{user}")] [HttpGet("{user}")]
public async Task<IActionResult> Challenge(string user) public async Task<IActionResult> Challenge(string user)
{ {
var c = await _user.Challenge(user); var c = await _userService.Challenge(user);
if(c == null) if (c == null)
return StatusCode(403, new { message = "Access forbidden" }); return StatusCode(403, new { message = "Access forbidden" });
return Ok(c); return Ok(c);
} }
[HttpPost("{user}")] [HttpPost("{user}")]
public async Task<IActionResult> Challenge(string user, [FromBody] ChallengeResponse response) public async Task<IActionResult> Challenge(string user, [FromBody] ChallengeResponse response)
{ {
var r = await _user.Verify(user, response.Response, Ip); var r = await _userService.Verify(user, response.Response, Ip);
if(r == null) if (r == null)
return StatusCode(403, new { message = "Access forbidden" }); return StatusCode(403, new { message = "Access forbidden" });
return Ok(r); return Ok(r);
} }
[HttpPost("validate")] [HttpPost("validate")]
public IActionResult Validate(string token) public IActionResult Validate(string token)
{ {
var u = _user.Validate(token, Ip); var u = _userService.Validate(token, Ip);
if (u == -1) if (u == -1)
{ {
return StatusCode(401, new { message = "Invalid" }); return StatusCode(401, new { message = "Invalid" });
} }
return Ok(u); return Ok(u);
} }
[HttpPost("destroy")] [HttpPost("destroy")]
public IActionResult Destroy(string token) public IActionResult Destroy(string token)
{ {
var u = _user.Validate(token, Ip); var u = _userService.Validate(token, Ip);
if (u == -1) if (u == -1)
{ {
return StatusCode(401, new { message = "Invalid" }); return StatusCode(401, new { message = "Invalid" });
} }
_user.Destroy(token); _userService.Destroy(token);
return Ok("Success"); return Ok("Success");
} }
@@ -67,46 +65,46 @@ public class UserController(UserService user, ILogger<UserController> logger) :
public async Task<IActionResult> Create(string user, [FromBody] UserCreating creating) public async Task<IActionResult> Create(string user, [FromBody] UserCreating creating)
{ {
// Valid token // Valid token
var r = await _user.Verify(user, creating.Response, Ip); var r = await _userService.Verify(user, creating.Response, Ip);
if(r == null) if (r == null)
return StatusCode(403, new { message = "Denied" }); return StatusCode(403, new { message = "Denied" });
// User exists ? // User exists ?
var cu = await _user.QueryUser(creating.Name); var cu = await _userService.QueryUser(creating.Name);
if(cu != null) if (cu != null)
return StatusCode(403, new { message = "Denied" }); return StatusCode(403, new { message = "Denied" });
// Valid username string // Valid username string
if(!IsAlphanumeric(creating.Name)) if (!IsAlphanumeric(creating.Name))
return StatusCode(403, new { message = "Denied" }); return StatusCode(403, new { message = "Denied" });
// Valid parent && Privilege // Valid parent && Privilege
var ou = await _user.QueryUser(_user.Validate(r, Ip)); var ou = await _userService.QueryUser(_userService.Validate(r, Ip));
if(creating.Privilege > ou?.Privilege || ou == null) if (creating.Privilege > ou?.Privilege || ou == null)
return StatusCode(403, new { message = "Denied" }); return StatusCode(403, new { message = "Denied" });
await _user.CreateUser(new User await _userService.CreateUser(new User
{ {
Username = creating.Name, Username = creating.Name,
ParentId = ou.Uuid, ParentId = ou.Uuid,
Privilege = creating.Privilege, Privilege = creating.Privilege,
PublicKey = creating.PublicKey, PublicKey = creating.PublicKey,
} ); });
_user.Destroy(r); _userService.Destroy(r);
return Ok("Success"); return Ok("Success");
} }
[HttpGet("{user}/open")] [HttpGet("{user}/open")]
public async Task<IActionResult> Open(string user, [FromQuery] string token, [FromQuery] string? bindIp = null) public async Task<IActionResult> Open(string user, [FromQuery] string token, [FromQuery] string? bindIp = null)
{ {
var caller = _user.Validate(token, Ip); var caller = _userService.Validate(token, Ip);
if (caller != 1) if (caller != 1)
{ {
return StatusCode(403, new { message = "Access forbidden" }); return StatusCode(403, new { message = "Access forbidden" });
} }
var target = await _user.QueryUser(user); var target = await _userService.QueryUser(user);
if (target == null) if (target == null)
{ {
return StatusCode(404, new { message = "User not found" }); return StatusCode(404, new { message = "User not found" });
@@ -114,12 +112,13 @@ public class UserController(UserService user, ILogger<UserController> logger) :
var ipToBind = string.IsNullOrWhiteSpace(bindIp) ? Ip : bindIp; var ipToBind = string.IsNullOrWhiteSpace(bindIp) ? Ip : bindIp;
var t = _user.CreateToken(target.Uuid, ipToBind, TimeSpan.FromHours(1)); var t = _userService.CreateToken(target.Uuid, ipToBind, TimeSpan.FromHours(1));
_logger.LogInformation("Root created 1h token for {User}, bound to {BindIp}, request from {ReqIp}", user, ipToBind, Ip); _logger.LogInformation("Root created 1h token for {User}, bound to {BindIp}, request from {ReqIp}", user,
ipToBind, Ip);
return Ok(new { token = t, user, boundIp = ipToBind }); return Ok(new { token = t, user, boundIp = ipToBind });
} }
public static bool IsAlphanumeric(string input) public static bool IsAlphanumeric(string input)
{ {
if (string.IsNullOrEmpty(input)) if (string.IsNullOrEmpty(input))

View File

@@ -1,4 +1,5 @@
using System.Threading.RateLimiting; using System.Threading.RateLimiting;
using Abyss.Components.Controllers.Middleware;
using Abyss.Components.Controllers.Task; using Abyss.Components.Controllers.Task;
using Abyss.Components.Services; using Abyss.Components.Services;
using Microsoft.AspNetCore.RateLimiting; using Microsoft.AspNetCore.RateLimiting;
@@ -41,6 +42,7 @@ public class Program
var app = builder.Build(); var app = builder.Build();
// app.UseHttpsRedirection(); // app.UseHttpsRedirection();
app.UseMiddleware<BadRequestExceptionMiddleware>();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();