mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-20 02:28:31 +01:00
95b9e4dfd9
* Add basic Greenfield API Get and Delete operations for apps Will follow-up with PATCH and also with GET which returns more than just basic data later. This sets up the basic stuff first. * Add methods to LocalBTCPayServerClient
153 lines
5.6 KiB
C#
153 lines
5.6 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using BTCPayServer.Abstractions.Constants;
|
|
using BTCPayServer.Client;
|
|
using BTCPayServer.Client.Models;
|
|
using BTCPayServer.Data;
|
|
using BTCPayServer.Services.Apps;
|
|
using BTCPayServer.Services.Stores;
|
|
using BTCPayServer.Abstractions.Extensions;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Cors;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace BTCPayServer.Controllers.Greenfield
|
|
{
|
|
[ApiController]
|
|
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
|
[EnableCors(CorsPolicies.All)]
|
|
public class GreenfieldAppsController : ControllerBase
|
|
{
|
|
private readonly AppService _appService;
|
|
private readonly StoreRepository _storeRepository;
|
|
|
|
public GreenfieldAppsController(
|
|
AppService appService,
|
|
StoreRepository storeRepository,
|
|
UserManager<ApplicationUser> userManager,
|
|
BTCPayNetworkProvider btcPayNetworkProvider
|
|
)
|
|
{
|
|
_appService = appService;
|
|
_storeRepository = storeRepository;
|
|
}
|
|
|
|
[HttpPost("~/api/v1/stores/{storeId}/apps/pos")]
|
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
|
public async Task<IActionResult> CreatePointOfSaleApp(string storeId, CreatePointOfSaleAppRequest request)
|
|
{
|
|
var validationResult = Validate(request);
|
|
if (validationResult != null)
|
|
{
|
|
return validationResult;
|
|
}
|
|
|
|
var store = await _storeRepository.FindStore(storeId);
|
|
if (store == null)
|
|
return this.CreateAPIError(404, "store-not-found", "The store was not found");
|
|
|
|
var defaultCurrency = store.GetStoreBlob().DefaultCurrency;
|
|
var appData = new AppData
|
|
{
|
|
StoreDataId = storeId,
|
|
Name = request.AppName,
|
|
AppType = AppType.PointOfSale.ToString()
|
|
};
|
|
|
|
appData.SetSettings(new PointOfSaleSettings
|
|
{
|
|
Title = request.Title,
|
|
DefaultView = (Services.Apps.PosViewType)request.DefaultView,
|
|
ShowCustomAmount = request.ShowCustomAmount,
|
|
ShowDiscount = request.ShowDiscount,
|
|
EnableTips = request.EnableTips,
|
|
Currency = request.Currency ?? defaultCurrency,
|
|
Template = request.Template,
|
|
ButtonText = request.FixedAmountPayButtonText ?? PointOfSaleSettings.BUTTON_TEXT_DEF,
|
|
CustomButtonText = request.CustomAmountPayButtonText ?? PointOfSaleSettings.CUSTOM_BUTTON_TEXT_DEF,
|
|
CustomTipText = request.TipText ?? PointOfSaleSettings.CUSTOM_TIP_TEXT_DEF,
|
|
CustomCSSLink = request.CustomCSSLink,
|
|
NotificationUrl = request.NotificationUrl,
|
|
RedirectUrl = request.RedirectUrl,
|
|
Description = request.Description,
|
|
EmbeddedCSS = request.EmbeddedCSS,
|
|
RedirectAutomatically = request.RedirectAutomatically,
|
|
RequiresRefundEmail = request.RequiresRefundEmail == true ?
|
|
RequiresRefundEmail.On :
|
|
request.RequiresRefundEmail == false ?
|
|
RequiresRefundEmail.Off :
|
|
RequiresRefundEmail.InheritFromStore,
|
|
});
|
|
|
|
await _appService.UpdateOrCreateApp(appData);
|
|
|
|
return Ok(ToModel(appData));
|
|
}
|
|
|
|
[HttpGet("~/api/v1/apps/{appId}")]
|
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
|
public async Task<IActionResult> GetApp(string appId)
|
|
{
|
|
var app = await _appService.GetApp(appId, AppType.PointOfSale);
|
|
if (app == null)
|
|
{
|
|
return AppNotFound();
|
|
}
|
|
|
|
return Ok(ToModel(app));
|
|
}
|
|
|
|
[HttpDelete("~/api/v1/apps/{appId}")]
|
|
public async Task<IActionResult> DeleteApp(string appId)
|
|
{
|
|
var app = await _appService.GetApp(appId, null);
|
|
if (app == null)
|
|
{
|
|
return AppNotFound();
|
|
}
|
|
|
|
await _appService.DeleteApp(app);
|
|
|
|
return Ok();
|
|
}
|
|
|
|
private IActionResult AppNotFound()
|
|
{
|
|
return this.CreateAPIError(404, "app-not-found", "The app with specified ID was not found");
|
|
}
|
|
|
|
private PointOfSaleAppData ToModel(AppData appData)
|
|
{
|
|
return new PointOfSaleAppData
|
|
{
|
|
Id = appData.Id,
|
|
AppType = appData.AppType,
|
|
Name = appData.Name,
|
|
StoreId = appData.StoreDataId,
|
|
Created = appData.Created
|
|
};
|
|
}
|
|
|
|
private IActionResult? Validate(CreateAppRequest request)
|
|
{
|
|
if (request is null)
|
|
{
|
|
return BadRequest();
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(request.AppName))
|
|
{
|
|
ModelState.AddModelError(nameof(request.AppName), "App name is missing");
|
|
}
|
|
else if (request.AppName.Length < 1 || request.AppName.Length > 50)
|
|
{
|
|
ModelState.AddModelError(nameof(request.AppName), "Name can only be between 1 and 50 characters");
|
|
}
|
|
|
|
return !ModelState.IsValid ? this.CreateValidationError(ModelState) : null;
|
|
}
|
|
}
|
|
}
|