mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 22:14:26 +01:00
Part 1: OpenIddict - Minor Changes & Config prep (#566)
* Part 1: OpenIddict - Minor Changes & Config prep * add missing nuget * pr changes * pr fixes * remove config for openid -- no need for it for now * remove unused extension * Add tests * use pay tester http client * check redirecturl in tests
This commit is contained in:
committed by
Nicolas Dorier
parent
e22b7f74c7
commit
cf436e11ae
@@ -316,6 +316,42 @@ namespace BTCPayServer.Tests
|
|||||||
#pragma warning restore CS0618
|
#pragma warning restore CS0618
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Integration", "Integration")]
|
||||||
|
public async Task GetRedirectedToLoginPathOnChallenge()
|
||||||
|
{
|
||||||
|
using (var tester = ServerTester.Create())
|
||||||
|
{
|
||||||
|
tester.Start();
|
||||||
|
var client = tester.PayTester.HttpClient;
|
||||||
|
//Wallets endpoint is protected
|
||||||
|
var response = await client.GetAsync("wallets");
|
||||||
|
var urlPath = response.RequestMessage.RequestUri.ToString()
|
||||||
|
.Replace(tester.PayTester.ServerUri.ToString(), "");
|
||||||
|
//Cookie Challenge redirects you to login page
|
||||||
|
Assert.StartsWith("Account/Login", urlPath, StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
|
||||||
|
var queryString = response.RequestMessage.RequestUri.ParseQueryString();
|
||||||
|
|
||||||
|
Assert.NotNull(queryString["ReturnUrl"]);
|
||||||
|
Assert.Equal("/wallets", queryString["ReturnUrl"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Integration", "Integration")]
|
||||||
|
public async Task CanUseTestWebsiteUI()
|
||||||
|
{
|
||||||
|
using (var tester = ServerTester.Create())
|
||||||
|
{
|
||||||
|
tester.Start();
|
||||||
|
var http = new HttpClient();
|
||||||
|
var response = await http.GetAsync(tester.PayTester.ServerUri);
|
||||||
|
Assert.True(response.IsSuccessStatusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Integration", "Integration")]
|
[Trait("Integration", "Integration")]
|
||||||
public void CanAcceptInvoiceWithTolerance()
|
public void CanAcceptInvoiceWithTolerance()
|
||||||
|
|||||||
@@ -57,6 +57,8 @@
|
|||||||
<PackageReference Include="NicolasDorier.RateLimits" Version="1.0.0.3" />
|
<PackageReference Include="NicolasDorier.RateLimits" Version="1.0.0.3" />
|
||||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
|
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.2" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.2" />
|
||||||
|
<PackageReference Include="OpenIddict" Version="2.0.0" />
|
||||||
|
<PackageReference Include="OpenIddict.EntityFrameworkCore" Version="2.0.0" />
|
||||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.2" />
|
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.2" />
|
||||||
<PackageReference Include="Serilog" Version="2.7.1" />
|
<PackageReference Include="Serilog" Version="2.7.1" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
|
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
|
||||||
|
|||||||
@@ -6,13 +6,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
|
||||||
using StandardConfiguration;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using NBXplorer;
|
|
||||||
using BTCPayServer.Payments.Lightning;
|
|
||||||
using Renci.SshNet;
|
|
||||||
using NBitcoin.DataEncoders;
|
|
||||||
using BTCPayServer.SSH;
|
using BTCPayServer.SSH;
|
||||||
using BTCPayServer.Lightning;
|
using BTCPayServer.Lightning;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
@@ -49,7 +43,7 @@ namespace BTCPayServer.Configuration
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
public EndPoint SocksEndpoint { get; set; }
|
public EndPoint SocksEndpoint { get; set; }
|
||||||
|
|
||||||
public List<NBXplorerConnectionSetting> NBXplorerConnectionSettings
|
public List<NBXplorerConnectionSetting> NBXplorerConnectionSettings
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
@@ -75,8 +69,7 @@ namespace BTCPayServer.Configuration
|
|||||||
public void LoadArgs(IConfiguration conf)
|
public void LoadArgs(IConfiguration conf)
|
||||||
{
|
{
|
||||||
NetworkType = DefaultConfiguration.GetNetworkType(conf);
|
NetworkType = DefaultConfiguration.GetNetworkType(conf);
|
||||||
var defaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType);
|
DataDir = conf.GetDataDir(NetworkType);
|
||||||
DataDir = conf.GetOrDefault<string>("datadir", defaultSettings.DefaultDataDirectory);
|
|
||||||
Logs.Configuration.LogInformation("Network: " + NetworkType.ToString());
|
Logs.Configuration.LogInformation("Network: " + NetworkType.ToString());
|
||||||
|
|
||||||
var supportedChains = conf.GetOrDefault<string>("chains", "btc")
|
var supportedChains = conf.GetOrDefault<string>("chains", "btc")
|
||||||
|
|||||||
@@ -58,5 +58,17 @@ namespace BTCPayServer.Configuration
|
|||||||
throw new NotSupportedException("Configuration value does not support time " + typeof(T).Name);
|
throw new NotSupportedException("Configuration value does not support time " + typeof(T).Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetDataDir(this IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var networkType = DefaultConfiguration.GetNetworkType(configuration);
|
||||||
|
return GetDataDir(configuration, networkType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetDataDir(this IConfiguration configuration, NetworkType networkType)
|
||||||
|
{
|
||||||
|
var defaultSettings = BTCPayDefaultSettings.GetDefaultSettings(networkType);
|
||||||
|
return configuration.GetOrDefault("datadir", defaultSettings.DefaultDataDirectory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ namespace BTCPayServer.Hosting
|
|||||||
{
|
{
|
||||||
public static class BTCPayServerServices
|
public static class BTCPayServerServices
|
||||||
{
|
{
|
||||||
public static IServiceCollection AddBTCPayServer(this IServiceCollection services)
|
public static IServiceCollection AddBTCPayServer(this IServiceCollection services, IConfiguration configuration)
|
||||||
{
|
{
|
||||||
services.AddDbContext<ApplicationDbContext>((provider, o) =>
|
services.AddDbContext<ApplicationDbContext>((provider, o) =>
|
||||||
{
|
{
|
||||||
@@ -67,7 +67,8 @@ namespace BTCPayServer.Hosting
|
|||||||
services.TryAddSingleton<SocketFactory>();
|
services.TryAddSingleton<SocketFactory>();
|
||||||
services.TryAddSingleton<LightningClientFactoryService>();
|
services.TryAddSingleton<LightningClientFactoryService>();
|
||||||
services.TryAddSingleton<InvoicePaymentNotification>();
|
services.TryAddSingleton<InvoicePaymentNotification>();
|
||||||
services.TryAddSingleton<BTCPayServerOptions>(o => o.GetRequiredService<IOptions<BTCPayServerOptions>>().Value);
|
services.TryAddSingleton<BTCPayServerOptions>(o =>
|
||||||
|
o.GetRequiredService<IOptions<BTCPayServerOptions>>().Value);
|
||||||
services.TryAddSingleton<InvoiceRepository>(o =>
|
services.TryAddSingleton<InvoiceRepository>(o =>
|
||||||
{
|
{
|
||||||
var opts = o.GetRequiredService<BTCPayServerOptions>();
|
var opts = o.GetRequiredService<BTCPayServerOptions>();
|
||||||
@@ -219,7 +220,7 @@ namespace BTCPayServer.Hosting
|
|||||||
// bundling
|
// bundling
|
||||||
|
|
||||||
services.AddAuthorization(o => Policies.AddBTCPayPolicies(o));
|
services.AddAuthorization(o => Policies.AddBTCPayPolicies(o));
|
||||||
BitpayAuthentication.AddAuthentication(services);
|
services.AddBtcPayServerAuthenticationSchemes(configuration);
|
||||||
|
|
||||||
services.AddSingleton<IBundleProvider, ResourceBundleProvider>();
|
services.AddSingleton<IBundleProvider, ResourceBundleProvider>();
|
||||||
services.AddTransient<BundleOptions>(provider =>
|
services.AddTransient<BundleOptions>(provider =>
|
||||||
@@ -231,9 +232,9 @@ namespace BTCPayServer.Hosting
|
|||||||
return bundle;
|
return bundle;
|
||||||
});
|
});
|
||||||
|
|
||||||
services.AddCors(options=>
|
services.AddCors(options =>
|
||||||
{
|
{
|
||||||
options.AddPolicy(CorsPolicies.All, p=>p.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
|
options.AddPolicy(CorsPolicies.All, p => p.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());
|
||||||
});
|
});
|
||||||
|
|
||||||
var rateLimits = new RateLimitService();
|
var rateLimits = new RateLimitService();
|
||||||
@@ -241,6 +242,13 @@ namespace BTCPayServer.Hosting
|
|||||||
services.AddSingleton(rateLimits);
|
services.AddSingleton(rateLimits);
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void AddBtcPayServerAuthenticationSchemes(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
services.AddAuthentication()
|
||||||
|
.AddCookie()
|
||||||
|
.AddBitpayAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
public static IApplicationBuilder UsePayServer(this IApplicationBuilder app)
|
public static IApplicationBuilder UsePayServer(this IApplicationBuilder app)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ namespace BTCPayServer.Hosting
|
|||||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||||
.AddDefaultTokenProviders();
|
.AddDefaultTokenProviders();
|
||||||
services.AddSignalR();
|
services.AddSignalR();
|
||||||
services.AddBTCPayServer();
|
|
||||||
services.AddProviderStorage();
|
services.AddProviderStorage();
|
||||||
services.AddSession();
|
services.AddSession();
|
||||||
|
services.AddBTCPayServer(Configuration);
|
||||||
services.AddMvc(o =>
|
services.AddMvc(o =>
|
||||||
{
|
{
|
||||||
o.Filters.Add(new XFrameOptionsAttribute("DENY"));
|
o.Filters.Add(new XFrameOptionsAttribute("DENY"));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace BTCPayServer.Models
|
namespace BTCPayServer.Models
|
||||||
{
|
{
|
||||||
@@ -7,5 +8,11 @@ namespace BTCPayServer.Models
|
|||||||
public string RequestId { get; set; }
|
public string RequestId { get; set; }
|
||||||
|
|
||||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||||
|
|
||||||
|
[Display(Name = "Error")]
|
||||||
|
public string Error { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "Description")]
|
||||||
|
public string ErrorDescription { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
using System;
|
using System.Security.Claims;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Models;
|
using BTCPayServer.Models;
|
||||||
using BTCPayServer.Services.Stores;
|
using BTCPayServer.Services.Stores;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace BTCPayServer.Security
|
namespace BTCPayServer.Security
|
||||||
@@ -17,13 +12,13 @@ namespace BTCPayServer.Security
|
|||||||
|
|
||||||
public class BTCPayClaimsFilter : IAsyncAuthorizationFilter, IConfigureOptions<MvcOptions>
|
public class BTCPayClaimsFilter : IAsyncAuthorizationFilter, IConfigureOptions<MvcOptions>
|
||||||
{
|
{
|
||||||
UserManager<ApplicationUser> _UserManager;
|
UserManager<ApplicationUser> _userManager;
|
||||||
StoreRepository _StoreRepository;
|
StoreRepository _StoreRepository;
|
||||||
public BTCPayClaimsFilter(
|
public BTCPayClaimsFilter(
|
||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
StoreRepository storeRepository)
|
StoreRepository storeRepository)
|
||||||
{
|
{
|
||||||
_UserManager = userManager;
|
_userManager = userManager;
|
||||||
_StoreRepository = storeRepository;
|
_StoreRepository = storeRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,28 +30,34 @@ namespace BTCPayServer.Security
|
|||||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||||
{
|
{
|
||||||
var principal = context.HttpContext.User;
|
var principal = context.HttpContext.User;
|
||||||
if (!context.HttpContext.GetIsBitpayAPI())
|
if (context.HttpContext.GetIsBitpayAPI())
|
||||||
{
|
{
|
||||||
var identity = ((ClaimsIdentity)principal.Identity);
|
return;
|
||||||
if (principal.IsInRole(Roles.ServerAdmin))
|
}
|
||||||
|
|
||||||
|
var identity = ((ClaimsIdentity)principal.Identity);
|
||||||
|
if (principal.IsInRole(Roles.ServerAdmin))
|
||||||
|
{
|
||||||
|
identity.AddClaim(new Claim(Policies.CanModifyServerSettings.Key, "true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.RouteData.Values.TryGetValue("storeId", out var storeId))
|
||||||
|
{
|
||||||
|
var userid = _userManager.GetUserId(principal);
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(userid))
|
||||||
{
|
{
|
||||||
identity.AddClaim(new Claim(Policies.CanModifyServerSettings.Key, "true"));
|
var store = await _StoreRepository.FindStore((string)storeId, userid);
|
||||||
}
|
if (store == null)
|
||||||
if (context.RouteData.Values.TryGetValue("storeId", out var storeId))
|
|
||||||
{
|
|
||||||
var claim = identity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
|
|
||||||
if (claim != null)
|
|
||||||
{
|
{
|
||||||
var store = await _StoreRepository.FindStore((string)storeId, claim.Value);
|
context.Result = new ChallengeResult();
|
||||||
if (store == null)
|
}
|
||||||
context.Result = new ChallengeResult(Policies.CookieAuthentication);
|
else
|
||||||
else
|
{
|
||||||
|
context.HttpContext.SetStoreData(store);
|
||||||
|
if (store != null)
|
||||||
{
|
{
|
||||||
context.HttpContext.SetStoreData(store);
|
identity.AddClaims(store.GetClaims());
|
||||||
if (store != null)
|
|
||||||
{
|
|
||||||
identity.AddClaims(store.GetClaims());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
|
||||||
using Microsoft.AspNetCore.Http.Extensions;
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -10,13 +8,9 @@ using System.Security.Claims;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using BTCPayServer.Authentication;
|
using BTCPayServer.Authentication;
|
||||||
using BTCPayServer.Models;
|
|
||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
using BTCPayServer.Services.Stores;
|
using BTCPayServer.Services.Stores;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBitcoin.DataEncoders;
|
using NBitcoin.DataEncoders;
|
||||||
@@ -27,7 +21,6 @@ using BTCPayServer.Logging;
|
|||||||
using Microsoft.AspNetCore.Http.Internal;
|
using Microsoft.AspNetCore.Http.Internal;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace BTCPayServer.Security
|
namespace BTCPayServer.Security
|
||||||
{
|
{
|
||||||
@@ -185,10 +178,10 @@ namespace BTCPayServer.Security
|
|||||||
return await _TokenRepository.GetStoreIdFromAPIKey(apiKey);
|
return await _TokenRepository.GetStoreIdFromAPIKey(apiKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal static void AddAuthentication(IServiceCollection services, Action<BitpayAuthOptions> bitpayAuth = null)
|
public static void AddAuthentication(AuthenticationBuilder builder, Action<BitpayAuthOptions> bitpayAuth = null)
|
||||||
{
|
{
|
||||||
bitpayAuth = bitpayAuth ?? new Action<BitpayAuthOptions>((o) => { });
|
bitpayAuth = bitpayAuth ?? new Action<BitpayAuthOptions>((o) => { });
|
||||||
services.AddAuthentication().AddScheme<BitpayAuthOptions, BitpayAuthHandler>(Policies.BitpayAuthentication, bitpayAuth);
|
builder.AddScheme<BitpayAuthOptions, BitpayAuthHandler>(Policies.BitpayAuthentication, bitpayAuth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
BTCPayServer/Security/BitpayAuthenticationExtensions.cs
Normal file
15
BTCPayServer/Security/BitpayAuthenticationExtensions.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
|
||||||
|
namespace BTCPayServer.Security
|
||||||
|
{
|
||||||
|
public static class BitpayAuthenticationExtensions
|
||||||
|
{
|
||||||
|
public static AuthenticationBuilder AddBitpayAuthentication(this AuthenticationBuilder builder,
|
||||||
|
Action<BitpayAuthentication.BitpayAuthOptions> bitpayAuth = null)
|
||||||
|
{
|
||||||
|
BitpayAuthentication.AddAuthentication(builder,bitpayAuth);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,8 +3,24 @@
|
|||||||
ViewData["Title"] = "Error";
|
ViewData["Title"] = "Error";
|
||||||
}
|
}
|
||||||
|
|
||||||
<h1 class="text-danger">Error.</h1>
|
<h1 class="text-danger">
|
||||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
@if (!string.IsNullOrEmpty(Model.Error)) {
|
||||||
|
<strong>@Model.Error</strong>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@:Error.
|
||||||
|
}
|
||||||
|
</h1>
|
||||||
|
<h2 class="text-danger">
|
||||||
|
@if (!string.IsNullOrEmpty(Model.ErrorDescription)) {
|
||||||
|
<small>@Model.ErrorDescription</small>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@:An error occurred while processing your request.
|
||||||
|
}
|
||||||
|
</h2>
|
||||||
|
|
||||||
@if(Model != null && Model.ShowRequestId)
|
@if(Model != null && Model.ShowRequestId)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user