protect contrib endpoint when needed

This commit is contained in:
Kukks
2019-01-02 11:29:47 +01:00
parent 5a3f7b5b70
commit bfec722312
4 changed files with 39 additions and 34 deletions

View File

@@ -107,14 +107,32 @@ namespace BTCPayServer.Controllers
public async Task<IActionResult> ContributeToCrowdfund(string appId, ContributeToCrowdfund request) public async Task<IActionResult> ContributeToCrowdfund(string appId, ContributeToCrowdfund request)
{ {
var app = await _AppsHelper.GetApp(appId, AppType.Crowdfund, true); var app = await _AppsHelper.GetApp(appId, AppType.Crowdfund, true);
if (app == null ||
(!app.GetSettings<CrowdfundSettings>().Enabled && if (app == null)
_AppsHelper.GetAppDataIfOwner(GetUserId(), appId, AppType.Crowdfund) == null))
return NotFound(); return NotFound();
var settings = app.GetSettings<CrowdfundSettings>(); var settings = app.GetSettings<CrowdfundSettings>();
var isAdmin = false;
if (!settings.Enabled)
{
isAdmin = await _AppsHelper.GetAppDataIfOwner(GetUserId(), appId, AppType.Crowdfund) == null;
if(!isAdmin)
return NotFound();
}
var info = await _CrowdfundHubStreamer.GetCrowdfundInfo(appId);
if(!isAdmin &&
((settings.StartDate.HasValue && DateTime.Now < settings.StartDate) ||
(settings.EndDate.HasValue && DateTime.Now > settings.EndDate) ||
(settings.EnforceTargetAmount && (info.Info.PendingProgressPercentage.GetValueOrDefault(0) + info.Info.ProgressPercentage.GetValueOrDefault(0)) >= 100)))
{
return NotFound();
}
var store = await _AppsHelper.GetStore(app); var store = await _AppsHelper.GetStore(app);
string title = null; var title = settings.Title;
var price = 0.0m; var price = request.Amount;
if (!string.IsNullOrEmpty(request.ChoiceKey)) if (!string.IsNullOrEmpty(request.ChoiceKey))
{ {
var choices = _AppsHelper.Parse(settings.PerksTemplate, settings.TargetCurrency); var choices = _AppsHelper.Parse(settings.PerksTemplate, settings.TargetCurrency);
@@ -126,12 +144,6 @@ namespace BTCPayServer.Controllers
if (request.Amount > price) if (request.Amount > price)
price = request.Amount; price = request.Amount;
} }
else
{
price = request.Amount;
title = settings.Title;
}
store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id)); store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id));
var invoice = await _InvoiceController.CreateInvoiceCore(new Invoice() var invoice = await _InvoiceController.CreateInvoiceCore(new Invoice()

View File

@@ -28,8 +28,6 @@ namespace BTCPayServer.Hubs
private readonly RateFetcher _RateFetcher; private readonly RateFetcher _RateFetcher;
private readonly BTCPayNetworkProvider _BtcPayNetworkProvider; private readonly BTCPayNetworkProvider _BtcPayNetworkProvider;
private readonly InvoiceRepository _InvoiceRepository; private readonly InvoiceRepository _InvoiceRepository;
private Dictionary<string, CancellationTokenSource> _CacheTokens = new Dictionary<string, CancellationTokenSource>();
public CrowdfundHubStreamer(EventAggregator eventAggregator, public CrowdfundHubStreamer(EventAggregator eventAggregator,
IHubContext<CrowdfundHub> hubContext, IHubContext<CrowdfundHub> hubContext,
IMemoryCache memoryCache, IMemoryCache memoryCache,
@@ -50,20 +48,12 @@ namespace BTCPayServer.Hubs
public Task<ViewCrowdfundViewModel> GetCrowdfundInfo(string appId) public Task<ViewCrowdfundViewModel> GetCrowdfundInfo(string appId)
{ {
var key = GetCacheKey(appId); return _MemoryCache.GetOrCreateAsync(GetCacheKey(appId), async entry =>
return _MemoryCache.GetOrCreateAsync(key, async entry =>
{ {
if (_CacheTokens.ContainsKey(key))
{
_CacheTokens.Remove(key);
}
var app = await _AppsHelper.GetApp(appId, AppType.Crowdfund, true); var app = await _AppsHelper.GetApp(appId, AppType.Crowdfund, true);
var result = await GetInfo(app); var result = await GetInfo(app);
entry.SetValue(result); entry.SetValue(result);
var token = new CancellationTokenSource();
_CacheTokens.Add(key, token);
entry.AddExpirationToken(new CancellationChangeToken(token.Token));
TimeSpan? expire = null; TimeSpan? expire = null;
if (result.StartDate.HasValue && result.StartDate < DateTime.Now) if (result.StartDate.HasValue && result.StartDate < DateTime.Now)
@@ -87,7 +77,7 @@ namespace BTCPayServer.Hubs
private void SubscribeToEvents() private void SubscribeToEvents()
{ {
_EventAggregator.Subscribe<InvoiceEvent>(Subscription); _EventAggregator.Subscribe<InvoiceEvent>(OnInvoiceEvent);
_EventAggregator.Subscribe<AppsController.CrowdfundAppUpdated>(updated => _EventAggregator.Subscribe<AppsController.CrowdfundAppUpdated>(updated =>
{ {
InvalidateCacheForApp(updated.AppId); InvalidateCacheForApp(updated.AppId);
@@ -99,7 +89,7 @@ namespace BTCPayServer.Hubs
return $"{CrowdfundInvoiceOrderIdPrefix}:{appId}"; return $"{CrowdfundInvoiceOrderIdPrefix}:{appId}";
} }
private void Subscription(InvoiceEvent invoiceEvent) private void OnInvoiceEvent(InvoiceEvent invoiceEvent)
{ {
if (!invoiceEvent.Invoice.OrderId.StartsWith(CrowdfundInvoiceOrderIdPrefix, StringComparison.InvariantCultureIgnoreCase)) if (!invoiceEvent.Invoice.OrderId.StartsWith(CrowdfundInvoiceOrderIdPrefix, StringComparison.InvariantCultureIgnoreCase))
{ {
@@ -128,10 +118,7 @@ namespace BTCPayServer.Hubs
private void InvalidateCacheForApp(string appId) private void InvalidateCacheForApp(string appId)
{ {
if (_CacheTokens.ContainsKey(appId)) _MemoryCache.Remove(GetCacheKey(appId));
{
_CacheTokens[appId].Cancel();
}
GetCrowdfundInfo(appId).ContinueWith(task => GetCrowdfundInfo(appId).ContinueWith(task =>
{ {
@@ -210,8 +197,8 @@ namespace BTCPayServer.Hubs
EmbeddedCSS = settings.EmbeddedCSS, EmbeddedCSS = settings.EmbeddedCSS,
StoreId = appData.StoreDataId, StoreId = appData.StoreDataId,
AppId = appData.Id, AppId = appData.Id,
StartDate = settings.StartDate, StartDate = settings.StartDate?.ToUniversalTime(),
EndDate = settings.EndDate, EndDate = settings.EndDate?.ToUniversalTime(),
TargetAmount = settings.TargetAmount, TargetAmount = settings.TargetAmount,
TargetCurrency = settings.TargetCurrency, TargetCurrency = settings.TargetCurrency,
EnforceTargetAmount = settings.EnforceTargetAmount, EnforceTargetAmount = settings.EnforceTargetAmount,

View File

@@ -197,8 +197,8 @@
</script> </script>
<script type="text/x-template" id="perk-template"> <script type="text/x-template" id="perk-template">
<div class="card mb-4 perk" v-bind:class="{ 'expanded': expanded, 'unexpanded': !expanded }" v-on:click="expand"> <div class="card mb-4 perk" v-bind:class="{ 'expanded': expanded, 'unexpanded': !expanded }" v-on:click="expand" :id="perk.id">
<div class="perk-zoom " v-if="!expanded && active"> <div class="perk-zoom " v-if="canExpand">
<div class="perk-zoom-bg bg-primary"> </div> <div class="perk-zoom-bg bg-primary"> </div>
<div class="perk-zoom-text w-100 text-center text-white font-weight-bold"> <div class="perk-zoom-text w-100 text-center text-white font-weight-bold">
Select this contribution perk Select this contribution perk
@@ -218,6 +218,7 @@
<template v-else-if="!perk.price.value && perk.custom"> <template v-else-if="!perk.price.value && perk.custom">
Any amount Any amount
</template> </template>
</span> </span>
</div> </div>
<p class="card-text" v-if="perk.description" v-html="perk.description"></p> <p class="card-text" v-if="perk.description" v-html="perk.description"></p>

View File

@@ -36,6 +36,11 @@ addLoadEvent(function (ev) {
expanded: false expanded: false
} }
}, },
computed: {
canExpand: function(){
return !this.expanded && this.active && (this.perk.price.value || this.perk.custom)
}
},
methods: { methods: {
onContributeFormSubmit: function (e) { onContributeFormSubmit: function (e) {
if (e) { if (e) {
@@ -47,7 +52,7 @@ addLoadEvent(function (ev) {
eventAggregator.$emit("contribute", {amount: this.amount, choiceKey: this.choiceKey}); eventAggregator.$emit("contribute", {amount: this.amount, choiceKey: this.choiceKey});
}, },
expand: function(){ expand: function(){
if(this.active){ if(this.canExpand){
this.expanded = true; this.expanded = true;
} }
} }