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; /// /// /// [Route("api/[controller]")] public class ImageController : AuthorizationControllerBase { private readonly IImageBucketDataProvider _imageBucketDataProvider; private readonly IImageService _imageService; /// /// /// /// /// /// public ImageController( IAuthorizationService authorizationService, IImageBucketDataProvider imageBucketDataProvider, IImageService imgeService ) : base (authorizationService) { _imageBucketDataProvider = imageBucketDataProvider; _imageService = imgeService; } #region Post /// /// Site wide /// /// Allowed: Admin, Shop Manager /// /// /// /// /// [HttpPost("{siteId}")] public async Task Post([FromRoute] Guid siteId, IFormFile formFile) => await PostCore(siteId, null, formFile); /// /// Site user specific /// /// Allowed: Admin, Editor, Author, Contributor, Shop manager /// /// /// /// /// /// [HttpPost("{siteId}/{userId}")] public async Task Post([FromRoute] Guid siteId, [FromRoute] Guid userId, IFormFile formFile) => await PostCore(siteId, userId, formFile); private async Task 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 { 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 /// /// Site user specific /// /// Allowed: Admin, Editor, Author (own), Contributor (own), Shop manager /// /// fileresult-in-asp-net-core-mvc2 /// /// /// /// /// [HttpGet("{siteId}/{userId}/{fileId}")] public async Task 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 { 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 }; }); } /// /// Site wide /// /// Allowed everyone /// /// /// /// /// /// /// [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 }; } /// /// Site wide /// /// Allowed everyone /// /// /// /// /// /// /// /// [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 /// /// Site specific /// /// Allowed Admin, Shop Manager /// /// /// /// /// /// [HttpPost("{siteId}/{fileId}")] public async Task Update([FromRoute] Guid siteId, [FromRoute] Guid fileId, IFormFile formFile) => await UpdateCore(siteId, null, fileId, formFile); /// /// Site user specific /// /// Can Admin, Editor, Author (own), Contributor (own, not yet pubblished), Shop manager /// /// /// /// /// /// /// [HttpPost("{siteId}/{userId}/{fileId}")] public async Task Update([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] Guid fileId, IFormFile formFile) => await UpdateCore(siteId, userId, fileId, formFile); private async Task 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 { 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 /// /// Cross site media /// Can Admin, Shop manager /// /// /// /// [HttpDelete("{siteId}/{fileId}")] public async Task Delete([FromRoute] Guid siteId, [FromRoute] Guid fileId) => await DeleteCore(siteId, null, fileId); /// /// Can Admin, Editor, Author (own), Contributor (own, not yet pubblished), Shop manager /// /// /// /// /// [HttpDelete("{siteId}/{userId}/{fileId}")] public async Task Delete([FromRoute] Guid siteId, [FromRoute] Guid userId, [FromRoute] Guid fileId) => await DeleteCore(siteId, userId, fileId); private async Task 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 { 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 }