From 9eac33793a0b00819ad86138dc033d99ecd83427 Mon Sep 17 00:00:00 2001 From: Kukks Date: Mon, 24 Feb 2020 18:43:28 +0100 Subject: [PATCH] GreenField API #1: Get current API Key info --- BTCPayServer.Tests/GreenfieldAPITests.cs | 71 +++++++++++++++++++ .../Controllers/RestApi/ApiKeys/ApiKeyData.cs | 23 ++++++ .../RestApi/ApiKeys/ApiKeysController.cs | 37 ++++++++++ 3 files changed, 131 insertions(+) create mode 100644 BTCPayServer.Tests/GreenfieldAPITests.cs create mode 100644 BTCPayServer/Controllers/RestApi/ApiKeys/ApiKeyData.cs create mode 100644 BTCPayServer/Controllers/RestApi/ApiKeys/ApiKeysController.cs diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs new file mode 100644 index 000000000..d2ba99676 --- /dev/null +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -0,0 +1,71 @@ +using System; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using BTCPayServer.Controllers; +using BTCPayServer.Controllers.RestApi.ApiKeys; +using BTCPayServer.Data; +using BTCPayServer.Security.APIKeys; +using BTCPayServer.Tests.Logging; +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json.Linq; +using Xunit; +using Xunit.Abstractions; + +namespace BTCPayServer.Tests +{ + public class GreenfieldAPITests + { + public const int TestTimeout = TestUtils.TestTimeout; + + public const string TestApiPath = "api/test/apikey"; + + public GreenfieldAPITests(ITestOutputHelper helper) + { + Logs.Tester = new XUnitLog(helper) {Name = "Tests"}; + Logs.LogProvider = new XUnitLogProvider(helper); + } + + [Fact] + [Trait("Integration", "Integration")] + public async Task ApiKeysControllerTests() + { + using (var tester = ServerTester.Create()) + { + await tester.StartAsync(); + var user = tester.NewAccount(); + user.GrantAccess(); + await user.MakeAdmin(); + string apiKey = await GenerateAPIKey(tester, user); + + //Get current api key + var request = new HttpRequestMessage(HttpMethod.Get, "api/v1/api-keys/current"); + request.Headers.Authorization = new AuthenticationHeaderValue("token", apiKey); + var result = await tester.PayTester.HttpClient.SendAsync(request); + Assert.True(result.IsSuccessStatusCode); + var apiKeyData = JObject.Parse(await result.Content.ReadAsStringAsync()).ToObject(); + Assert.NotNull(apiKeyData); + Assert.Equal(apiKey, apiKeyData.ApiKey); + Assert.Equal(user.UserId, apiKeyData.UserId); + Assert.Equal(2, apiKeyData.Permissions.Length); + } + } + + private static async Task GenerateAPIKey(ServerTester tester, TestAccount user) + { + var manageController = tester.PayTester.GetController(user.UserId, user.StoreId, user.IsAdmin); + var x = Assert.IsType(await manageController.AddApiKey( + new ManageController.AddApiKeyViewModel() + { + ServerManagementPermission = true, + StoreManagementPermission = true, + StoreMode = ManageController.AddApiKeyViewModel.ApiKeyStoreMode.AllStores + })); + var statusMessage = manageController.TempData.GetStatusMessageModel(); + Assert.NotNull(statusMessage); + var apiKey = statusMessage.Html.Substring(statusMessage.Html.IndexOf("") + 6); + apiKey = apiKey.Substring(0, apiKey.IndexOf("") ); + return apiKey; + } + } +} diff --git a/BTCPayServer/Controllers/RestApi/ApiKeys/ApiKeyData.cs b/BTCPayServer/Controllers/RestApi/ApiKeys/ApiKeyData.cs new file mode 100644 index 000000000..b308976c3 --- /dev/null +++ b/BTCPayServer/Controllers/RestApi/ApiKeys/ApiKeyData.cs @@ -0,0 +1,23 @@ +using BTCPayServer.Data; + +namespace BTCPayServer.Controllers.RestApi.ApiKeys +{ + public class ApiKeyData + { + public string ApiKey { get; set; } + public string Label { get; set; } + public string UserId { get; set; } + public string[] Permissions { get; set; } + + public static ApiKeyData FromModel(APIKeyData data) + { + return new ApiKeyData() + { + Permissions = data.GetPermissions(), + ApiKey = data.Id, + UserId = data.UserId, + Label = data.Label + }; + } + } +} diff --git a/BTCPayServer/Controllers/RestApi/ApiKeys/ApiKeysController.cs b/BTCPayServer/Controllers/RestApi/ApiKeys/ApiKeysController.cs new file mode 100644 index 000000000..ed45d77d6 --- /dev/null +++ b/BTCPayServer/Controllers/RestApi/ApiKeys/ApiKeysController.cs @@ -0,0 +1,37 @@ +using System.Threading.Tasks; +using BTCPayServer.Hosting.OpenApi; +using BTCPayServer.Security; +using BTCPayServer.Security.APIKeys; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using NSwag.Annotations; + +namespace BTCPayServer.Controllers.RestApi.ApiKeys +{ + [ApiController] + [IncludeInOpenApiDocs] + [OpenApiTags("API Keys")] + [Authorize(AuthenticationSchemes = AuthenticationSchemes.ApiKey)] + public class ApiKeysController : ControllerBase + { + private readonly APIKeyRepository _apiKeyRepository; + + public ApiKeysController(APIKeyRepository apiKeyRepository) + { + _apiKeyRepository = apiKeyRepository; + } + + [OpenApiOperation("Get current API Key information", "View information about the current API key")] + [SwaggerResponse(StatusCodes.Status200OK, typeof(ApiKeyData), + Description = "Information about the current api key")] + [HttpGet("~/api/v1/api-keys/current")] + [HttpGet("~/api/v1/users/me/api-keys/current")] + public async Task> GetKey() + { + ControllerContext.HttpContext.GetAPIKey(out var apiKey); + var data = await _apiKeyRepository.GetKey(apiKey); + return Ok(ApiKeyData.FromModel(data)); + } + } +}