feat(backend): improve bad request errors

This commit is contained in:
sam 2024-07-14 16:44:41 +02:00
parent e7ec0e6661
commit fb34464199
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
6 changed files with 114 additions and 45 deletions

View file

@ -48,7 +48,7 @@ public class DiscordAuthController(
public async Task<IActionResult> RegisterAsync([FromBody] AuthController.OauthRegisterRequest req)
{
var remoteUser = await keyCacheSvc.GetKeyAsync<RemoteAuthService.RemoteUser>($"discord:{req.Ticket}");
if (remoteUser == null) throw new ApiError.BadRequest("Invalid ticket", "ticket");
if (remoteUser == null) throw new ApiError.BadRequest("Invalid ticket", "ticket", req.Ticket);
if (await db.AuthMethods.AnyAsync(a => a.AuthType == AuthType.Discord && a.RemoteId == remoteUser.Id))
{
logger.Error("Discord user {Id} has valid ticket but is already linked to an existing account",

View file

@ -45,7 +45,7 @@ public class MembersController(
if (await db.Members.AnyAsync(m => m.UserId == CurrentUser!.Id && m.Name.ToLower() == req.Name.ToLower()))
#pragma warning restore CA1862
{
throw new ApiError.BadRequest("A member with that name already exists", "name");
throw new ApiError.BadRequest("A member with that name already exists", "name", req.Name);
}
var member = new Member

View file

@ -38,30 +38,35 @@ public class UsersController(DatabaseContext db, UserRendererService userRendere
{
await using var tx = await db.Database.BeginTransactionAsync();
var user = await db.Users.FirstAsync(u => u.Id == CurrentUser!.Id);
var errors = new List<(string, ValidationError?)>();
if (req.Username != null && req.Username != user.Username)
{
ValidationUtils.ValidateUsername(req.Username);
errors.Add(("username", ValidationUtils.ValidateUsername(req.Username)));
user.Username = req.Username;
}
if (req.HasProperty(nameof(req.DisplayName)))
{
ValidationUtils.ValidateDisplayName(req.DisplayName);
errors.Add(("display_name", ValidationUtils.ValidateDisplayName(req.DisplayName)));
user.DisplayName = req.DisplayName;
}
if (req.HasProperty(nameof(req.Bio)))
{
ValidationUtils.ValidateBio(req.Bio);
errors.Add(("bio", ValidationUtils.ValidateBio(req.Bio)));
user.Bio = req.Bio;
}
if (req.HasProperty(nameof(req.Avatar)))
{
ValidationUtils.ValidateAvatar(req.Avatar);
errors.Add(("avatar", ValidationUtils.ValidateAvatar(req.Avatar)));
ValidationUtils.Validate(errors);
// This is fired off regardless of whether the transaction is committed
// (atomic operations are hard when combined with background jobs)
// so it's in a separate block to the validation above.
if (req.HasProperty(nameof(req.Avatar)))
AvatarUpdateJob.QueueUpdateUserAvatar(CurrentUser!.Id, req.Avatar);
}
await db.SaveChangesAsync();
await tx.CommitAsync();