diff --git a/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NotificationRenderer.cs b/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NotificationRenderer.cs index b54737ff..cf52e43e 100644 --- a/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NotificationRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Mastodon/Renderers/NotificationRenderer.cs @@ -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? statuses = null, Dictionary? 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; diff --git a/Iceshrimp.Backend/Controllers/Web/AuthController.cs b/Iceshrimp.Backend/Controllers/Web/AuthController.cs index 342b8b6a..d27766ac 100644 --- a/Iceshrimp.Backend/Controllers/Web/AuthController.cs +++ b/Iceshrimp.Backend/Controllers/Web/AuthController.cs @@ -109,9 +109,9 @@ public class AuthController(DatabaseContext db, UserService userSvc, UserRendere Justification = "Argon2 is execution time-heavy by design")] public async Task 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) diff --git a/Iceshrimp.Backend/Core/Extensions/QueryableExtensions.cs b/Iceshrimp.Backend/Core/Extensions/QueryableExtensions.cs index b057d3a1..f66cf7f8 100644 --- a/Iceshrimp.Backend/Core/Extensions/QueryableExtensions.cs +++ b/Iceshrimp.Backend/Core/Extensions/QueryableExtensions.cs @@ -202,7 +202,7 @@ public static class QueryableExtensions .OfType() .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() .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() .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() .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() .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); } diff --git a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs index 8e1df4cc..f9f391bd 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/ActivityFetcherService.cs @@ -145,12 +145,14 @@ public class ActivityFetcherService( var input = await response.Content.ReadAsStringAsync(); var json = JsonConvert.DeserializeObject(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(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().FirstOrDefault() ?? - throw new GracefulException($"Failed to fetch actor: {uri}"); + throw new Exception($"Failed to fetch actor: {uri}"); } public async Task FetchActorAsync(string uri) diff --git a/Iceshrimp.Backend/Core/Federation/ActivityPub/UserRenderer.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/UserRenderer.cs index 1fb7fcdf..90e4aaf2 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityPub/UserRenderer.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/UserRenderer.cs @@ -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, 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, 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) diff --git a/Iceshrimp.Backend/Core/Federation/ActivityPub/UserResolver.cs b/Iceshrimp.Backend/Core/Federation/ActivityPub/UserResolver.cs index cbf23f29..43366eb8 100644 --- a/Iceshrimp.Backend/Core/Federation/ActivityPub/UserResolver.cs +++ b/Iceshrimp.Backend/Core/Federation/ActivityPub/UserResolver.cs @@ -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); } diff --git a/Iceshrimp.Backend/Core/Middleware/AuthenticationMiddleware.cs b/Iceshrimp.Backend/Core/Middleware/AuthenticationMiddleware.cs index fb9a802d..8a22e252 100644 --- a/Iceshrimp.Backend/Core/Middleware/AuthenticationMiddleware.cs +++ b/Iceshrimp.Backend/Core/Middleware/AuthenticationMiddleware.cs @@ -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) diff --git a/Iceshrimp.Backend/Core/Middleware/AuthorizedFetchMiddleware.cs b/Iceshrimp.Backend/Core/Middleware/AuthorizedFetchMiddleware.cs index c9ceacb8..e5a6a7d5 100644 --- a/Iceshrimp.Backend/Core/Middleware/AuthorizedFetchMiddleware.cs +++ b/Iceshrimp.Backend/Core/Middleware/AuthorizedFetchMiddleware.cs @@ -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)) diff --git a/Iceshrimp.Backend/Core/Middleware/InboxValidationMiddleware.cs b/Iceshrimp.Backend/Core/Middleware/InboxValidationMiddleware.cs index a94c6f7f..73e87054 100644 --- a/Iceshrimp.Backend/Core/Middleware/InboxValidationMiddleware.cs +++ b/Iceshrimp.Backend/Core/Middleware/InboxValidationMiddleware.cs @@ -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)) diff --git a/Iceshrimp.Backend/Core/Queues/InboxQueue.cs b/Iceshrimp.Backend/Core/Queues/InboxQueue.cs index acf777b9..41a81fd3 100644 --- a/Iceshrimp.Backend/Core/Queues/InboxQueue.cs +++ b/Iceshrimp.Backend/Core/Queues/InboxQueue.cs @@ -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(); try diff --git a/Iceshrimp.Backend/Core/Services/SystemUserService.cs b/Iceshrimp.Backend/Core/Services/SystemUserService.cs index e9e9f723..8276b6af 100644 --- a/Iceshrimp.Backend/Core/Services/SystemUserService.cs +++ b/Iceshrimp.Backend/Core/Services/SystemUserService.cs @@ -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 logger, DatabaseContex private async Task 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