reactredux/src/WeatherForecast/Controllers/ImageController.cs

279 lines
9.3 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using WeatherForecast.Services;
using DomainResults.Mvc;
using Core.Enumerations;
using DataProviders.Buckets;
using DomainResults.Common;
using WeatherForecast.Policies;
using DomainObjects.Documents.Users;
using WeatherForecast.Controllers.Abstractions;
namespace WeatherForecast.Controllers;
/// <summary>
///
/// </summary>
[Route("api/[controller]")]
public class ImageController : AuthorizationControllerBase {
private readonly IImageBucketDataProvider _imageBucketDataProvider;
private readonly IImageService _imageService;
/// <summary>
///
/// </summary>
/// <param name="authorizationService"></param>
/// <param name="imageBucketDataProvider"></param>
/// <param name="imgeService"></param>
public ImageController(
IAuthorizationService authorizationService,
IImageBucketDataProvider imageBucketDataProvider,
IImageService imgeService
) : base (authorizationService) {
_imageBucketDataProvider = imageBucketDataProvider;
_imageService = imgeService;
}
#region Post
/// <summary>
/// Site wide
/// <para>
/// Allowed: Admin, Shop Manager
/// </para>
/// </summary>
/// <param name="siteId"></param>
/// <param name="formFile"></param>
/// <returns></returns>
[HttpPost("{siteId}")]
public async Task<IActionResult> Post([FromRoute] Guid siteId, IFormFile formFile) =>
await PostCore(siteId, null, formFile);
/// <summary>
/// Site user specific
/// <para>
/// Allowed: Admin, Editor, Author, Contributor, Shop manager
/// </para>
/// </summary>
/// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="formFile"></param>
/// <returns></returns>
[HttpPost("{siteId}/{userId}")]
public async Task<IActionResult> Post([FromRoute] Guid siteId, [FromRoute] Guid userId, IFormFile formFile) =>
await PostCore(siteId, userId, formFile);
private async Task<IActionResult> PostCore(Guid siteId, Guid? userId, IFormFile formFile) {
if (!(formFile.Length > 0))
return IDomainResult.Failed().ToActionResult();
using var ms = new MemoryStream();
formFile.CopyTo(ms);
var newFile = new BucketFile(Guid.NewGuid(), siteId, formFile.FileName, ms.ToArray(), formFile.ContentType);
if (userId != null)
newFile.UserId = userId;
return await AuthorizeAsync(User, new ImageAuthorisationRequirement(CrudActions.Create, new List<ImageRole> {
new ImageRole(Roles.Admin),
new ImageRole(Roles.Editor),
new ImageRole(Roles.Author) { OwnOnly = true },
new ImageRole(Roles.Contributor) { OwnOnly = true },
new ImageRole(Roles.ShopManager)
}), newFile, () => {
var result = _imageService.Post(newFile);
return result.ToActionResult();
});
}
#endregion
#region Get
/// <summary>
/// Site user specific
/// <para>
/// Allowed: Admin, Editor, Author (own), Contributor (own), Shop manager
/// </para>
/// <see href="https://www.c-sharpcorner.com/article/fileresult-in-asp-net-core-mvc2/">fileresult-in-asp-net-core-mvc2</see>
/// </summary>
/// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="fileId"></param>
/// <returns></returns>
[HttpGet("{siteId}/{userId}/{fileId}")]
public async Task<IActionResult> Get([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] Guid fileId) {
var (file, result) = _imageBucketDataProvider.Download(siteId, userId, fileId);
if (!result.IsSuccess || file == null)
return result.ToActionResult();
return await AuthorizeAsync(User, new ImageAuthorisationRequirement(CrudActions.Read, new List<ImageRole> {
new ImageRole(Roles.Admin),
new ImageRole(Roles.Editor),
new ImageRole(Roles.Author) { OwnOnly = true },
new ImageRole(Roles.Contributor) { OwnOnly = true },
new ImageRole(Roles.ShopManager)
}), file, () => {
var stream = new MemoryStream(file.Bytes);
return new FileStreamResult(stream, file.ContentType) {
FileDownloadName = file.Name
};
});
}
/// <summary>
/// Site wide
/// <para>
/// Allowed everyone
/// </para>
/// </summary>
/// <param name="siteId"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="imageId"></param>
/// <returns></returns>
[HttpGet("{siteId}/{width}x{height}/{imageId}")]
public IActionResult Get([FromRoute] Guid siteId, [FromRoute] int width, [FromRoute] int height, [FromRoute] Guid imageId) {
var (file, result) = _imageService.Get(siteId, width, height, imageId);
if (!result.IsSuccess || file == null)
return result.ToActionResult();
var stream = new MemoryStream(file.Bytes);
return new FileStreamResult(stream, file.ContentType) {
FileDownloadName = file.Name
};
}
/// <summary>
/// Site wide
/// <para>
/// Allowed everyone
/// </para>
/// </summary>
/// <param name="siteId"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="background"></param>
/// <param name="foreground"></param>
/// <returns></returns>
[HttpGet("{width}x{height}/{background}/{foreground}")]
public IActionResult Get([FromRoute] int width, [FromRoute] int height, [FromRoute] string background, [FromRoute] string foreground) {
var (file, result) = _imageService.Get(width, height, background, foreground);
if (!result.IsSuccess || file == null)
return result.ToActionResult();
var stream = new MemoryStream(file.Bytes);
return new FileStreamResult(stream, file.ContentType) {
FileDownloadName = file.Name
};
}
#endregion
#region Update
/// <summary>
/// Site specific
/// <para>
/// Allowed Admin, Shop Manager
/// </para>
/// </summary>
/// <param name="siteId"></param>
/// <param name="fileId"></param>
/// <param name="formFile"></param>
/// <returns></returns>
[HttpPost("{siteId}/{fileId}")]
public async Task<IActionResult> Update([FromRoute] Guid siteId, [FromRoute] Guid fileId, IFormFile formFile) =>
await UpdateCore(siteId, null, fileId, formFile);
/// <summary>
/// Site user specific
/// <para>
/// Can Admin, Editor, Author (own), Contributor (own, not yet pubblished), Shop manager
/// </para>
/// </summary>
/// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="fileId"></param>
/// <param name="formFile"></param>
/// <returns></returns>
[HttpPost("{siteId}/{userId}/{fileId}")]
public async Task<IActionResult> Update([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] Guid fileId, IFormFile formFile) =>
await UpdateCore(siteId, userId, fileId, formFile);
private async Task<IActionResult> UpdateCore(Guid siteId, Guid? userId, Guid fileId, IFormFile formFile) {
var (file, getFileResult) = _imageBucketDataProvider.Download(siteId, userId, fileId);
if (!getFileResult.IsSuccess || file == null)
return getFileResult.ToActionResult();
if (!(formFile.Length > 0))
return IDomainResult.Failed().ToActionResult();
using var ms = new MemoryStream();
formFile.CopyTo(ms);
var newFile = new BucketFile(fileId, siteId, formFile.FileName, ms.ToArray(), formFile.ContentType);
if(userId != null)
newFile.UserId = userId;
return await AuthorizeAsync(User, new ImageAuthorisationRequirement(CrudActions.Update, new List<ImageRole> {
new ImageRole(Roles.Admin),
new ImageRole(Roles.Editor),
new ImageRole(Roles.Author) { OwnOnly = true },
new ImageRole(Roles.Contributor) { OwnOnly = true, DenyPublished = true },
new ImageRole(Roles.ShopManager)
}), file, () => {
var result = _imageService.Update(siteId, userId, fileId, newFile);
return result.ToActionResult();
});
}
#endregion
#region Delete
/// <summary>
/// Cross site media
/// Can Admin, Shop manager
/// </summary>
/// <param name="siteId"></param>
/// <param name="fileId"></param>
/// <returns></returns>
[HttpDelete("{siteId}/{fileId}")]
public async Task<IActionResult> Delete([FromRoute] Guid siteId, [FromRoute] Guid fileId) =>
await DeleteCore(siteId, null, fileId);
/// <summary>
/// Can Admin, Editor, Author (own), Contributor (own, not yet pubblished), Shop manager
/// </summary>
/// <param name="siteId"></param>
/// <param name="userId"></param>
/// <param name="fileId"></param>
/// <returns></returns>
[HttpDelete("{siteId}/{userId}/{fileId}")]
public async Task<IActionResult> Delete([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] Guid fileId) =>
await DeleteCore(siteId, userId, fileId);
private async Task<IActionResult> DeleteCore(Guid siteId, Guid? userId, Guid fileId) {
var (file, fileDownloadResult) = _imageBucketDataProvider.Download(siteId, userId, fileId);
if (!fileDownloadResult.IsSuccess || file == null)
return fileDownloadResult.ToActionResult();
return await AuthorizeAsync(User, new ImageAuthorisationRequirement(CrudActions.Delete, new List<ImageRole> {
new ImageRole(Roles.Admin),
new ImageRole(Roles.Editor),
new ImageRole(Roles.Author) { OwnOnly = true },
new ImageRole(Roles.Contributor) { OwnOnly = true, DenyPublished = true },
new ImageRole(Roles.ShopManager)
}), file, () => {
var result = _imageService.Delete(siteId, userId, fileId);
return result.ToActionResult();
});
}
#endregion
}