btcpayserver/BTCPayServer/Controllers/AppsController.cs

187 lines
6.6 KiB
C#
Raw Normal View History

2018-04-03 04:50:41 +02:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Data;
using BTCPayServer.Models;
using BTCPayServer.Models.AppViewModels;
using BTCPayServer.Security;
2018-08-22 10:26:49 +02:00
using BTCPayServer.Services.Apps;
using BTCPayServer.Services.Mails;
using BTCPayServer.Services.Rates;
using Ganss.XSS;
using Microsoft.AspNetCore.Authorization;
2018-04-03 04:50:41 +02:00
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
2018-08-22 10:26:49 +02:00
using Microsoft.EntityFrameworkCore;
2018-04-03 04:50:41 +02:00
using NBitcoin;
2018-08-22 10:26:49 +02:00
using NBitcoin.DataEncoders;
2018-04-03 04:50:41 +02:00
namespace BTCPayServer.Controllers
{
[Authorize(AuthenticationSchemes = Policies.CookieAuthentication)]
2018-04-03 04:50:41 +02:00
[AutoValidateAntiforgeryToken]
[Route("apps")]
public partial class AppsController : Controller
{
public AppsController(
UserManager<ApplicationUser> userManager,
ApplicationDbContextFactory contextFactory,
2018-12-28 17:38:20 +01:00
EventAggregator eventAggregator,
BTCPayNetworkProvider networkProvider,
CurrencyNameTable currencies,
EmailSenderFactory emailSenderFactory,
2019-02-19 05:04:58 +01:00
AppService AppService)
2018-04-03 04:50:41 +02:00
{
_UserManager = userManager;
_ContextFactory = contextFactory;
2018-12-28 17:38:20 +01:00
_EventAggregator = eventAggregator;
_NetworkProvider = networkProvider;
_currencies = currencies;
_emailSenderFactory = emailSenderFactory;
2019-02-19 05:04:58 +01:00
_AppService = AppService;
2018-04-03 04:50:41 +02:00
}
private UserManager<ApplicationUser> _UserManager;
private ApplicationDbContextFactory _ContextFactory;
2018-12-28 17:38:20 +01:00
private readonly EventAggregator _EventAggregator;
private BTCPayNetworkProvider _NetworkProvider;
private readonly CurrencyNameTable _currencies;
private readonly EmailSenderFactory _emailSenderFactory;
2019-02-19 05:04:58 +01:00
private AppService _AppService;
[TempData]
public string StatusMessage { get; set; }
public string CreatedAppId { get; set; }
2018-04-03 04:50:41 +02:00
public async Task<IActionResult> ListApps()
{
2019-02-19 05:04:58 +01:00
var apps = await _AppService.GetAllApps(GetUserId());
2018-04-03 04:50:41 +02:00
return View(new ListAppsViewModel()
{
Apps = apps
});
}
[HttpPost]
[Route("{appId}/delete")]
public async Task<IActionResult> DeleteAppPost(string appId)
{
var appData = await GetOwnedApp(appId);
if (appData == null)
return NotFound();
2019-02-19 05:04:58 +01:00
if (await _AppService.DeleteApp(appData))
2018-04-03 04:50:41 +02:00
StatusMessage = "App removed successfully";
return RedirectToAction(nameof(ListApps));
}
[HttpGet]
[Route("create")]
public async Task<IActionResult> CreateApp()
{
2019-02-19 05:04:58 +01:00
var stores = await _AppService.GetOwnedStores(GetUserId());
2018-04-03 04:50:41 +02:00
if (stores.Length == 0)
{
StatusMessage = new StatusMessageModel()
{
Html =
$"Error: You need to create at least one store. <a href='{(Url.Action("CreateStore", "UserStores"))}'>Create store</a>",
Severity = StatusMessageModel.StatusSeverity.Error
}.ToString();
2018-04-03 04:50:41 +02:00
return RedirectToAction(nameof(ListApps));
}
var vm = new CreateAppViewModel();
vm.SetStores(stores);
return View(vm);
}
[HttpPost]
[Route("create")]
public async Task<IActionResult> CreateApp(CreateAppViewModel vm)
{
2019-02-19 05:04:58 +01:00
var stores = await _AppService.GetOwnedStores(GetUserId());
2018-04-03 04:50:41 +02:00
if (stores.Length == 0)
{
StatusMessage = new StatusMessageModel()
{
Html =
$"Error: You need to create at least one store. <a href='{(Url.Action("CreateStore", "UserStores"))}'>Create store</a>",
Severity = StatusMessageModel.StatusSeverity.Error
}.ToString();
2018-04-03 04:50:41 +02:00
return RedirectToAction(nameof(ListApps));
}
var selectedStore = vm.SelectedStore;
vm.SetStores(stores);
vm.SelectedStore = selectedStore;
if (!Enum.TryParse<AppType>(vm.SelectedAppType, out AppType appType))
ModelState.AddModelError(nameof(vm.SelectedAppType), "Invalid App Type");
if (!ModelState.IsValid)
{
return View(vm);
}
if (!stores.Any(s => s.Id == selectedStore))
{
StatusMessage = "Error: You are not owner of this store";
return RedirectToAction(nameof(ListApps));
}
var id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(20));
2018-04-03 04:50:41 +02:00
using (var ctx = _ContextFactory.CreateContext())
{
var appData = new AppData() { Id = id };
appData.StoreDataId = selectedStore;
appData.Name = vm.Name;
appData.AppType = appType.ToString();
ctx.Apps.Add(appData);
await ctx.SaveChangesAsync();
}
StatusMessage = "App successfully created";
CreatedAppId = id;
2018-12-29 11:52:07 +01:00
switch (appType)
{
case AppType.PointOfSale:
return RedirectToAction(nameof(UpdatePointOfSale), new { appId = id });
case AppType.Crowdfund:
return RedirectToAction(nameof(UpdateCrowdfund), new { appId = id });
default:
return RedirectToAction(nameof(ListApps));
}
2018-04-03 04:50:41 +02:00
}
[HttpGet]
[Route("{appId}/delete")]
public async Task<IActionResult> DeleteApp(string appId)
{
var appData = await GetOwnedApp(appId);
if (appData == null)
return NotFound();
return View("Confirm", new ConfirmModel()
{
Title = $"Delete app {appData.Name} ({appData.AppType})",
Description = "This app will be removed from this store",
Action = "Delete"
});
}
private Task<AppData> GetOwnedApp(string appId, AppType? type = null)
2018-04-03 04:50:41 +02:00
{
2019-02-19 05:04:58 +01:00
return _AppService.GetAppDataIfOwner(GetUserId(), appId, type);
2018-04-03 04:50:41 +02:00
}
2019-01-05 19:47:39 +01:00
2018-04-03 04:50:41 +02:00
private string GetUserId()
{
return _UserManager.GetUserId(User);
}
private async Task<bool> IsEmailConfigured(string storeId)
{
return (await (_emailSenderFactory.GetEmailSender(storeId) as EmailSender)?.GetEmailSettings())?.IsComplete() is true;
}
2018-04-03 04:50:41 +02:00
}
}