Greenfield: Add image upload for app items (#6226)

Upload endpoints for app item images. Follow-up to #6075.
Tested to work with the app item editor.

Uses UploadImage consistently in API and UI.
This commit is contained in:
d11n
2024-11-07 02:43:22 +01:00
committed by GitHub
parent 392ec623c0
commit a129114603
13 changed files with 239 additions and 128 deletions

View File

@@ -3,7 +3,9 @@ using System;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Constants;
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Abstractions.Models;
using BTCPayServer.Client;
using BTCPayServer.Client.Models;
using BTCPayServer.Data;
@@ -15,6 +17,7 @@ using BTCPayServer.Services.Rates;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
@@ -33,13 +36,14 @@ namespace BTCPayServer.Controllers.Greenfield
private readonly StoreRepository _storeRepository;
private readonly CurrencyNameTable _currencies;
private readonly UserManager<ApplicationUser> _userManager;
private readonly IFileService _fileService;
public GreenfieldAppsController(
AppService appService,
UriResolver uriResolver,
StoreRepository storeRepository,
BTCPayNetworkProvider btcPayNetworkProvider,
CurrencyNameTable currencies,
IFileService fileService,
UserManager<ApplicationUser> userManager
)
{
@@ -47,6 +51,7 @@ namespace BTCPayServer.Controllers.Greenfield
_uriResolver = uriResolver;
_storeRepository = storeRepository;
_currencies = currencies;
_fileService = fileService;
_userManager = userManager;
}
@@ -221,10 +226,7 @@ namespace BTCPayServer.Controllers.Greenfield
public async Task<IActionResult> DeleteApp(string appId)
{
var app = await _appService.GetApp(appId, null, includeArchived: true);
if (app == null)
{
return AppNotFound();
}
if (app == null) return AppNotFound();
await _appService.DeleteApp(app);
@@ -254,6 +256,57 @@ namespace BTCPayServer.Controllers.Greenfield
var items = stats.GetRange(offset, max);
return Ok(items);
}
[HttpPost("~/api/v1/apps/{appId}/image")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public async Task<IActionResult> UploadAppItemImage(string appId, IFormFile? file)
{
var app = await _appService.GetApp(appId, null, includeArchived: true);
var userId = _userManager.GetUserId(User);
if (app == null || userId == null) return AppNotFound();
UploadImageResultModel? upload = null;
if (file is null)
ModelState.AddModelError(nameof(file), "Invalid file");
else
{
upload = await _fileService.UploadImage(file, userId, 500_000);
if (!upload.Success)
ModelState.AddModelError(nameof(file), upload.Response);
}
if (!ModelState.IsValid)
return this.CreateValidationError(ModelState);
try
{
var storedFile = upload!.StoredFile!;
var fileData = new FileData
{
Id = storedFile.Id,
UserId = storedFile.ApplicationUserId,
Url = await _fileService.GetFileUrl(Request.GetAbsoluteRootUri(), storedFile.Id),
OriginalName = storedFile.FileName,
StorageName = storedFile.StorageFileName,
CreatedAt = storedFile.Timestamp
};
return Ok(fileData);
}
catch (Exception e)
{
return this.CreateAPIError(404, "file-upload-failed", e.Message);
}
}
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
[HttpDelete("~/api/v1/apps/{appId}/image/{fileId}")]
public async Task<IActionResult> DeleteAppItemImage(string appId, string fileId)
{
var app = await _appService.GetApp(appId, null, includeArchived: true);
var userId = _userManager.GetUserId(User);
if (app == null || userId == null) return AppNotFound();
if (!string.IsNullOrEmpty(fileId)) await _fileService.RemoveFile(fileId, userId);
return Ok();
}
private IActionResult AppNotFound()
{