GreenField: Prep store for more data

refactored things around a bit to make it cleaner for when we add more properties to the store model
This commit is contained in:
Kukks
2020-04-30 16:43:16 +02:00
parent 3e13e478ad
commit 85517b0344
4 changed files with 60 additions and 86 deletions

View File

@@ -1,7 +1,6 @@
namespace BTCPayServer.Client.Models namespace BTCPayServer.Client.Models
{ {
public class CreateStoreRequest public class CreateStoreRequest:StoreBaseData
{ {
public string Name { get; set; }
} }
} }

View File

@@ -1,10 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Security.Claims;
namespace BTCPayServer.Data namespace BTCPayServer.Data
{ {
@@ -15,76 +11,39 @@ namespace BTCPayServer.Data
LowSpeed = 2, LowSpeed = 2,
LowMediumSpeed = 3 LowMediumSpeed = 3
} }
public class StoreData public class StoreData
{ {
public string Id public string Id { get; set; }
{ public List<UserStore> UserStores { get; set; }
get;
set;
}
public List<UserStore> UserStores public List<AppData> Apps { get; set; }
{
get; set;
}
public List<AppData> Apps
{
get; set;
}
public List<PaymentRequestData> PaymentRequests public List<PaymentRequestData> PaymentRequests { get; set; }
{
get; set;
}
public List<InvoiceData> Invoices { get; set; } public List<InvoiceData> Invoices { get; set; }
[Obsolete("Use GetDerivationStrategies instead")] [Obsolete("Use GetDerivationStrategies instead")]
public string DerivationStrategy public string DerivationStrategy { get; set; }
{
get; set;
}
[Obsolete("Use GetDerivationStrategies instead")] [Obsolete("Use GetDerivationStrategies instead")]
public string DerivationStrategies public string DerivationStrategies { get; set; }
{
get;
set;
}
public string StoreName public string StoreName { get; set; }
{
get; set;
}
public SpeedPolicy SpeedPolicy public SpeedPolicy SpeedPolicy { get; set; } = SpeedPolicy.MediumSpeed;
{
get; set;
}
public string StoreWebsite public string StoreWebsite { get; set; }
{
get; set;
}
public byte[] StoreCertificate public byte[] StoreCertificate { get; set; }
{
get; set;
}
[NotMapped] [NotMapped] public string Role { get; set; }
public string Role
{ public byte[] StoreBlob { get; set; }
get; set;
}
public byte[] StoreBlob
{
get;
set;
}
[Obsolete("Use GetDefaultPaymentId instead")] [Obsolete("Use GetDefaultPaymentId instead")]
public string DefaultCrypto { get; set; } public string DefaultCrypto { get; set; }
public List<PairedSINData> PairedSINs { get; set; } public List<PairedSINData> PairedSINs { get; set; }
public IEnumerable<APIKeyData> APIKeys { get; set; } public IEnumerable<APIKeyData> APIKeys { get; set; }
} }

View File

@@ -9,7 +9,6 @@ using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace BTCPayServer.Controllers.GreenField namespace BTCPayServer.Controllers.GreenField
{ {
@@ -66,27 +65,36 @@ namespace BTCPayServer.Controllers.GreenField
[HttpPost("~/api/v1/stores")] [HttpPost("~/api/v1/stores")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)] [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public async Task<ActionResult<Client.Models.StoreData>> CreateStore(CreateStoreRequest request) public async Task<IActionResult> CreateStore(CreateStoreRequest request)
{ {
if (request?.Name is null) var validationResult = Validate(request);
return BadRequest(CreateValidationProblem(nameof(request.Name), "Name is missing")); if (validationResult != null)
var store = await _storeRepository.CreateStore(_userManager.GetUserId(User), request.Name); {
return validationResult;
}
var store = new Data.StoreData();
ToModel(request, store);
await _storeRepository.CreateStore(_userManager.GetUserId(User), store);
return Ok(FromModel(store)); return Ok(FromModel(store));
} }
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)] [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
[HttpPut("~/api/v1/stores/{storeId}")] [HttpPut("~/api/v1/stores/{storeId}")]
public async Task<ActionResult> UpdateStore(string storeId, UpdateStoreRequest request) public async Task<IActionResult> UpdateStore(string storeId, UpdateStoreRequest request)
{ {
var store = HttpContext.GetStoreData(); var store = HttpContext.GetStoreData();
if (store == null) if (store == null)
{ {
return NotFound(); return NotFound();
} }
var validationResult = Validate(request);
if (validationResult != null)
{
return validationResult;
}
if (request?.Name is null) ToModel(request, store);
return BadRequest(CreateValidationProblem(nameof(request.Name), "Name is missing"));
store.StoreName = request.Name;
await _storeRepository.UpdateStore(store); await _storeRepository.UpdateStore(store);
return Ok(FromModel(store)); return Ok(FromModel(store));
} }
@@ -100,11 +108,16 @@ namespace BTCPayServer.Controllers.GreenField
}; };
} }
private ValidationProblemDetails CreateValidationProblem(string propertyName, string errorMessage) private static void ToModel(StoreBaseData restModel,Data.StoreData model)
{ {
var modelState = new ModelStateDictionary(); model.StoreName = restModel.Name;
modelState.AddModelError(propertyName, errorMessage); }
return new ValidationProblemDetails(modelState);
private IActionResult Validate(StoreBaseData request)
{
if (request?.Name is null)
ModelState.AddModelError(nameof(request.Name), "Name is missing");
return !ModelState.IsValid ? BadRequest(new ValidationProblemDetails(ModelState)) : null;
} }
} }
} }

View File

@@ -158,33 +158,36 @@ namespace BTCPayServer.Services.Stores
} }
} }
public async Task<StoreData> CreateStore(string ownerId, string name) public async Task CreateStore(string ownerId, StoreData storeData)
{ {
if (string.IsNullOrEmpty(name)) if (!string.IsNullOrEmpty(storeData.Id))
throw new ArgumentException("name should not be empty", nameof(name)); throw new ArgumentException("id should be empty", nameof(storeData.StoreName));
if (string.IsNullOrEmpty(storeData.StoreName))
throw new ArgumentException("name should not be empty", nameof(storeData.StoreName));
if (ownerId == null) if (ownerId == null)
throw new ArgumentNullException(nameof(ownerId)); throw new ArgumentNullException(nameof(ownerId));
using (var ctx = _ContextFactory.CreateContext()) using (var ctx = _ContextFactory.CreateContext())
{ {
StoreData store = new StoreData storeData.Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(32));
{
Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(32)),
StoreName = name,
SpeedPolicy = SpeedPolicy.MediumSpeed
};
var userStore = new UserStore var userStore = new UserStore
{ {
StoreDataId = store.Id, StoreDataId = storeData.Id,
ApplicationUserId = ownerId, ApplicationUserId = ownerId,
Role = "Owner" Role = StoreRoles.Owner
}; };
ctx.Add(store); ctx.Add(storeData);
ctx.Add(userStore); ctx.Add(userStore);
await ctx.SaveChangesAsync().ConfigureAwait(false); await ctx.SaveChangesAsync();
return store;
} }
} }
public async Task<StoreData> CreateStore(string ownerId, string name)
{
var store = new StoreData() {StoreName = name};
await CreateStore(ownerId,store);
return store;
}
public async Task RemoveStore(string storeId, string userId) public async Task RemoveStore(string storeId, string userId)
{ {
using (var ctx = _ContextFactory.CreateContext()) using (var ctx = _ContextFactory.CreateContext())