2020-06-29 04:44:35 +02:00
using System ;
2018-04-03 04:50:41 +02:00
using System.Linq ;
using System.Threading.Tasks ;
2020-11-17 13:46:23 +01:00
using BTCPayServer.Abstractions.Constants ;
using BTCPayServer.Abstractions.Extensions ;
using BTCPayServer.Abstractions.Models ;
2018-04-03 04:50:41 +02:00
using BTCPayServer.Data ;
using BTCPayServer.Models ;
using BTCPayServer.Models.AppViewModels ;
2018-08-30 20:16:24 +02:00
using BTCPayServer.Security ;
2018-08-22 10:26:49 +02:00
using BTCPayServer.Services.Apps ;
2019-04-28 08:27:10 +02:00
using BTCPayServer.Services.Mails ;
2019-02-17 08:53:41 +01:00
using BTCPayServer.Services.Rates ;
2018-08-30 20:16:24 +02:00
using Microsoft.AspNetCore.Authorization ;
2018-04-03 04:50:41 +02:00
using Microsoft.AspNetCore.Identity ;
using Microsoft.AspNetCore.Mvc ;
namespace BTCPayServer.Controllers
{
2019-10-12 13:35:30 +02:00
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie)]
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 ,
2018-08-30 20:16:24 +02:00
BTCPayNetworkProvider networkProvider ,
2019-02-17 08:53:41 +01:00
CurrencyNameTable currencies ,
2019-04-28 08:27:10 +02:00
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 ;
2018-08-14 23:47:41 +02:00
_NetworkProvider = networkProvider ;
2019-02-17 08:53:41 +01:00
_currencies = currencies ;
2019-04-28 08:27:10 +02:00
_emailSenderFactory = emailSenderFactory ;
2019-02-19 05:04:58 +01:00
_AppService = AppService ;
2018-04-03 04:50:41 +02:00
}
2018-08-30 20:16:24 +02:00
2020-06-29 05:07:48 +02:00
private readonly UserManager < ApplicationUser > _UserManager ;
private readonly ApplicationDbContextFactory _ContextFactory ;
2018-12-28 17:38:20 +01:00
private readonly EventAggregator _EventAggregator ;
2020-06-29 05:07:48 +02:00
private readonly BTCPayNetworkProvider _NetworkProvider ;
2019-02-17 08:53:41 +01:00
private readonly CurrencyNameTable _currencies ;
2019-04-28 08:27:10 +02:00
private readonly EmailSenderFactory _emailSenderFactory ;
2020-06-29 05:07:48 +02:00
private readonly AppService _AppService ;
2018-08-30 20:16:24 +02:00
2018-10-09 16:38:56 +02:00
public string CreatedAppId { get ; set ; }
2018-08-30 20:16:24 +02:00
2020-07-19 23:22:26 +02:00
public async Task < IActionResult > ListApps (
string sortOrder = null ,
string sortOrderColumn = null
)
2018-04-03 04:50:41 +02:00
{
2019-02-19 05:04:58 +01:00
var apps = await _AppService . GetAllApps ( GetUserId ( ) ) ;
2020-07-19 23:22:26 +02:00
if ( sortOrder ! = null & & sortOrderColumn ! = null )
{
apps = apps . OrderByDescending ( app = >
{
switch ( sortOrderColumn )
{
2020-07-21 05:02:14 +02:00
case nameof ( app . AppName ) :
2020-07-19 23:22:26 +02:00
return app . AppName ;
2020-07-21 05:02:14 +02:00
case nameof ( app . StoreName ) :
2020-07-19 23:22:26 +02:00
return app . StoreName ;
2020-07-21 05:02:14 +02:00
case nameof ( app . AppType ) :
2020-07-19 23:22:26 +02:00
return app . AppType ;
default :
return app . Id ;
}
} ) . ToArray ( ) ;
switch ( sortOrder )
{
case "desc" :
ViewData [ $"{sortOrderColumn}SortOrder" ] = "asc" ;
break ;
case "asc" :
apps = apps . Reverse ( ) . ToArray ( ) ;
ViewData [ $"{sortOrderColumn}SortOrder" ] = "desc" ;
break ;
}
}
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 ) )
2021-09-07 04:55:53 +02:00
TempData [ WellKnownTempData . SuccessMessage ] = "App deleted successfully." ;
2018-04-03 04:50:41 +02:00
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 )
{
2019-11-07 10:20:17 +01:00
TempData . SetStatusMessageModel ( new StatusMessageModel ( )
2019-01-29 08:44:46 +01:00
{
Html =
2020-04-05 19:17:49 +02:00
$"Error: You need to create at least one store. <a href='{(Url.Action(" CreateStore ", " UserStores "))}' class='alert-link'>Create store</a>" ,
2019-01-29 08:44:46 +01:00
Severity = StatusMessageModel . StatusSeverity . Error
2019-11-07 10:20:17 +01:00
} ) ;
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 )
{
2019-11-07 10:20:17 +01:00
TempData . SetStatusMessageModel ( new StatusMessageModel ( )
2019-01-29 08:44:46 +01:00
{
Html =
2020-04-05 19:17:49 +02:00
$"Error: You need to create at least one store. <a href='{(Url.Action(" CreateStore ", " UserStores "))}' class='alert-link'>Create store</a>" ,
2019-01-29 08:44:46 +01:00
Severity = StatusMessageModel . StatusSeverity . Error
2019-11-07 10:20:17 +01:00
} ) ;
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 ) )
{
2019-10-31 04:29:59 +01:00
TempData [ WellKnownTempData . ErrorMessage ] = "You are not owner of this store" ;
2018-04-03 04:50:41 +02:00
return RedirectToAction ( nameof ( ListApps ) ) ;
}
2019-09-02 15:37:52 +02:00
var appData = new AppData
2018-04-03 04:50:41 +02:00
{
2020-06-28 10:55:27 +02:00
StoreDataId = selectedStore ,
Name = vm . Name ,
2019-09-02 15:37:52 +02:00
AppType = appType . ToString ( )
} ;
await _AppService . UpdateOrCreateApp ( appData ) ;
2019-10-31 04:29:59 +01:00
TempData [ WellKnownTempData . SuccessMessage ] = "App successfully created" ;
2019-09-02 15:37:52 +02:00
CreatedAppId = appData . Id ;
2018-12-29 11:52:07 +01:00
switch ( appType )
{
case AppType . PointOfSale :
2019-09-02 15:37:52 +02:00
return RedirectToAction ( nameof ( UpdatePointOfSale ) , new { appId = appData . Id } ) ;
2018-12-29 11:52:07 +01:00
case AppType . Crowdfund :
2019-09-02 15:37:52 +02:00
return RedirectToAction ( nameof ( UpdateCrowdfund ) , new { appId = appData . Id } ) ;
2018-12-29 11:52:07 +01:00
default :
return RedirectToAction ( nameof ( ListApps ) ) ;
}
2018-04-03 04:50:41 +02:00
}
2021-09-07 04:55:53 +02:00
[HttpGet("{appId}/delete")]
2018-04-03 04:50:41 +02:00
public async Task < IActionResult > DeleteApp ( string appId )
{
var appData = await GetOwnedApp ( appId ) ;
if ( appData = = null )
return NotFound ( ) ;
2021-09-07 04:55:53 +02:00
return View ( "Confirm" , new ConfirmModel ( "Delete app" , $"The app <strong>{appData.Name}</strong> and its settings will be permanently deleted. Are you sure?" , "Delete" ) ) ;
2018-04-03 04:50:41 +02:00
}
2018-10-09 16:38:56 +02:00
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
}
private string GetUserId ( )
{
return _UserManager . GetUserId ( User ) ;
}
}
}