using Hutopy.Web.Common; using Hutopy.Web.Common.BlobStorage; using Hutopy.Web.Common.Security; namespace Hutopy.Web.Features.Users.Handlers; [PublicAPI] public record ChangePortraitRequest( IFormFile File); [PublicAPI] public record ChangePortraitResponse( string BlobUrl); [PublicAPI] public sealed class ChangePortraitRequestValidator : Validator { public ChangePortraitRequestValidator() { RuleFor(x => x.File) .NotNull() .NotEmpty(); } } [PublicAPI] public class ChangePortraitHandler( ApplicationUserManager userManager, AzureBlobStorage blobStorage) : Endpoint { public override void Configure() { Post("/api/users/portrait"); Options(o => o.WithTags("Users")); AllowFileUploads(); } public override async Task HandleAsync( ChangePortraitRequest request, CancellationToken ct) { var user = await userManager.FindByIdAsync(HttpContext.User.GetUserId().ToString()); if (user is null) { await SendNotFoundAsync(ct); return; } var blobUrl = await blobStorage.UploadFileAsync( ContainerNames.Users, $"{user.Id}/{SubDirectoryNames.Profile}/{CommonFileNames.ProfilePicture}", request.File.OpenReadStream(), request.File.ContentType, ct); user.PortraitUrl = blobUrl; var result = await userManager.UpdateAsync(user); if (result.Succeeded) { await SendOkAsync( new ChangePortraitResponse(blobUrl), ct); } else { await SendUnauthorizedAsync(ct); } } }