Merge pull request #1531 from Kukks/api/store/prep

GreenField: Prep store for more data
This commit is contained in:
Nicolas Dorier 2020-05-01 18:49:29 +09:00 committed by GitHub
commit 5443ac4688
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 88 additions and 112 deletions

View file

@ -1,6 +1,3 @@
using BTCPayServer.Client.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
{
public class ApiHealthData

View file

@ -7,6 +7,7 @@ namespace BTCPayServer.Client.Models
{
public string ApiKey { get; set; }
public string Label { get; set; }
[JsonProperty(ItemConverterType = typeof(PermissionJsonConverter))]
public Permission[] Permissions { get; set; }
}

View file

@ -6,33 +6,20 @@ namespace BTCPayServer.Client.Models
/// the id of the user
/// </summary>
public string Id { get; set; }
/// <summary>
/// the email AND username of the user
/// </summary>
public string Email { get; set; }
/// <summary>
/// Whether the user has verified their email
/// </summary>
public bool EmailConfirmed { get; set; }
/// <summary>
/// whether the user needed to verify their email on account creation
/// </summary>
public bool RequiresEmailConfirmation { get; set; }
}
public class CreateApplicationUserRequest
{
/// <summary>
/// the email AND username of the new user
/// </summary>
public string Email { get; set; }
/// <summary>
/// password of the new user
/// </summary>
public string Password { get; set; }
/// <summary>
/// Whether this user is an administrator. If left null and there are no admins in the system, the user will be created as an admin.
/// </summary>
public bool? IsAdministrator { get; set; }
}
}

View file

@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using BTCPayServer.Client.JsonConverters;
using BTCPayServer.Client.JsonConverters;
using Newtonsoft.Json;
namespace BTCPayServer.Client.Models
@ -9,6 +6,7 @@ namespace BTCPayServer.Client.Models
public class CreateApiKeyRequest
{
public string Label { get; set; }
[JsonProperty(ItemConverterType = typeof(PermissionJsonConverter))]
public Permission[] Permissions { get; set; }
}

View file

@ -0,0 +1,20 @@
namespace BTCPayServer.Client.Models
{
public class CreateApplicationUserRequest
{
/// <summary>
/// the email AND username of the new user
/// </summary>
public string Email { get; set; }
/// <summary>
/// password of the new user
/// </summary>
public string Password { get; set; }
/// <summary>
/// Whether this user is an administrator. If left null and there are no admins in the system, the user will be created as an admin.
/// </summary>
public bool? IsAdministrator { get; set; }
}
}

View file

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

View file

@ -1,11 +1,10 @@
namespace BTCPayServer.Client.Models
{
public class StoreData: StoreBaseData
public class StoreData : StoreBaseData
{
/// <summary>
/// the id of the store
/// </summary>
public string Id { get; set; }
}
}

View file

@ -1,6 +1,6 @@
namespace BTCPayServer.Client.Models
{
public class UpdateStoreRequest: StoreBaseData
public class UpdateStoreRequest : StoreBaseData
{
}
}

View file

@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Security.Claims;
namespace BTCPayServer.Data
{
@ -15,76 +11,39 @@ namespace BTCPayServer.Data
LowSpeed = 2,
LowMediumSpeed = 3
}
public class StoreData
{
public string Id
{
get;
set;
}
public string Id { get; set; }
public List<UserStore> UserStores { get; set; }
public List<UserStore> UserStores
{
get; set;
}
public List<AppData> Apps
{
get; set;
}
public List<PaymentRequestData> PaymentRequests
{
get; set;
}
public List<AppData> Apps { get; set; }
public List<PaymentRequestData> PaymentRequests { get; set; }
public List<InvoiceData> Invoices { get; set; }
[Obsolete("Use GetDerivationStrategies instead")]
public string DerivationStrategy
{
get; set;
}
public string DerivationStrategy { get; set; }
[Obsolete("Use GetDerivationStrategies instead")]
public string DerivationStrategies
{
get;
set;
}
public string DerivationStrategies { get; set; }
public string StoreName
{
get; set;
}
public string StoreName { get; set; }
public SpeedPolicy SpeedPolicy
{
get; set;
}
public SpeedPolicy SpeedPolicy { get; set; } = SpeedPolicy.MediumSpeed;
public string StoreWebsite
{
get; set;
}
public string StoreWebsite { get; set; }
public byte[] StoreCertificate
{
get; set;
}
public byte[] StoreCertificate { get; set; }
[NotMapped]
public string Role
{
get; set;
}
[NotMapped] public string Role { get; set; }
public byte[] StoreBlob { get; set; }
public byte[] StoreBlob
{
get;
set;
}
[Obsolete("Use GetDefaultPaymentId instead")]
public string DefaultCrypto { get; set; }
public List<PairedSINData> PairedSINs { 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.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace BTCPayServer.Controllers.GreenField
{
@ -66,27 +65,36 @@ namespace BTCPayServer.Controllers.GreenField
[HttpPost("~/api/v1/stores")]
[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)
return BadRequest(CreateValidationProblem(nameof(request.Name), "Name is missing"));
var store = await _storeRepository.CreateStore(_userManager.GetUserId(User), request.Name);
var validationResult = Validate(request);
if (validationResult != null)
{
return validationResult;
}
var store = new Data.StoreData();
ToModel(request, store);
await _storeRepository.CreateStore(_userManager.GetUserId(User), store);
return Ok(FromModel(store));
}
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
[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();
if (store == null)
{
return NotFound();
}
var validationResult = Validate(request);
if (validationResult != null)
{
return validationResult;
}
if (request?.Name is null)
return BadRequest(CreateValidationProblem(nameof(request.Name), "Name is missing"));
store.StoreName = request.Name;
ToModel(request, store);
await _storeRepository.UpdateStore(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();
modelState.AddModelError(propertyName, errorMessage);
return new ValidationProblemDetails(modelState);
model.StoreName = restModel.Name;
}
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))
throw new ArgumentException("name should not be empty", nameof(name));
if (!string.IsNullOrEmpty(storeData.Id))
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)
throw new ArgumentNullException(nameof(ownerId));
using (var ctx = _ContextFactory.CreateContext())
{
StoreData store = new StoreData
{
Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(32)),
StoreName = name,
SpeedPolicy = SpeedPolicy.MediumSpeed
};
storeData.Id = Encoders.Base58.EncodeData(RandomUtils.GetBytes(32));
var userStore = new UserStore
{
StoreDataId = store.Id,
StoreDataId = storeData.Id,
ApplicationUserId = ownerId,
Role = "Owner"
Role = StoreRoles.Owner
};
ctx.Add(store);
ctx.Add(storeData);
ctx.Add(userStore);
await ctx.SaveChangesAsync().ConfigureAwait(false);
return store;
await ctx.SaveChangesAsync();
}
}
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)
{
using (var ctx = _ContextFactory.CreateContext())