refactor(backend): misc cleanup

This commit is contained in:
sam 2025-03-13 15:18:35 +01:00
parent 5d452824cd
commit f5f0416346
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
8 changed files with 43 additions and 62 deletions

View file

@ -196,9 +196,6 @@ public static class WebApplicationExtensions
public static async Task Initialize(this WebApplication app, string[] args)
{
// Read version information from .version in the repository root
await BuildInfo.ReadBuildInfo();
app.Services.ConfigureQueue()
.LogQueuedTaskProgress(app.Services.GetRequiredService<ILogger<IQueue>>());

View file

@ -34,6 +34,9 @@ Config config = builder.AddConfiguration();
builder.AddSerilog();
// Read version information from .version in the repository root
await BuildInfo.ReadBuildInfo();
builder
.WebHost.UseSentry(opts =>
{
@ -68,11 +71,9 @@ builder
})
.ConfigureApiBehaviorOptions(options =>
{
// the type isn't needed but without it, rider keeps complaining for no reason (it compiles just fine)
options.InvalidModelStateResponseFactory = (ActionContext actionContext) =>
new BadRequestObjectResult(
new ApiError.AspBadRequest("Bad request", actionContext.ModelState).ToJson()
);
options.InvalidModelStateResponseFactory = actionContext => new BadRequestObjectResult(
new ApiError.AspBadRequest("Bad request", actionContext.ModelState).ToJson()
);
});
builder

View file

@ -25,20 +25,20 @@ namespace Foxnouns.Backend.Services.Auth;
public partial class FediverseAuthService
{
private string MastodonRedirectUri(string instance) =>
$"{_config.BaseUrl}/auth/callback/mastodon/{instance}";
$"{config.BaseUrl}/auth/callback/mastodon/{instance}";
private async Task<FediverseApplication> CreateMastodonApplicationAsync(
string instance,
Snowflake? existingAppId = null
)
{
HttpResponseMessage resp = await _client.PostAsJsonAsync(
HttpResponseMessage resp = await client.PostAsJsonAsync(
$"https://{instance}/api/v1/apps",
new CreateMastodonApplicationRequest(
$"pronouns.cc (+{_config.BaseUrl})",
$"pronouns.cc (+{config.BaseUrl})",
MastodonRedirectUri(instance),
"read read:accounts",
_config.BaseUrl
config.BaseUrl
)
);
resp.EnsureSuccessStatusCode();
@ -58,19 +58,19 @@ public partial class FediverseAuthService
{
app = new FediverseApplication
{
Id = existingAppId ?? _snowflakeGenerator.GenerateSnowflake(),
Id = existingAppId ?? snowflakeGenerator.GenerateSnowflake(),
ClientId = mastodonApp.ClientId,
ClientSecret = mastodonApp.ClientSecret,
Domain = instance,
InstanceType = FediverseInstanceType.MastodonApi,
};
_db.Add(app);
db.Add(app);
}
else
{
app =
await _db.FediverseApplications.FindAsync(existingAppId)
await db.FediverseApplications.FindAsync(existingAppId)
?? throw new FoxnounsError($"Existing app with ID {existingAppId} was null");
app.ClientId = mastodonApp.ClientId;
@ -78,7 +78,7 @@ public partial class FediverseAuthService
app.InstanceType = FediverseInstanceType.MastodonApi;
}
await _db.SaveChangesAsync();
await db.SaveChangesAsync();
return app;
}
@ -90,9 +90,9 @@ public partial class FediverseAuthService
)
{
if (state != null)
await _keyCacheService.ValidateAuthStateAsync(state);
await keyCacheService.ValidateAuthStateAsync(state);
HttpResponseMessage tokenResp = await _client.PostAsync(
HttpResponseMessage tokenResp = await client.PostAsync(
MastodonTokenUri(app.Domain),
new FormUrlEncodedContent(
new Dictionary<string, string>
@ -123,7 +123,7 @@ public partial class FediverseAuthService
var req = new HttpRequestMessage(HttpMethod.Get, MastodonCurrentUserUri(app.Domain));
req.Headers.Add("Authorization", $"Bearer {token}");
HttpResponseMessage currentUserResp = await _client.SendAsync(req);
HttpResponseMessage currentUserResp = await client.SendAsync(req);
currentUserResp.EnsureSuccessStatusCode();
FediverseUser? user = await currentUserResp.Content.ReadFromJsonAsync<FediverseUser>();
if (user == null)
@ -151,7 +151,7 @@ public partial class FediverseAuthService
app = await CreateMastodonApplicationAsync(app.Domain, app.Id);
}
state ??= HttpUtility.UrlEncode(await _keyCacheService.GenerateAuthStateAsync());
state ??= HttpUtility.UrlEncode(await keyCacheService.GenerateAuthStateAsync());
return $"https://{app.Domain}/oauth/authorize?response_type=code"
+ $"&client_id={app.ClientId}"

View file

@ -34,11 +34,11 @@ public partial class FediverseAuthService
Snowflake? existingAppId = null
)
{
HttpResponseMessage resp = await _client.PostAsJsonAsync(
HttpResponseMessage resp = await client.PostAsJsonAsync(
MisskeyAppUri(instance),
new CreateMisskeyApplicationRequest(
$"pronouns.cc (+{_config.BaseUrl})",
$"pronouns.cc on {_config.BaseUrl}",
$"pronouns.cc (+{config.BaseUrl})",
$"pronouns.cc on {config.BaseUrl}",
["read:account"],
MastodonRedirectUri(instance)
)
@ -60,19 +60,19 @@ public partial class FediverseAuthService
{
app = new FediverseApplication
{
Id = existingAppId ?? _snowflakeGenerator.GenerateSnowflake(),
Id = existingAppId ?? snowflakeGenerator.GenerateSnowflake(),
ClientId = misskeyApp.Id,
ClientSecret = misskeyApp.Secret,
Domain = instance,
InstanceType = FediverseInstanceType.MisskeyApi,
};
_db.Add(app);
db.Add(app);
}
else
{
app =
await _db.FediverseApplications.FindAsync(existingAppId)
await db.FediverseApplications.FindAsync(existingAppId)
?? throw new FoxnounsError($"Existing app with ID {existingAppId} was null");
app.ClientId = misskeyApp.Id;
@ -80,7 +80,7 @@ public partial class FediverseAuthService
app.InstanceType = FediverseInstanceType.MisskeyApi;
}
await _db.SaveChangesAsync();
await db.SaveChangesAsync();
return app;
}
@ -96,7 +96,7 @@ public partial class FediverseAuthService
private async Task<FediverseUser> GetMisskeyUserAsync(FediverseApplication app, string code)
{
HttpResponseMessage resp = await _client.PostAsJsonAsync(
HttpResponseMessage resp = await client.PostAsJsonAsync(
MisskeyTokenUri(app.Domain),
new GetMisskeySessionUserKeyRequest(app.ClientSecret, code)
);
@ -130,7 +130,7 @@ public partial class FediverseAuthService
app = await CreateMisskeyApplicationAsync(app.Domain, app.Id);
}
HttpResponseMessage resp = await _client.PostAsJsonAsync(
HttpResponseMessage resp = await client.PostAsJsonAsync(
MisskeyGenerateSessionUri(app.Domain),
new CreateMisskeySessionUriRequest(app.ClientSecret)
);

View file

@ -19,33 +19,17 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute;
namespace Foxnouns.Backend.Services.Auth;
public partial class FediverseAuthService
public partial class FediverseAuthService(
ILogger logger,
Config config,
DatabaseContext db,
HttpClient client,
KeyCacheService keyCacheService,
ISnowflakeGenerator snowflakeGenerator
)
{
private const string NodeInfoRel = "http://nodeinfo.diaspora.software/ns/schema/2.0";
private readonly HttpClient _client;
private readonly ILogger _logger;
private readonly Config _config;
private readonly DatabaseContext _db;
private readonly KeyCacheService _keyCacheService;
private readonly ISnowflakeGenerator _snowflakeGenerator;
public FediverseAuthService(
ILogger logger,
Config config,
DatabaseContext db,
HttpClient client,
KeyCacheService keyCacheService,
ISnowflakeGenerator snowflakeGenerator
)
{
_logger = logger.ForContext<FediverseAuthService>();
_config = config;
_db = db;
_keyCacheService = keyCacheService;
_snowflakeGenerator = snowflakeGenerator;
_client = client;
}
private readonly ILogger _logger = logger.ForContext<FediverseAuthService>();
public async Task<string> GenerateAuthUrlAsync(
string instance,
@ -66,7 +50,7 @@ public partial class FediverseAuthService
public async Task<FediverseApplication> GetApplicationAsync(string instance)
{
FediverseApplication? app = await _db.FediverseApplications.FirstOrDefaultAsync(a =>
FediverseApplication? app = await db.FediverseApplications.FirstOrDefaultAsync(a =>
a.Domain == instance
);
if (app != null)
@ -88,7 +72,7 @@ public partial class FediverseAuthService
{
_logger.Debug("Requesting software name for fediverse instance {Instance}", instance);
HttpResponseMessage wellKnownResp = await _client.GetAsync(
HttpResponseMessage wellKnownResp = await client.GetAsync(
new Uri($"https://{instance}/.well-known/nodeinfo")
);
wellKnownResp.EnsureSuccessStatusCode();
@ -103,7 +87,7 @@ public partial class FediverseAuthService
);
}
HttpResponseMessage nodeInfoResp = await _client.GetAsync(nodeInfoUrl);
HttpResponseMessage nodeInfoResp = await client.GetAsync(nodeInfoUrl);
nodeInfoResp.EnsureSuccessStatusCode();
PartialNodeInfo? nodeInfo = await nodeInfoResp.Content.ReadFromJsonAsync<PartialNodeInfo>();

View file

@ -39,8 +39,6 @@ public class KeyCacheService(Config config)
public async Task DeleteKeyAsync(string key) =>
await Multiplexer.GetDatabase().KeyDeleteAsync(key);
public Task DeleteExpiredKeysAsync(CancellationToken ct) => Task.CompletedTask;
public async Task SetKeyAsync<T>(string key, T obj, Duration expiresAt)
where T : class
{

View file

@ -33,11 +33,9 @@ public class PeriodicTasksService(ILogger logger, IServiceProvider services) : B
// The type is literally written on the same line, we can just use `var`
// ReSharper disable SuggestVarOrType_SimpleTypes
var keyCacheService = scope.ServiceProvider.GetRequiredService<KeyCacheService>();
var dataCleanupService = scope.ServiceProvider.GetRequiredService<DataCleanupService>();
// ReSharper restore SuggestVarOrType_SimpleTypes
await keyCacheService.DeleteExpiredKeysAsync(ct);
await dataCleanupService.InvokeAsync(ct);
}
}

View file

@ -31,6 +31,7 @@ public partial class ValidationService
"settings",
"pronouns.cc",
"pronounscc",
"null",
];
private static readonly string[] InvalidMemberNames =
@ -38,8 +39,10 @@ public partial class ValidationService
// these break routing outright
".",
"..",
// the user edit page lives at `/@{username}/edit`, so a member named "edit" would be inaccessible
// TODO: remove this? i'm not sure if /@[username]/edit will redirect to settings
"edit",
// this breaks the frontend, somehow
"null",
];
public ValidationError? ValidateUsername(string username)