[backend] Rework GracefulException throws without additional detail

This commit is contained in:
Laura Hausmann 2024-09-24 00:45:18 +02:00
parent d1721d71c2
commit 1c2079e1ee
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
11 changed files with 31 additions and 30 deletions

View file

@ -3,7 +3,6 @@ using Iceshrimp.Backend.Controllers.Pleroma.Schemas.Entities;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Extensions;
using Iceshrimp.Backend.Core.Middleware;
using Iceshrimp.Backend.Core.Services;
using Microsoft.EntityFrameworkCore;
@ -16,7 +15,7 @@ public class NotificationRenderer(DatabaseContext db, NoteRenderer noteRenderer,
IEnumerable<StatusEntity>? statuses = null, Dictionary<string, string>? emojiUrls = null
)
{
var dbNotifier = notification.Notifier ?? throw new GracefulException("Notification has no notifier");
var dbNotifier = notification.Notifier ?? throw new Exception("Notification has no notifier");
var targetNote = notification.Note;

View file

@ -109,9 +109,9 @@ public class AuthController(DatabaseContext db, UserService userSvc, UserRendere
Justification = "Argon2 is execution time-heavy by design")]
public async Task<AuthResponse> ChangePassword([FromBody] ChangePasswordRequest request)
{
var user = HttpContext.GetUser() ?? throw new GracefulException("HttpContext.GetUser() was null");
var user = HttpContext.GetUserOrFail();
var settings = await db.UserSettings.FirstOrDefaultAsync(p => p.User == user);
if (settings is not { Password: not null }) throw new GracefulException("settings?.Password was null");
if (settings is not { Password: not null }) throw new Exception("settings?.Password was null");
if (!AuthHelpers.ComparePassword(request.OldPassword, settings.Password))
throw GracefulException.BadRequest("old_password is invalid");
if (request.NewPassword.Length < 8)

View file

@ -202,7 +202,7 @@ public static class QueryableExtensions
.OfType<LinkPaginationAttribute>()
.FirstOrDefault();
if (filter == null)
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
throw new Exception("Route doesn't have a LinkPaginationAttribute");
return Paginate(query, pq, filter.DefaultLimit, filter.MaxLimit);
}
@ -230,7 +230,7 @@ public static class QueryableExtensions
.OfType<LinkPaginationAttribute>()
.FirstOrDefault();
if (filter == null)
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
throw new Exception("Route doesn't have a LinkPaginationAttribute");
return PaginateByOffset(query, pq, filter.DefaultLimit, filter.MaxLimit);
}
@ -246,7 +246,7 @@ public static class QueryableExtensions
.OfType<LinkPaginationAttribute>()
.FirstOrDefault();
if (filter == null)
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
throw new Exception("Route doesn't have a LinkPaginationAttribute");
return Paginate(query, predicate, pq, filter.DefaultLimit, filter.MaxLimit);
}
@ -262,7 +262,7 @@ public static class QueryableExtensions
.OfType<LinkPaginationAttribute>()
.FirstOrDefault();
if (filter == null)
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
throw new Exception("Route doesn't have a LinkPaginationAttribute");
return Paginate(query, predicate, pq, filter.DefaultLimit, filter.MaxLimit);
}
@ -277,7 +277,7 @@ public static class QueryableExtensions
.OfType<LinkPaginationAttribute>()
.FirstOrDefault();
if (filter == null)
throw new GracefulException("Route doesn't have a LinkPaginationAttribute");
throw new Exception("Route doesn't have a LinkPaginationAttribute");
return Paginate(query, pq, filter.DefaultLimit, filter.MaxLimit);
}

View file

@ -145,12 +145,14 @@ public class ActivityFetcherService(
var input = await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<JObject?>(input);
var res = LdHelpers.Expand(json) ?? throw new GracefulException("Failed to expand JSON-LD object");
var res = LdHelpers.Expand(json) ??
throw new GracefulException(HttpStatusCode.UnprocessableEntity, "Failed to expand JSON-LD object");
if (res.Count != 1)
throw new GracefulException("Received zero or more than one activity");
throw new GracefulException(HttpStatusCode.UnprocessableEntity, "Received zero or more than one activity");
var activity = res[0].ToObject<ASObject>(new JsonSerializer { Converters = { new ASObjectConverter() } }) ??
throw new GracefulException("Failed to deserialize activity");
throw new GracefulException(HttpStatusCode.UnprocessableEntity,
"Failed to deserialize activity");
if (finalUri.Host == config.Value.WebDomain || finalUri.Host == config.Value.WebDomain)
throw GracefulException.UnprocessableEntity("Refusing to process activity from local domain");
@ -214,7 +216,7 @@ public class ActivityFetcherService(
{
var activity = await FetchActivityAsync(uri, actor, keypair);
return activity.OfType<ASActor>().FirstOrDefault() ??
throw new GracefulException($"Failed to fetch actor: {uri}");
throw new Exception($"Failed to fetch actor: {uri}");
}
public async Task<ASActor> FetchActorAsync(string uri)

View file

@ -4,7 +4,6 @@ using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types;
using Iceshrimp.Backend.Core.Helpers.LibMfm.Conversion;
using Iceshrimp.Backend.Core.Middleware;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
@ -20,7 +19,7 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, DatabaseConte
public ASActor RenderLite(User user)
{
return user.IsRemoteUser
? new ASActor { Id = user.Uri ?? throw new GracefulException("Remote user must have an URI") }
? new ASActor { Id = user.Uri ?? throw new Exception("Remote user must have an URI") }
: new ASActor { Id = user.GetPublicUri(config.Value) };
}
@ -28,13 +27,13 @@ public class UserRenderer(IOptions<Config.InstanceSection> config, DatabaseConte
{
if (user.IsRemoteUser)
{
return new ASActor { Id = user.Uri ?? throw new GracefulException("Remote user must have an URI") };
return new ASActor { Id = user.Uri ?? throw new Exception("Remote user must have an URI") };
}
var profile = await db.UserProfiles.FirstOrDefaultAsync(p => p.User == user);
var keypair = await db.UserKeypairs.FirstOrDefaultAsync(p => p.User == user);
if (keypair == null) throw new GracefulException("User has no keypair");
if (keypair == null) throw new Exception("User has no keypair");
var id = user.GetPublicUri(config.Value);
var type = Constants.SystemUsers.Contains(user.UsernameLower)

View file

@ -151,7 +151,7 @@ public class UserResolver(
fingerRes = await webFingerSvc.ResolveAsync(acctUri);
if (fingerRes == null) throw new GracefulException($"Failed to WebFinger '{acctUri}'");
if (fingerRes == null) throw new Exception($"Failed to WebFinger '{acctUri}'");
responses.Add(acctUri, fingerRes);
}
@ -159,14 +159,14 @@ public class UserResolver(
throw new Exception($"WebFinger response for '{acctUri}' didn't contain any acct uris");
var finalUri = fingerRes.Links.FirstOrDefault(p => p is { Rel: "self", Type: "application/activity+json" })
?.Href ??
throw new GracefulException("Final AP URI was null");
throw new Exception("Final AP URI was null");
if (apUri != finalUri)
{
logger.LogDebug("WebFinger: finalUri doesn't match apUri, setting acct host to apUri host: {apUri}", apUri);
var split = finalAcct.Split('@');
if (split.Length != 2)
throw new GracefulException($"Failed to finalize WebFinger for '{apUri}': invalid acct '{finalAcct}'");
throw new Exception($"Failed to finalize WebFinger for '{apUri}': invalid acct '{finalAcct}'");
split[1] = new Uri(apUri).Host;
finalAcct = string.Join('@', split);
}

View file

@ -148,7 +148,7 @@ public static partial class HttpContextExtensions
public static User GetUserOrFail(this HttpContext ctx)
{
return ctx.GetUser() ?? throw new GracefulException("Failed to get user from HttpContext");
return ctx.GetUser() ?? throw new Exception("Failed to get user from HttpContext");
}
public static bool ShouldHideFooter(this HttpContext ctx)

View file

@ -76,16 +76,15 @@ public class AuthorizedFetchMiddleware(
catch (Exception e)
{
if (e is GracefulException) throw;
throw new
GracefulException($"Failed to fetch key of signature user ({sig.KeyId}) - {e.Message}");
throw new Exception($"Failed to fetch key of signature user ({sig.KeyId}) - {e.Message}");
}
}
// If we still don't have the key, something went wrong and we need to throw an exception
if (key == null) throw new GracefulException($"Failed to fetch key of signature user ({sig.KeyId})");
if (key == null) throw new Exception($"Failed to fetch key of signature user ({sig.KeyId})");
if (key.User.IsLocalUser)
throw new GracefulException("Remote user must have a host");
throw new Exception("Remote user must have a host");
// We want to check both the user host & the keyId host (as account & web domain might be different)
if (await fedCtrlSvc.ShouldBlockAsync(key.User.Host, key.KeyId))

View file

@ -89,7 +89,8 @@ public class InboxValidationMiddleware(
if (obj == null)
throw new Exception("Failed to deserialize ASObject");
if (obj is not ASActivity activity)
throw new GracefulException("Request body is not an ASActivity", $"Type: {obj.Type}");
throw new GracefulException(HttpStatusCode.UnprocessableEntity,
"Request body is not an ASActivity", $"Type: {obj.Type}");
UserPublickey? key = null;
var verified = false;
@ -128,7 +129,7 @@ public class InboxValidationMiddleware(
if (key == null) throw new GracefulException($"Failed to fetch key of signature user ({sig.KeyId})");
if (key.User.IsLocalUser)
throw new GracefulException("Remote user must have a host");
throw new Exception("Remote user must have a host");
// We want to check both the user host & the keyId host (as account & web domain might be different)
if (await fedCtrlSvc.ShouldBlockAsync(key.User.Host, key.KeyId))

View file

@ -1,3 +1,4 @@
using System.Net;
using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Federation.ActivityStreams;
using Iceshrimp.Backend.Core.Federation.ActivityStreams.Types;
@ -22,7 +23,8 @@ public class InboxQueue(int parallelism)
var expanded = LdHelpers.Expand(JToken.Parse(jobData.Body)) ?? throw new Exception("Failed to expand ASObject");
var obj = ASObject.Deserialize(expanded) ?? throw new Exception("Failed to deserialize ASObject");
if (obj is not ASActivity activity)
throw new GracefulException("Job data is not an ASActivity", $"Type: {obj.Type}");
throw new GracefulException(HttpStatusCode.UnprocessableEntity, "Job data is not an ASActivity",
$"Type: {obj.Type}");
var apHandler = scope.GetRequiredService<ActivityPub.ActivityHandlerService>();
try

View file

@ -3,7 +3,6 @@ using AsyncKeyedLock;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Database.Tables;
using Iceshrimp.Backend.Core.Helpers;
using Iceshrimp.Backend.Core.Middleware;
using Microsoft.EntityFrameworkCore;
namespace Iceshrimp.Backend.Core.Services;
@ -67,7 +66,7 @@ public class SystemUserService(ILogger<SystemUserService> logger, DatabaseContex
private async Task<User> CreateSystemUserAsync(string username)
{
if (await db.Users.AnyAsync(p => p.UsernameLower == username.ToLowerInvariant() && p.IsLocalUser))
throw new GracefulException($"System user {username} already exists");
throw new Exception($"System user {username} already exists");
var keypair = RSA.Create(4096);
var user = new User