refactor(backend): misc cleanup
This commit is contained in:
		
							parent
							
								
									5d452824cd
								
							
						
					
					
						commit
						f5f0416346
					
				
					 8 changed files with 43 additions and 62 deletions
				
			
		|  | @ -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>>()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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}" | ||||
|  |  | |||
|  | @ -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) | ||||
|         ); | ||||
|  |  | |||
|  | @ -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>(); | ||||
|  |  | |||
|  | @ -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 | ||||
|     { | ||||
|  |  | |||
|  | @ -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); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue