start (actual) email auth, add CancellationToken to most async methods
This commit is contained in:
parent
acc54a55bc
commit
344a0071e5
22 changed files with 325 additions and 152 deletions
|
@ -14,12 +14,12 @@ public static class AvatarObjectExtensions
|
|||
private static readonly string[] ValidContentTypes = ["image/png", "image/webp", "image/jpeg"];
|
||||
|
||||
public static async Task
|
||||
DeleteMemberAvatarAsync(this ObjectStorageService objectStorage, Snowflake id, string hash) =>
|
||||
await objectStorage.RemoveObjectAsync(MemberAvatarUpdateInvocable.Path(id, hash));
|
||||
DeleteMemberAvatarAsync(this ObjectStorageService objectStorage, Snowflake id, string hash, CancellationToken ct = default) =>
|
||||
await objectStorage.RemoveObjectAsync(MemberAvatarUpdateInvocable.Path(id, hash), ct);
|
||||
|
||||
public static async Task
|
||||
DeleteUserAvatarAsync(this ObjectStorageService objectStorage, Snowflake id, string hash) =>
|
||||
await objectStorage.RemoveObjectAsync(UserAvatarUpdateInvocable.Path(id, hash));
|
||||
DeleteUserAvatarAsync(this ObjectStorageService objectStorage, Snowflake id, string hash, CancellationToken ct = default) =>
|
||||
await objectStorage.RemoveObjectAsync(UserAvatarUpdateInvocable.Path(id, hash), ct);
|
||||
|
||||
public static async Task<Stream> ConvertBase64UriToAvatar(this string uri)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using Foxnouns.Backend.Database;
|
||||
using Foxnouns.Backend.Services;
|
||||
using Foxnouns.Backend.Utils;
|
||||
using NodaTime;
|
||||
|
@ -6,16 +7,31 @@ namespace Foxnouns.Backend.Extensions;
|
|||
|
||||
public static class KeyCacheExtensions
|
||||
{
|
||||
public static async Task<string> GenerateAuthStateAsync(this KeyCacheService keyCacheSvc)
|
||||
public static async Task<string> GenerateAuthStateAsync(this KeyCacheService keyCacheSvc, CancellationToken ct = default)
|
||||
{
|
||||
var state = AuthUtils.RandomToken();
|
||||
await keyCacheSvc.SetKeyAsync($"oauth_state:{state}", "", Duration.FromMinutes(10));
|
||||
await keyCacheSvc.SetKeyAsync($"oauth_state:{state}", "", Duration.FromMinutes(10), ct);
|
||||
return state;
|
||||
}
|
||||
|
||||
public static async Task ValidateAuthStateAsync(this KeyCacheService keyCacheSvc, string state)
|
||||
public static async Task ValidateAuthStateAsync(this KeyCacheService keyCacheSvc, string state, CancellationToken ct = default)
|
||||
{
|
||||
var val = await keyCacheSvc.GetKeyAsync($"oauth_state:{state}", delete: true);
|
||||
var val = await keyCacheSvc.GetKeyAsync($"oauth_state:{state}", delete: true, ct);
|
||||
if (val == null) throw new ApiError.BadRequest("Invalid OAuth state");
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<string> GenerateRegisterEmailStateAsync(this KeyCacheService keyCacheSvc, string email,
|
||||
Snowflake? userId = null, CancellationToken ct = default)
|
||||
{
|
||||
var state = AuthUtils.RandomToken();
|
||||
await keyCacheSvc.SetKeyAsync($"email_state:{state}", new RegisterEmailState(email, userId),
|
||||
Duration.FromDays(1), ct);
|
||||
return state;
|
||||
}
|
||||
|
||||
public static async Task<RegisterEmailState?> GetRegisterEmailStateAsync(this KeyCacheService keyCacheSvc,
|
||||
string state, CancellationToken ct = default) =>
|
||||
await keyCacheSvc.GetKeyAsync<RegisterEmailState>($"email_state:{state}", delete: true, ct);
|
||||
}
|
||||
|
||||
public record RegisterEmailState(string Email, Snowflake? ExistingUserId);
|
|
@ -70,38 +70,43 @@ public static class WebApplicationExtensions
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds required services to the IServiceCollection.
|
||||
/// Adds required services to the WebApplicationBuilder.
|
||||
/// This should only add services that are not ASP.NET-related (i.e. no middleware).
|
||||
/// </summary>
|
||||
public static IServiceCollection AddServices(this IServiceCollection services, Config config)
|
||||
public static IServiceCollection AddServices(this WebApplicationBuilder builder, Config config)
|
||||
{
|
||||
services
|
||||
.AddQueue()
|
||||
.AddDbContext<DatabaseContext>()
|
||||
.AddMetricServer(o => o.Port = config.Logging.MetricsPort)
|
||||
.AddMinio(c =>
|
||||
c.WithEndpoint(config.Storage.Endpoint)
|
||||
.WithCredentials(config.Storage.AccessKey, config.Storage.SecretKey)
|
||||
.Build())
|
||||
.AddSingleton<MetricsCollectionService>()
|
||||
.AddSingleton<IClock>(SystemClock.Instance)
|
||||
.AddSnowflakeGenerator()
|
||||
.AddScoped<UserRendererService>()
|
||||
.AddScoped<MemberRendererService>()
|
||||
.AddScoped<AuthService>()
|
||||
.AddScoped<KeyCacheService>()
|
||||
.AddScoped<RemoteAuthService>()
|
||||
.AddScoped<ObjectStorageService>()
|
||||
// Background services
|
||||
.AddHostedService<PeriodicTasksService>()
|
||||
// Transient jobs
|
||||
.AddTransient<MemberAvatarUpdateInvocable>()
|
||||
.AddTransient<UserAvatarUpdateInvocable>();
|
||||
|
||||
if (!config.Logging.EnableMetrics)
|
||||
services.AddHostedService<BackgroundMetricsCollectionService>();
|
||||
|
||||
return services;
|
||||
builder.Host.ConfigureServices((ctx, services) =>
|
||||
{
|
||||
services
|
||||
.AddQueue()
|
||||
.AddMailer(ctx.Configuration)
|
||||
.AddDbContext<DatabaseContext>()
|
||||
.AddMetricServer(o => o.Port = config.Logging.MetricsPort)
|
||||
.AddMinio(c =>
|
||||
c.WithEndpoint(config.Storage.Endpoint)
|
||||
.WithCredentials(config.Storage.AccessKey, config.Storage.SecretKey)
|
||||
.Build())
|
||||
.AddSingleton<MetricsCollectionService>()
|
||||
.AddSingleton<IClock>(SystemClock.Instance)
|
||||
.AddSnowflakeGenerator()
|
||||
.AddSingleton<MailService>()
|
||||
.AddScoped<UserRendererService>()
|
||||
.AddScoped<MemberRendererService>()
|
||||
.AddScoped<AuthService>()
|
||||
.AddScoped<KeyCacheService>()
|
||||
.AddScoped<RemoteAuthService>()
|
||||
.AddScoped<ObjectStorageService>()
|
||||
// Background services
|
||||
.AddHostedService<PeriodicTasksService>()
|
||||
// Transient jobs
|
||||
.AddTransient<MemberAvatarUpdateInvocable>()
|
||||
.AddTransient<UserAvatarUpdateInvocable>();
|
||||
|
||||
if (!config.Logging.EnableMetrics)
|
||||
services.AddHostedService<BackgroundMetricsCollectionService>();
|
||||
});
|
||||
|
||||
return builder.Services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddCustomMiddleware(this IServiceCollection services) => services
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue