mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-01-19 05:33:31 +01:00
Remove dependency on NSwag
This commit is contained in:
parent
8d7b9fcef2
commit
e351e0c9ea
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json.Schema" Version="3.0.13" />
|
||||||
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
|
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
|
||||||
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="80.0.3987.10600" />
|
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="80.0.3987.10600" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
|
@ -61,6 +61,7 @@ using NBXplorer.DerivationStrategy;
|
|||||||
using BTCPayServer.U2F.Models;
|
using BTCPayServer.U2F.Models;
|
||||||
using BTCPayServer.Security.Bitpay;
|
using BTCPayServer.Security.Bitpay;
|
||||||
using MemoryCache = Microsoft.Extensions.Caching.Memory.MemoryCache;
|
using MemoryCache = Microsoft.Extensions.Caching.Memory.MemoryCache;
|
||||||
|
using Newtonsoft.Json.Schema;
|
||||||
|
|
||||||
namespace BTCPayServer.Tests
|
namespace BTCPayServer.Tests
|
||||||
{
|
{
|
||||||
@ -90,6 +91,20 @@ namespace BTCPayServer.Tests
|
|||||||
await Task.WhenAll(checkLinks);
|
await Task.WhenAll(checkLinks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Fast", "Fast")]
|
||||||
|
public async Task CheckSwaggerIsConformToSchema()
|
||||||
|
{
|
||||||
|
JObject swagger = JObject.Parse(File.ReadAllText(Path.Combine(TestUtils.TryGetSolutionDirectoryInfo().FullName, "BTCPayServer", "wwwroot", "swagger", "v1", "swagger.template.json")));
|
||||||
|
using HttpClient client = new HttpClient();
|
||||||
|
var resp = await client.GetAsync("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/schemas/v3.0/schema.json");
|
||||||
|
var schema = JSchema.Parse(await resp.Content.ReadAsStringAsync());
|
||||||
|
IList<ValidationError> errors;
|
||||||
|
bool valid = swagger.IsValid(schema, out errors);
|
||||||
|
Assert.Empty(errors);
|
||||||
|
Assert.True(valid);
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task CheckLinks(Regex regex, HttpClient httpClient, string file)
|
private static async Task CheckLinks(Regex regex, HttpClient httpClient, string file)
|
||||||
{
|
{
|
||||||
List<Task> checkLinks = new List<Task>();
|
List<Task> checkLinks = new List<Task>();
|
||||||
@ -2766,7 +2781,6 @@ noninventoryitem:
|
|||||||
.Select(p => (ExpectedName: p.Key, ResultAsync: p.Value.GetRatesAsync(default), Fetcher: (BackgroundFetcherRateProvider)p.Value))
|
.Select(p => (ExpectedName: p.Key, ResultAsync: p.Value.GetRatesAsync(default), Fetcher: (BackgroundFetcherRateProvider)p.Value))
|
||||||
.ToList())
|
.ToList())
|
||||||
{
|
{
|
||||||
|
|
||||||
Logs.Tester.LogInformation($"Testing {result.ExpectedName}");
|
Logs.Tester.LogInformation($"Testing {result.ExpectedName}");
|
||||||
if (result.ExpectedName == "ndax")
|
if (result.ExpectedName == "ndax")
|
||||||
{
|
{
|
||||||
|
@ -48,7 +48,6 @@
|
|||||||
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.3" />
|
<PackageReference Include="NicolasDorier.CommandLine.Configuration" Version="1.0.0.3" />
|
||||||
<PackageReference Include="NicolasDorier.RateLimits" Version="1.1.0" />
|
<PackageReference Include="NicolasDorier.RateLimits" Version="1.1.0" />
|
||||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
|
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
|
||||||
<PackageReference Include="NSwag.AspNetCore" Version="13.2.2" />
|
|
||||||
<PackageReference Include="Serilog" Version="2.9.0" />
|
<PackageReference Include="Serilog" Version="2.9.0" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
|
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
||||||
@ -223,4 +222,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<_ContentIncludedByDefault Remove="Views\Authorization\Authorize.cshtml" />
|
<_ContentIncludedByDefault Remove="Views\Authorization\Authorize.cshtml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ProjectExtensions><VisualStudio><UserProperties wwwroot_4swagger_4v1_4swagger_1json__JsonSchema="https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/schemas/v3.0/schema.json" /></VisualStudio></ProjectExtensions>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -14,22 +14,30 @@ using BTCPayServer.HostedServices;
|
|||||||
using BTCPayServer.Services.Apps;
|
using BTCPayServer.Services.Apps;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
using System.IO;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using BTCPayServer.Security;
|
||||||
|
|
||||||
namespace BTCPayServer.Controllers
|
namespace BTCPayServer.Controllers
|
||||||
{
|
{
|
||||||
public class HomeController : Controller
|
public class HomeController : Controller
|
||||||
{
|
{
|
||||||
private readonly CssThemeManager _cachedServerSettings;
|
private readonly CssThemeManager _cachedServerSettings;
|
||||||
|
private readonly IFileProvider _fileProvider;
|
||||||
|
|
||||||
public IHttpClientFactory HttpClientFactory { get; }
|
public IHttpClientFactory HttpClientFactory { get; }
|
||||||
SignInManager<ApplicationUser> SignInManager { get; }
|
SignInManager<ApplicationUser> SignInManager { get; }
|
||||||
|
|
||||||
public HomeController(IHttpClientFactory httpClientFactory,
|
public HomeController(IHttpClientFactory httpClientFactory,
|
||||||
CssThemeManager cachedServerSettings,
|
CssThemeManager cachedServerSettings,
|
||||||
|
IWebHostEnvironment webHostEnvironment,
|
||||||
SignInManager<ApplicationUser> signInManager)
|
SignInManager<ApplicationUser> signInManager)
|
||||||
{
|
{
|
||||||
HttpClientFactory = httpClientFactory;
|
HttpClientFactory = httpClientFactory;
|
||||||
_cachedServerSettings = cachedServerSettings;
|
_cachedServerSettings = cachedServerSettings;
|
||||||
|
_fileProvider = webHostEnvironment.WebRootFileProvider;
|
||||||
SignInManager = signInManager;
|
SignInManager = signInManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +113,26 @@ namespace BTCPayServer.Controllers
|
|||||||
return View(new BitpayTranslatorViewModel());
|
return View(new BitpayTranslatorViewModel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Route("swagger/v1/swagger.json")]
|
||||||
|
public async Task<IActionResult> Swagger()
|
||||||
|
{
|
||||||
|
var fi = _fileProvider.GetFileInfo("swagger/v1/swagger.template.json");
|
||||||
|
using var stream = fi.CreateReadStream();
|
||||||
|
using var reader = new StreamReader(fi.CreateReadStream());
|
||||||
|
var json = JObject.Parse(await reader.ReadToEndAsync());
|
||||||
|
var servers = new JArray();
|
||||||
|
servers.Add(new JObject(new JProperty("url", HttpContext.Request.GetAbsoluteRoot())));
|
||||||
|
json["servers"] = servers;
|
||||||
|
return Json(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("docs")]
|
||||||
|
public IActionResult SwaggerDocs()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("translate")]
|
[Route("translate")]
|
||||||
public async Task<IActionResult> BitpayTranslator(BitpayTranslatorViewModel vm)
|
public async Task<IActionResult> BitpayTranslator(BitpayTranslatorViewModel vm)
|
||||||
|
@ -5,7 +5,6 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client;
|
using BTCPayServer.Client;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Hosting.OpenApi;
|
|
||||||
using BTCPayServer.Models;
|
using BTCPayServer.Models;
|
||||||
using BTCPayServer.Security;
|
using BTCPayServer.Security;
|
||||||
using BTCPayServer.Security.APIKeys;
|
using BTCPayServer.Security.APIKeys;
|
||||||
@ -13,7 +12,6 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBitcoin.DataEncoders;
|
using NBitcoin.DataEncoders;
|
||||||
using NSwag.Annotations;
|
|
||||||
using YamlDotNet.Core.Tokens;
|
using YamlDotNet.Core.Tokens;
|
||||||
|
|
||||||
namespace BTCPayServer.Controllers
|
namespace BTCPayServer.Controllers
|
||||||
@ -82,15 +80,7 @@ namespace BTCPayServer.Controllers
|
|||||||
return View("AddApiKey", await SetViewModelValues(new AddApiKeyViewModel()));
|
return View("AddApiKey", await SetViewModelValues(new AddApiKeyViewModel()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <param name="permissions">The permissions to request. Current permissions available: ServerManagement, StoreManagement</param>
|
|
||||||
/// <param name="applicationName">The name of your application</param>
|
|
||||||
/// <param name="strict">If permissions are specified, and strict is set to false, it will allow the user to reject some of permissions the application is requesting.</param>
|
|
||||||
/// <param name="selectiveStores">If the application is requesting the CanModifyStoreSettings permission and selectiveStores is set to true, this allows the user to only grant permissions to selected stores under the user's control.</param>
|
|
||||||
[HttpGet("~/api-keys/authorize")]
|
[HttpGet("~/api-keys/authorize")]
|
||||||
[OpenApiTags("Authorization")]
|
|
||||||
[OpenApiOperation("Authorize User",
|
|
||||||
"Redirect the browser to this endpoint to request the user to generate an api-key with specific permissions")]
|
|
||||||
[IncludeInOpenApiDocs]
|
|
||||||
public async Task<IActionResult> AuthorizeAPIKey(string[] permissions, string applicationName = null,
|
public async Task<IActionResult> AuthorizeAPIKey(string[] permissions, string applicationName = null,
|
||||||
bool strict = true, bool selectiveStores = false)
|
bool strict = true, bool selectiveStores = false)
|
||||||
{
|
{
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Hosting.OpenApi;
|
|
||||||
using BTCPayServer.Security;
|
using BTCPayServer.Security;
|
||||||
using BTCPayServer.Security.APIKeys;
|
using BTCPayServer.Security.APIKeys;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NSwag.Annotations;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Controllers.RestApi.ApiKeys
|
namespace BTCPayServer.Controllers.RestApi.ApiKeys
|
||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[IncludeInOpenApiDocs]
|
|
||||||
[OpenApiTags("API Keys")]
|
|
||||||
[Authorize(AuthenticationSchemes = AuthenticationSchemes.ApiKey)]
|
[Authorize(AuthenticationSchemes = AuthenticationSchemes.ApiKey)]
|
||||||
public class ApiKeysController : ControllerBase
|
public class ApiKeysController : ControllerBase
|
||||||
{
|
{
|
||||||
@ -27,9 +23,6 @@ namespace BTCPayServer.Controllers.RestApi.ApiKeys
|
|||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
[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/api-keys/current")]
|
||||||
[HttpGet("~/api/v1/users/me/api-keys/current")]
|
[HttpGet("~/api/v1/users/me/api-keys/current")]
|
||||||
public async Task<ActionResult<ApiKeyData>> GetKey()
|
public async Task<ActionResult<ApiKeyData>> GetKey()
|
||||||
@ -38,10 +31,7 @@ namespace BTCPayServer.Controllers.RestApi.ApiKeys
|
|||||||
var data = await _apiKeyRepository.GetKey(apiKey);
|
var data = await _apiKeyRepository.GetKey(apiKey);
|
||||||
return Ok(FromModel(data));
|
return Ok(FromModel(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
[OpenApiOperation("Revoke the current API Key", "Revoke the current API key so that it cannot be used anymore")]
|
|
||||||
[SwaggerResponse(StatusCodes.Status200OK, typeof(ApiKeyData),
|
|
||||||
Description = "The key was revoked and is no longer usable")]
|
|
||||||
[HttpDelete("~/api/v1/api-keys/current")]
|
[HttpDelete("~/api/v1/api-keys/current")]
|
||||||
[HttpDelete("~/api/v1/users/me/api-keys/current")]
|
[HttpDelete("~/api/v1/users/me/api-keys/current")]
|
||||||
public async Task<ActionResult<ApiKeyData>> RevokeKey()
|
public async Task<ActionResult<ApiKeyData>> RevokeKey()
|
||||||
|
@ -5,7 +5,6 @@ using BTCPayServer.Client.Models;
|
|||||||
using BTCPayServer.Configuration;
|
using BTCPayServer.Configuration;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Events;
|
using BTCPayServer.Events;
|
||||||
using BTCPayServer.Hosting.OpenApi;
|
|
||||||
using BTCPayServer.Security;
|
using BTCPayServer.Security;
|
||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@ -13,13 +12,10 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||||
using NSwag.Annotations;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Controllers.RestApi.Users
|
namespace BTCPayServer.Controllers.RestApi.Users
|
||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[IncludeInOpenApiDocs]
|
|
||||||
[OpenApiTags("Users")]
|
|
||||||
[Authorize(AuthenticationSchemes = AuthenticationSchemes.ApiKey)]
|
[Authorize(AuthenticationSchemes = AuthenticationSchemes.ApiKey)]
|
||||||
public class UsersController : ControllerBase
|
public class UsersController : ControllerBase
|
||||||
{
|
{
|
||||||
@ -40,9 +36,6 @@ namespace BTCPayServer.Controllers.RestApi.Users
|
|||||||
_eventAggregator = eventAggregator;
|
_eventAggregator = eventAggregator;
|
||||||
}
|
}
|
||||||
|
|
||||||
[OpenApiOperation("Get current user information", "View information about the current user")]
|
|
||||||
[SwaggerResponse(StatusCodes.Status200OK, typeof(ApplicationUserData),
|
|
||||||
Description = "Information about the current user")]
|
|
||||||
[Authorize(Policy = Policies.CanModifyProfile.Key, AuthenticationSchemes = AuthenticationSchemes.ApiKey)]
|
[Authorize(Policy = Policies.CanModifyProfile.Key, AuthenticationSchemes = AuthenticationSchemes.ApiKey)]
|
||||||
[HttpGet("~/api/v1/users/me")]
|
[HttpGet("~/api/v1/users/me")]
|
||||||
public async Task<ActionResult<ApplicationUserData>> GetCurrentUser()
|
public async Task<ActionResult<ApplicationUserData>> GetCurrentUser()
|
||||||
@ -51,13 +44,6 @@ namespace BTCPayServer.Controllers.RestApi.Users
|
|||||||
return FromModel(user);
|
return FromModel(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
[OpenApiOperation("Create user", "Create a new user")]
|
|
||||||
[SwaggerResponse(StatusCodes.Status201Created, typeof(ApplicationUserData),
|
|
||||||
Description = "Information about the new user")]
|
|
||||||
[SwaggerResponse(StatusCodes.Status422UnprocessableEntity, typeof(ValidationProblemDetails),
|
|
||||||
Description = "A list of validation errors that occurred")]
|
|
||||||
[SwaggerResponse(StatusCodes.Status400BadRequest, typeof(ValidationProblemDetails),
|
|
||||||
Description = "A list of errors that occurred when creating the user")]
|
|
||||||
[Authorize(Policy = Policies.CanCreateUser.Key, AuthenticationSchemes = AuthenticationSchemes.ApiKey)]
|
[Authorize(Policy = Policies.CanCreateUser.Key, AuthenticationSchemes = AuthenticationSchemes.ApiKey)]
|
||||||
[HttpPost("~/api/v1/users")]
|
[HttpPost("~/api/v1/users")]
|
||||||
public async Task<ActionResult<ApplicationUserData>> CreateUser(CreateApplicationUserRequest request)
|
public async Task<ActionResult<ApplicationUserData>> CreateUser(CreateApplicationUserRequest request)
|
||||||
|
@ -26,7 +26,6 @@ using System.Threading;
|
|||||||
using BTCPayServer.Services.Wallets;
|
using BTCPayServer.Services.Wallets;
|
||||||
using BTCPayServer.Logging;
|
using BTCPayServer.Logging;
|
||||||
using BTCPayServer.HostedServices;
|
using BTCPayServer.HostedServices;
|
||||||
using BTCPayServer.Hosting.OpenApi;
|
|
||||||
using BTCPayServer.PaymentRequest;
|
using BTCPayServer.PaymentRequest;
|
||||||
using BTCPayServer.Payments;
|
using BTCPayServer.Payments;
|
||||||
using BTCPayServer.Payments.Bitcoin;
|
using BTCPayServer.Payments.Bitcoin;
|
||||||
@ -264,8 +263,6 @@ namespace BTCPayServer.Hosting
|
|||||||
}
|
}
|
||||||
return rateLimits;
|
return rateLimits;
|
||||||
});
|
});
|
||||||
services.AddBTCPayOpenApi();
|
|
||||||
|
|
||||||
services.AddLogging(logBuilder =>
|
services.AddLogging(logBuilder =>
|
||||||
{
|
{
|
||||||
var debugLogFile = BTCPayServerOptions.GetDebugLog(configuration);
|
var debugLogFile = BTCPayServerOptions.GetDebugLog(configuration);
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
|
|
||||||
namespace BTCPayServer.Hosting.OpenApi
|
|
||||||
{
|
|
||||||
public class IncludeInOpenApiDocs : Attribute
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,115 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using BTCPayServer.Configuration;
|
|
||||||
using BTCPayServer.Data;
|
|
||||||
using BTCPayServer.Payments;
|
|
||||||
using BTCPayServer.Security;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using NJsonSchema;
|
|
||||||
using NJsonSchema.Generation.TypeMappers;
|
|
||||||
using NSwag;
|
|
||||||
using NSwag.Generation.Processors.Security;
|
|
||||||
using Org.BouncyCastle.Asn1.Ocsp;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Hosting.OpenApi
|
|
||||||
{
|
|
||||||
public static class OpenApiExtensions
|
|
||||||
{
|
|
||||||
public static IServiceCollection AddBTCPayOpenApi(this IServiceCollection serviceCollection)
|
|
||||||
{
|
|
||||||
return serviceCollection.AddOpenApiDocument(config =>
|
|
||||||
{
|
|
||||||
config.PostProcess = document =>
|
|
||||||
{
|
|
||||||
document.Info.Version = "v1";
|
|
||||||
document.Info.Title = "BTCPay Greenfield API";
|
|
||||||
document.Info.Description = "A full API to use your BTCPay Server";
|
|
||||||
document.Info.TermsOfService = null;
|
|
||||||
document.Info.Contact = new NSwag.OpenApiContact
|
|
||||||
{
|
|
||||||
Name = "BTCPay Server", Email = string.Empty, Url = "https://btcpayserver.org"
|
|
||||||
};
|
|
||||||
};
|
|
||||||
config.AddOperationFilter(context =>
|
|
||||||
{
|
|
||||||
var methodInfo = context.MethodInfo;
|
|
||||||
if (methodInfo != null)
|
|
||||||
{
|
|
||||||
return methodInfo.CustomAttributes.Any(data =>
|
|
||||||
data.AttributeType == typeof(IncludeInOpenApiDocs)) ||
|
|
||||||
methodInfo.DeclaringType.CustomAttributes.Any(data =>
|
|
||||||
data.AttributeType == typeof(IncludeInOpenApiDocs));
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
config.AddSecurity("APIKey", Enumerable.Empty<string>(),
|
|
||||||
new OpenApiSecurityScheme
|
|
||||||
{
|
|
||||||
Type = OpenApiSecuritySchemeType.ApiKey,
|
|
||||||
Name = "Authorization",
|
|
||||||
In = OpenApiSecurityApiKeyLocation.Header,
|
|
||||||
Description =
|
|
||||||
"BTCPay Server supports authenticating and authorizing users through an API Key that is generated by them. Send the API Key as a header value to Authorization with the format: token {token}. For a smoother experience, you can generate a url that redirects users to an API key creation screen."
|
|
||||||
});
|
|
||||||
|
|
||||||
config.OperationProcessors.Add(
|
|
||||||
new BTCPayPolicyOperationProcessor("APIKey", AuthenticationSchemes.ApiKey));
|
|
||||||
|
|
||||||
config.TypeMappers.Add(
|
|
||||||
new PrimitiveTypeMapper(typeof(PaymentType), s => s.Type = JsonObjectType.String));
|
|
||||||
config.TypeMappers.Add(new PrimitiveTypeMapper(typeof(PaymentMethodId),
|
|
||||||
s => s.Type = JsonObjectType.String));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IApplicationBuilder UseBTCPayOpenApi(this IApplicationBuilder builder)
|
|
||||||
{
|
|
||||||
var roothPath = builder.ApplicationServices.GetService<BTCPayServerOptions>().RootPath;
|
|
||||||
var matched = new PathString($"{roothPath}docs");
|
|
||||||
return builder.UseOpenApi()
|
|
||||||
.Use(async (context, next) =>
|
|
||||||
{
|
|
||||||
if (context.Request.Path.StartsWithSegments(matched, StringComparison.InvariantCultureIgnoreCase) && !context.User.Claims.Any())
|
|
||||||
{
|
|
||||||
context.Response.Redirect( $"{context.Request.GetRelativePath(roothPath)}account/login?returnUrl={context.Request.Path}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await next.Invoke();
|
|
||||||
})
|
|
||||||
.UseReDoc(settings =>
|
|
||||||
{
|
|
||||||
settings.Path = "/docs";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class BTCPayPolicyOperationProcessor : AspNetCoreOperationSecurityScopeProcessor
|
|
||||||
{
|
|
||||||
private readonly string _authScheme;
|
|
||||||
|
|
||||||
public BTCPayPolicyOperationProcessor(string x, string authScheme) : base(x)
|
|
||||||
{
|
|
||||||
_authScheme = authScheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override IEnumerable<string> GetScopes(IEnumerable<AuthorizeAttribute> authorizeAttributes)
|
|
||||||
{
|
|
||||||
var result = authorizeAttributes
|
|
||||||
.Where(attribute => attribute?.AuthenticationSchemes != null && attribute.Policy != null &&
|
|
||||||
attribute.AuthenticationSchemes.Equals(_authScheme,
|
|
||||||
StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
.Select(attribute => attribute.Policy);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,7 +19,6 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
|||||||
using BTCPayServer.Security;
|
using BTCPayServer.Security;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using BTCPayServer.Hosting.OpenApi;
|
|
||||||
using BTCPayServer.PaymentRequest;
|
using BTCPayServer.PaymentRequest;
|
||||||
using BTCPayServer.Services.Apps;
|
using BTCPayServer.Services.Apps;
|
||||||
using BTCPayServer.Storage;
|
using BTCPayServer.Storage;
|
||||||
@ -194,7 +193,6 @@ namespace BTCPayServer.Hosting
|
|||||||
app.UseProviderStorage(options);
|
app.UseProviderStorage(options);
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
app.UseBTCPayOpenApi();
|
|
||||||
app.UseSession();
|
app.UseSession();
|
||||||
|
|
||||||
app.UseWebSockets();
|
app.UseWebSockets();
|
||||||
|
27
BTCPayServer/Views/Home/SwaggerDocs.cshtml
Normal file
27
BTCPayServer/Views/Home/SwaggerDocs.cshtml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
@{
|
||||||
|
Layout = null;
|
||||||
|
}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>ReDoc</title>
|
||||||
|
<!-- needed for adaptive design -->
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
ReDoc doesn't change outer page styles
|
||||||
|
-->
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<redoc spec-url="@Url.ActionLink("Swagger")"></redoc>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/redoc@2.0.0-rc.24/bundles/redoc.standalone.js" integrity="sha384-ZO+OTQZMsYIcoraCBa8iJW/5b2O8K1ujHmRfOwSvpVBlHUeKq5t3/kh1p8JQJ99X" crossorigin="anonymous"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
430
BTCPayServer/wwwroot/swagger/v1/swagger.template.json
Normal file
430
BTCPayServer/wwwroot/swagger/v1/swagger.template.json
Normal file
@ -0,0 +1,430 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.0.0",
|
||||||
|
"info": {
|
||||||
|
"title": "BTCPay Greenfield API",
|
||||||
|
"description": "A full API to use your BTCPay Server",
|
||||||
|
"contact": {
|
||||||
|
"name": "BTCPay Server",
|
||||||
|
"url": "https://btcpayserver.org",
|
||||||
|
"email": "nicolas.dorier@gmail.com"
|
||||||
|
},
|
||||||
|
"version": "v1"
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/api-keys/authorize": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Authorization"
|
||||||
|
],
|
||||||
|
"summary": "Authorize User",
|
||||||
|
"description": "Redirect the browser to this endpoint to request the user to generate an api-key with specific permissions",
|
||||||
|
"operationId": "Manage_AuthorizeAPIKey",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "permissions",
|
||||||
|
"description": "The permissions to request. Current permissions available: ServerManagement, StoreManagement",
|
||||||
|
"in": "query",
|
||||||
|
"style": "form",
|
||||||
|
"explode": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"nullable": true,
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-position": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "applicationName",
|
||||||
|
"description": "The name of your application",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"x-position": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "strict",
|
||||||
|
"description": "If permissions are specified, and strict is set to false, it will allow the user to reject some of permissions the application is requesting.",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"x-position": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "selectiveStores",
|
||||||
|
"description": "If the application is requesting the CanModifyStoreSettings permission and selectiveStores is set to true, this allows the user to only grant permissions to selected stores under the user's control.",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"x-position": 4
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"content": {
|
||||||
|
"application/octet-stream": {
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "binary"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"APIKey": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/users/me": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Users"
|
||||||
|
],
|
||||||
|
"summary": "Get current user information",
|
||||||
|
"description": "View information about the current user",
|
||||||
|
"operationId": "Users_GetCurrentUser",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Information about the current user",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ApplicationUserData"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"APIKey": [
|
||||||
|
"btcpay.store.canmodifyprofile"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/users": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Users"
|
||||||
|
],
|
||||||
|
"summary": "Create user",
|
||||||
|
"description": "Create a new user",
|
||||||
|
"operationId": "Users_CreateUser",
|
||||||
|
"requestBody": {
|
||||||
|
"x-name": "request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"isAdministrator": {
|
||||||
|
"type": "boolean",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"emailConfirmed": {
|
||||||
|
"type": "boolean",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"x-position": 1
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "Information about the new user",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ApplicationUserData"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "A list of validation errors that occurred",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ValidationProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "A list of errors that occurred when creating the user",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ValidationProblemDetails"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"APIKey": [
|
||||||
|
"btcpay.store.cancreateuser"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/api-keys/current": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"API Keys"
|
||||||
|
],
|
||||||
|
"summary": "Get current API Key information",
|
||||||
|
"description": "View information about the current API key",
|
||||||
|
"operationId": "ApiKeys_GetKey",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Information about the current api key",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ApiKeyData"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"APIKey": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"API Keys"
|
||||||
|
],
|
||||||
|
"summary": "Revoke the current API Key",
|
||||||
|
"description": "Revoke the current API key so that it cannot be used anymore",
|
||||||
|
"operationId": "ApiKeys_RevokeKey",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The key was revoked and is no longer usable",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ApiKeyData"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"APIKey": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/users/me/api-keys/current": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"API Keys"
|
||||||
|
],
|
||||||
|
"summary": "Get current API Key information",
|
||||||
|
"description": "View information about the current API key",
|
||||||
|
"operationId": "ApiKeys_GetKey2",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Information about the current api key",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ApiKeyData"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"APIKey": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"API Keys"
|
||||||
|
],
|
||||||
|
"summary": "Revoke the current API Key",
|
||||||
|
"description": "Revoke the current API key so that it cannot be used anymore",
|
||||||
|
"operationId": "ApiKeys_RevokeKey2",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The key was revoked and is no longer usable",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ApiKeyData"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"APIKey": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"ApplicationUserData": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"emailConfirmed": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"requiresEmailConfirmation": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ValidationProblemDetails": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"errors": {
|
||||||
|
"type": "object",
|
||||||
|
"nullable": true,
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ProblemDetails": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"detail": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"instance": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"extensions": {
|
||||||
|
"type": "object",
|
||||||
|
"nullable": true,
|
||||||
|
"additionalProperties": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ApiKeyData": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"apiKey": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"userId": {
|
||||||
|
"type": "string",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"permissions": {
|
||||||
|
"type": "array",
|
||||||
|
"nullable": true,
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {
|
||||||
|
"APIKey": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"description": "BTCPay Server supports authenticating and authorizing users through an API Key that is generated by them. Send the API Key as a header value to Authorization with the format: token {token}. For a smoother experience, you can generate a url that redirects users to an API key creation screen.",
|
||||||
|
"name": "Authorization",
|
||||||
|
"in": "header"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"APIKey": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"name": "Users"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "API Keys"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user