[backend/core] Improve error handling in code paths that try to resolve a deleted remote user
This commit is contained in:
parent
399595ad1c
commit
f22c4a7c32
4 changed files with 20 additions and 9 deletions
|
@ -1,3 +1,4 @@
|
|||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using Iceshrimp.Backend.Core.Database.Tables;
|
||||
using Iceshrimp.Backend.Core.Federation.ActivityStreams;
|
||||
|
@ -34,6 +35,8 @@ public class ActivityFetcherService(
|
|||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
if (response.StatusCode == HttpStatusCode.Gone)
|
||||
throw AuthFetchException.NotFound("The remote user no longer exists.");
|
||||
logger.LogDebug("Failed to fetch activity: response status was {code}", response.StatusCode);
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class WebFingerService(HttpClient client, HttpRequestService httpRqSvc, I
|
|||
var res = await client.SendAsync(req, cts.Token);
|
||||
|
||||
if (res.StatusCode == HttpStatusCode.Gone)
|
||||
throw GracefulException.Accepted("The remote user no longer exists.");
|
||||
throw AuthFetchException.NotFound("The remote user no longer exists.");
|
||||
if (!res.IsSuccessStatusCode)
|
||||
return null;
|
||||
if (res.Content.Headers.ContentType?.MediaType is not "application/jrd+json" and not "application/json")
|
||||
|
|
|
@ -61,7 +61,7 @@ public class AuthorizedFetchMiddleware(
|
|||
|
||||
if (await fedCtrlSvc.ShouldBlockAsync(sig.KeyId))
|
||||
throw new GracefulException(HttpStatusCode.Forbidden, "Forbidden", "Instance is blocked",
|
||||
supressLog: true);
|
||||
suppressLog: true);
|
||||
|
||||
// First, we check if we already have the key
|
||||
key = await db.UserPublickeys.Include(p => p.User)
|
||||
|
@ -93,7 +93,7 @@ public class AuthorizedFetchMiddleware(
|
|||
// 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))
|
||||
throw new GracefulException(HttpStatusCode.Forbidden, "Forbidden", "Instance is blocked",
|
||||
supressLog: true);
|
||||
suppressLog: true);
|
||||
|
||||
List<string> headers = request.ContentLength > 0 || attribute.ForceBody
|
||||
? ["(request-target)", "digest", "host", "date"]
|
||||
|
@ -112,6 +112,7 @@ public class AuthorizedFetchMiddleware(
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is AuthFetchException afe) throw GracefulException.Accepted(afe.Message);
|
||||
if (e is GracefulException { SuppressLog: true }) throw;
|
||||
logger.LogDebug("Error validating HTTP signature: {error}", e.Message);
|
||||
}
|
||||
|
@ -142,7 +143,7 @@ public class AuthorizedFetchMiddleware(
|
|||
throw new Exception("Activity has no actor");
|
||||
if (await fedCtrlSvc.ShouldBlockAsync(new Uri(activity.Actor.Id).Host))
|
||||
throw new GracefulException(HttpStatusCode.Forbidden, "Forbidden", "Instance is blocked",
|
||||
supressLog: true);
|
||||
suppressLog: true);
|
||||
key = null;
|
||||
key = await db.UserPublickeys
|
||||
.Include(p => p.User)
|
||||
|
@ -161,7 +162,7 @@ public class AuthorizedFetchMiddleware(
|
|||
|
||||
if (await fedCtrlSvc.ShouldBlockAsync(key.User.Host, new Uri(key.KeyId).Host))
|
||||
throw new GracefulException(HttpStatusCode.Forbidden, "Forbidden", "Instance is blocked",
|
||||
supressLog: true);
|
||||
suppressLog: true);
|
||||
|
||||
// We need to re-run deserialize & expand with date time handling disabled for JSON-LD canonicalization to work correctly
|
||||
var rawDeserialized = JsonConvert.DeserializeObject<JObject?>(body, JsonSerializerSettings);
|
||||
|
@ -182,6 +183,7 @@ public class AuthorizedFetchMiddleware(
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e is AuthFetchException afe) throw GracefulException.Accepted(afe.Message);
|
||||
if (e is GracefulException { SuppressLog: true }) throw;
|
||||
logger.LogError("Error validating JSON-LD signature: {error}", e.Message);
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ public class GracefulException(
|
|||
string error,
|
||||
string message,
|
||||
string? details = null,
|
||||
bool supressLog = false,
|
||||
bool suppressLog = false,
|
||||
bool overrideBasic = false
|
||||
) : Exception(message)
|
||||
{
|
||||
|
@ -153,7 +153,7 @@ public class GracefulException(
|
|||
public readonly string Error = error;
|
||||
public readonly bool OverrideBasic = overrideBasic;
|
||||
public readonly HttpStatusCode StatusCode = statusCode;
|
||||
public readonly bool SuppressLog = supressLog;
|
||||
public readonly bool SuppressLog = suppressLog;
|
||||
|
||||
public GracefulException(HttpStatusCode statusCode, string message, string? details = null) :
|
||||
this(statusCode, statusCode.ToString(), message, details) { }
|
||||
|
@ -190,8 +190,14 @@ public class GracefulException(
|
|||
/// returning 410 Gone)
|
||||
/// </summary>
|
||||
public static GracefulException Accepted(string message) =>
|
||||
new(HttpStatusCode.Accepted, HttpStatusCode.Accepted.ToString(),
|
||||
message, supressLog: true);
|
||||
new(HttpStatusCode.Accepted, HttpStatusCode.Accepted.ToString(), message, suppressLog: true);
|
||||
}
|
||||
|
||||
public class AuthFetchException(HttpStatusCode statusCode, string message, string? details = null)
|
||||
: GracefulException(statusCode, message, details)
|
||||
{
|
||||
public static AuthFetchException NotFound(string message) =>
|
||||
new(HttpStatusCode.NotFound, HttpStatusCode.NotFound.ToString(), message);
|
||||
}
|
||||
|
||||
public enum ExceptionVerbosity
|
||||
|
|
Loading…
Add table
Reference in a new issue