Add set and delete methods for the /users api

This commit is contained in:
Zoe Roux 2024-02-04 23:31:00 +01:00
parent 6787400056
commit 666477e448
3 changed files with 82 additions and 9 deletions

View File

@ -302,6 +302,27 @@ namespace Kyoo.Authentication.Views
}
}
/// <summary>
/// Get profile picture
/// </summary>
/// <remarks>
/// Get your profile picture
/// </remarks>
/// <response code="401">The user is not authenticated.</response>
/// <response code="403">The given access token is invalid.</response>
[HttpGet("me/logo")]
[UserOnly]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(RequestError))]
[ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(RequestError))]
public async Task<ActionResult> GetProfilePicture()
{
Stream img = await thumbs.GetUserImage(User.GetIdOrThrow());
// Allow clients to cache the image for 6 month.
Response.Headers.Add("Cache-Control", $"public, max-age={60 * 60 * 24 * 31 * 6}");
return File(img, "image/webp", true);
}
/// <summary>
/// Set profile picture
/// </summary>
@ -324,24 +345,22 @@ namespace Kyoo.Authentication.Views
}
/// <summary>
/// Get profile picture
/// Delete profile picture
/// </summary>
/// <remarks>
/// Get your profile picture
/// Delete your profile picture
/// </remarks>
/// <response code="401">The user is not authenticated.</response>
/// <response code="403">The given access token is invalid.</response>
[HttpGet("me/logo")]
[HttpDelete("me/logo")]
[UserOnly]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(RequestError))]
[ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(RequestError))]
public async Task<ActionResult> GetProfilePicture()
public async Task<ActionResult> DeleteProfilePicture()
{
Stream img = await thumbs.GetUserImage(User.GetIdOrThrow());
// Allow clients to cache the image for 6 month.
Response.Headers.Add("Cache-Control", $"public, max-age={60 * 60 * 24 * 31 * 6}");
return File(img, "image/webp", true);
await thumbs.SetUserImage(User.GetIdOrThrow(), null);
return NoContent();
}
}
}

View File

@ -245,6 +245,14 @@ namespace Kyoo.Core.Controllers
public async Task SetUserImage(Guid userId, Stream? image)
{
if (image == null)
{
try
{
File.Delete($"/metadata/user/{userId}.webp");
} catch { }
return;
}
using SKCodec codec = SKCodec.Create(image);
SKImageInfo info = codec.Info;
info.ColorType = SKColorType.Rgba8888;

View File

@ -67,5 +67,51 @@ public class UserApi(ILibraryManager libraryManager, IThumbnailsManager thumbs)
}
return File(img, "image/webp", true);
}
/// <summary>
/// Set profile picture
/// </summary>
/// <remarks>
/// Set user profile picture
/// </remarks>
[HttpPost("{identifier:id}/logo")]
[PartialPermission(Kind.Write)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(RequestError))]
[ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(RequestError))]
public async Task<ActionResult> SetProfilePicture(Identifier identifier, IFormFile picture)
{
if (picture == null || picture.Length == 0)
return BadRequest();
Guid gid = await identifier.Match(
id => Task.FromResult(id),
async slug => (await libraryManager.Users.Get(slug)).Id
);
await thumbs.SetUserImage(gid, picture.OpenReadStream());
return NoContent();
}
/// <summary>
/// Delete profile picture
/// </summary>
/// <remarks>
/// Delete your profile picture
/// </remarks>
/// <response code="401">The user is not authenticated.</response>
/// <response code="403">The given access token is invalid.</response>
[HttpDelete("{identifier:id}/logo")]
[PartialPermission(Kind.Delete)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(RequestError))]
[ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(RequestError))]
public async Task<ActionResult> DeleteProfilePicture(Identifier identifier)
{
Guid gid = await identifier.Match(
id => Task.FromResult(id),
async slug => (await libraryManager.Users.Get(slug)).Id
);
await thumbs.SetUserImage(gid, null);
return NoContent();
}
}