This commit is contained in:
222
server/Controllers/LogoController.cs
Normal file
222
server/Controllers/LogoController.cs
Normal file
@@ -0,0 +1,222 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using Sockeye.Models;
|
||||
using Sockeye.Api.ControllerHelpers;
|
||||
using Sockeye.Biz;
|
||||
using Sockeye.Util;
|
||||
using System.IO;
|
||||
|
||||
|
||||
namespace Sockeye.Api.Controllers
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Logo controller
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[ApiVersion("8.0")]
|
||||
[Route("api/v{version:apiVersion}/logo")]
|
||||
[Produces("application/json")]
|
||||
[Authorize]
|
||||
public class LogoController : ControllerBase
|
||||
{
|
||||
private readonly AyContext ct;
|
||||
private readonly ILogger<LogoController> log;
|
||||
private readonly ApiServerState serverState;
|
||||
// private const int MAXIMUM_LOGO_SIZE = 512000;//We really don't want it too big or it will slow the fuck down for everything
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="dbcontext"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="apiServerState"></param>
|
||||
public LogoController(AyContext dbcontext, ILogger<LogoController> logger, ApiServerState apiServerState)
|
||||
{
|
||||
ct = dbcontext;
|
||||
log = logger;
|
||||
serverState = apiServerState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get Logo
|
||||
/// </summary>
|
||||
/// <param name="size">One of "small", "medium", "large"</param>
|
||||
/// <returns>A single Logo and it's values</returns>
|
||||
[AllowAnonymous]
|
||||
[HttpGet("{size}")]
|
||||
public async Task<IActionResult> DownloadLogo([FromRoute] string size)
|
||||
{
|
||||
//allowing this because it messes up the login form needlessly
|
||||
// if (serverState.IsClosed)
|
||||
// return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
||||
if (!ModelState.IsValid)
|
||||
return BadRequest(new ApiErrorResponse(ModelState));
|
||||
|
||||
if (string.IsNullOrWhiteSpace(size))
|
||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, "size", "Size is required and must be one of 'small', 'medium' or 'large'"));
|
||||
|
||||
size = size.ToLowerInvariant();
|
||||
if (size != "small" && size != "medium" && size != "large")
|
||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_INVALID_VALUE, "size", "Size parameter must be one of 'small', 'medium' or 'large'"));
|
||||
|
||||
var logo = await ct.Logo.SingleOrDefaultAsync();
|
||||
if (logo == null)
|
||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
||||
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case "small":
|
||||
if (logo.Small == null)
|
||||
return NotFound();
|
||||
return new FileStreamResult(new MemoryStream(logo.Small), Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(logo.SmallType));
|
||||
|
||||
case "medium":
|
||||
if (logo.Medium == null)
|
||||
return NotFound();
|
||||
return new FileStreamResult(new MemoryStream(logo.Medium), Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(logo.MediumType));
|
||||
|
||||
case "large":
|
||||
if (logo.Large == null)
|
||||
return NotFound();
|
||||
return new FileStreamResult(new MemoryStream(logo.Large), Microsoft.Net.Http.Headers.MediaTypeHeaderValue.Parse(logo.LargeType));
|
||||
}
|
||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Upload Logo
|
||||
/// Max 500 KiB total (512000 bytes)
|
||||
/// Must have full rights to Global object
|
||||
/// </summary>
|
||||
/// <param name="size">One of "small", "medium", "large"</param>
|
||||
/// <returns>Accepted</returns>
|
||||
[Authorize]
|
||||
[HttpPost("{size}")]
|
||||
//[DisableFormValueModelBinding]
|
||||
[RequestSizeLimit(ServerBootConfig.MAX_LOGO_UPLOAD_BYTES)]
|
||||
public async Task<IActionResult> UploadAsync([FromRoute] string size)
|
||||
{
|
||||
|
||||
//https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-3.1#upload-small-files-with-buffered-model-binding-to-a-database
|
||||
|
||||
if (!serverState.IsOpen)
|
||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
||||
|
||||
if (!Authorized.HasReadFullRole(HttpContext.Items, SockType.Global))
|
||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||
|
||||
if (string.IsNullOrWhiteSpace(size))
|
||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, "size", "Size is required and must be one of 'small', 'medium' or 'large'"));
|
||||
|
||||
size = size.ToLowerInvariant();
|
||||
if (size != "small" && size != "medium" && size != "large")
|
||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_INVALID_VALUE, "size", "Size parameter must be one of 'small', 'medium' or 'large'"));
|
||||
|
||||
//get the one and only logo object
|
||||
var logo = await ct.Logo.FirstOrDefaultAsync();
|
||||
if (logo == null)
|
||||
{
|
||||
logo = new Logo();
|
||||
ct.Logo.Add(logo);
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
var file = Request.Form.Files[0];
|
||||
|
||||
//var file=files[0];
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await file.CopyToAsync(memoryStream);
|
||||
if (memoryStream.Length > ServerBootConfig.MAX_LOGO_UPLOAD_BYTES)
|
||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_LENGTH_EXCEEDED, null, $"Logo files must be smaller than {ServerBootConfig.MAX_LOGO_UPLOAD_BYTES} maximum"));
|
||||
switch (size)
|
||||
{
|
||||
case "small":
|
||||
logo.Small = memoryStream.ToArray();
|
||||
logo.SmallType = file.ContentType;
|
||||
break;
|
||||
case "medium":
|
||||
logo.Medium = memoryStream.ToArray();
|
||||
logo.MediumType = file.ContentType;
|
||||
break;
|
||||
case "large":
|
||||
logo.Large = memoryStream.ToArray();
|
||||
logo.LargeType = file.ContentType;
|
||||
break;
|
||||
|
||||
}
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
return Accepted();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Delete logo
|
||||
/// </summary>
|
||||
/// <param name="size"></param>
|
||||
/// <returns>NoContent</returns>
|
||||
[Authorize]
|
||||
[HttpDelete("{size}")]
|
||||
public async Task<IActionResult> DeleteLogo([FromRoute] string size)
|
||||
{
|
||||
if (!serverState.IsOpen)
|
||||
return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason));
|
||||
|
||||
if (!Authorized.HasReadFullRole(HttpContext.Items, SockType.Global))
|
||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||
|
||||
if (string.IsNullOrWhiteSpace(size))
|
||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_REQUIRED, "size", "Size is required and must be one of 'small', 'medium' or 'large'"));
|
||||
|
||||
size = size.ToLowerInvariant();
|
||||
if (size != "small" && size != "medium" && size != "large")
|
||||
return BadRequest(new ApiErrorResponse(ApiErrorCode.VALIDATION_INVALID_VALUE, "size", "Size parameter must be one of 'small', 'medium' or 'large'"));
|
||||
|
||||
//get the one and only logo object
|
||||
var logo = await ct.Logo.FirstOrDefaultAsync();
|
||||
if (logo != null)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case "small":
|
||||
logo.Small = null;
|
||||
logo.SmallType = string.Empty;
|
||||
break;
|
||||
case "medium":
|
||||
logo.Medium = null;
|
||||
logo.MediumType = string.Empty;
|
||||
break;
|
||||
case "large":
|
||||
logo.Large = null;
|
||||
logo.LargeType = string.Empty;
|
||||
break;
|
||||
|
||||
}
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user