diff --git a/BTCPayServer.Client/BTCPayServerClient.Stores.cs b/BTCPayServer.Client/BTCPayServerClient.Stores.cs index 72de12483..301629352 100644 --- a/BTCPayServer.Client/BTCPayServerClient.Stores.cs +++ b/BTCPayServer.Client/BTCPayServerClient.Stores.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Net.Http; using System.Threading; @@ -27,5 +28,14 @@ namespace BTCPayServer.Client CreateHttpRequest($"api/v1/stores/{storeId}", method: HttpMethod.Delete), token); HandleResponse(response); } + + public virtual async Task CreateStore(CreateStoreRequest request, CancellationToken token = default) + { + if (request == null) + throw new ArgumentNullException(nameof(request)); + var response = await _httpClient.SendAsync(CreateHttpRequest("api/v1/stores", bodyPayload: request, method: HttpMethod.Post), token); + return await HandleResponse(response); + } + } } diff --git a/BTCPayServer.Client/Models/CreateStoreRequest.cs b/BTCPayServer.Client/Models/CreateStoreRequest.cs new file mode 100644 index 000000000..e6e3babc1 --- /dev/null +++ b/BTCPayServer.Client/Models/CreateStoreRequest.cs @@ -0,0 +1,7 @@ +namespace BTCPayServer.Client.Models +{ + public class CreateStoreRequest + { + public string Name { get; set; } + } +} diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index a2dba6a81..96fc313df 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -169,25 +169,30 @@ namespace BTCPayServer.Tests await user.MakeAdmin(); var client = await user.CreateClient(Policies.Unrestricted); + //create store + var newStore = await client.CreateStore(new CreateStoreRequest() {Name = "A"}); + //list stores var stores = await client.GetStores(); + var storeIds = stores.Select(data => data.Id); + var storeNames = stores.Select(data => data.Name); Assert.NotNull(stores); - Assert.Single(stores); - Assert.Equal(user.StoreId,stores.First().Id); + Assert.Equal(2, stores.Count()); + Assert.Contains(newStore.Id, storeIds); + Assert.Contains(user.StoreId, storeIds); //get store var store = await client.GetStore(user.StoreId); Assert.Equal(user.StoreId,store.Id); - Assert.Equal(store.Name,stores.First().Name); + Assert.Contains(store.Name,storeNames); //remove store - await client.RemoveStore(user.StoreId); + await client.RemoveStore(newStore.Id); await AssertHttpError(403, async () => { - await client.GetStore(user.StoreId); + await client.GetStore(newStore.Id); }); - //remove it from the tester state as it will not be happy we removed it ourselves - tester.Stores.Remove(user.StoreId); + Assert.Single(await client.GetStores()); } } diff --git a/BTCPayServer/Controllers/GreenField/StoresController.cs b/BTCPayServer/Controllers/GreenField/StoresController.cs index 7b8864354..48bf9be92 100644 --- a/BTCPayServer/Controllers/GreenField/StoresController.cs +++ b/BTCPayServer/Controllers/GreenField/StoresController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using BTCPayServer.Client; +using BTCPayServer.Client.Models; using BTCPayServer.Data; using BTCPayServer.Security; using BTCPayServer.Services.Stores; @@ -62,6 +63,16 @@ namespace BTCPayServer.Controllers.GreenField return Ok(); } + [HttpPost("~/api/v1/stores")] + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)] + public async Task> CreateStore(CreateStoreRequest request) + { + if (request is null) + return BadRequest(); + var store = await _storeRepository.CreateStore(_userManager.GetUserId(User), request.Name); + return Ok(FromModel(store)); + } + private static Client.Models.StoreData FromModel(Data.StoreData data) { return new Client.Models.StoreData()