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
|
||||
}
|
||||
|
||||
[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]
|
||||
[Trait("Integration", "Integration")]
|
||||
public void CanAcceptInvoiceWithTolerance()
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
<PackageReference Include="NicolasDorier.RateLimits" Version="1.0.0.3" />
|
||||
<PackageReference Include="NicolasDorier.StandardConfiguration" Version="1.0.0.18" />
|
||||
<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="Serilog" Version="2.7.1" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
|
||||
|
||||
@@ -6,13 +6,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using StandardConfiguration;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NBXplorer;
|
||||
using BTCPayServer.Payments.Lightning;
|
||||
using Renci.SshNet;
|
||||
using NBitcoin.DataEncoders;
|
||||
using BTCPayServer.SSH;
|
||||
using BTCPayServer.Lightning;
|
||||
using Serilog.Events;
|
||||
@@ -49,7 +43,7 @@ namespace BTCPayServer.Configuration
|
||||
private set;
|
||||
}
|
||||
public EndPoint SocksEndpoint { get; set; }
|
||||
|
||||
|
||||
public List<NBXplorerConnectionSetting> NBXplorerConnectionSettings
|
||||
{
|
||||
get;
|
||||
@@ -75,8 +69,7 @@ namespace BTCPayServer.Configuration
|
||||
public void LoadArgs(IConfiguration conf)
|
||||
{
|
||||
NetworkType = DefaultConfiguration.GetNetworkType(conf);
|
||||
var defaultSettings = BTCPayDefaultSettings.GetDefaultSettings(NetworkType);
|
||||
DataDir = conf.GetOrDefault<string>("datadir", defaultSettings.DefaultDataDirectory);
|
||||
DataDir = conf.GetDataDir(NetworkType);
|
||||
Logs.Configuration.LogInformation("Network: " + NetworkType.ToString());
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 IServiceCollection AddBTCPayServer(this IServiceCollection services)
|
||||
public static IServiceCollection AddBTCPayServer(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddDbContext<ApplicationDbContext>((provider, o) =>
|
||||
{
|
||||
@@ -67,7 +67,8 @@ namespace BTCPayServer.Hosting
|
||||
services.TryAddSingleton<SocketFactory>();
|
||||
services.TryAddSingleton<LightningClientFactoryService>();
|
||||
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 =>
|
||||
{
|
||||
var opts = o.GetRequiredService<BTCPayServerOptions>();
|
||||
@@ -219,7 +220,7 @@ namespace BTCPayServer.Hosting
|
||||
// bundling
|
||||
|
||||
services.AddAuthorization(o => Policies.AddBTCPayPolicies(o));
|
||||
BitpayAuthentication.AddAuthentication(services);
|
||||
services.AddBtcPayServerAuthenticationSchemes(configuration);
|
||||
|
||||
services.AddSingleton<IBundleProvider, ResourceBundleProvider>();
|
||||
services.AddTransient<BundleOptions>(provider =>
|
||||
@@ -231,9 +232,9 @@ namespace BTCPayServer.Hosting
|
||||
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();
|
||||
@@ -241,6 +242,13 @@ namespace BTCPayServer.Hosting
|
||||
services.AddSingleton(rateLimits);
|
||||
return services;
|
||||
}
|
||||
|
||||
private static void AddBtcPayServerAuthenticationSchemes(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddAuthentication()
|
||||
.AddCookie()
|
||||
.AddBitpayAuthentication();
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UsePayServer(this IApplicationBuilder app)
|
||||
{
|
||||
|
||||
@@ -67,9 +67,9 @@ namespace BTCPayServer.Hosting
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
services.AddSignalR();
|
||||
services.AddBTCPayServer();
|
||||
services.AddProviderStorage();
|
||||
services.AddSession();
|
||||
services.AddBTCPayServer(Configuration);
|
||||
services.AddMvc(o =>
|
||||
{
|
||||
o.Filters.Add(new XFrameOptionsAttribute("DENY"));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace BTCPayServer.Models
|
||||
{
|
||||
@@ -7,5 +8,11 @@ namespace BTCPayServer.Models
|
||||
public string RequestId { get; set; }
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace BTCPayServer.Security
|
||||
@@ -17,13 +12,13 @@ namespace BTCPayServer.Security
|
||||
|
||||
public class BTCPayClaimsFilter : IAsyncAuthorizationFilter, IConfigureOptions<MvcOptions>
|
||||
{
|
||||
UserManager<ApplicationUser> _UserManager;
|
||||
UserManager<ApplicationUser> _userManager;
|
||||
StoreRepository _StoreRepository;
|
||||
public BTCPayClaimsFilter(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
StoreRepository storeRepository)
|
||||
{
|
||||
_UserManager = userManager;
|
||||
_userManager = userManager;
|
||||
_StoreRepository = storeRepository;
|
||||
}
|
||||
|
||||
@@ -35,28 +30,34 @@ namespace BTCPayServer.Security
|
||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||
{
|
||||
var principal = context.HttpContext.User;
|
||||
if (!context.HttpContext.GetIsBitpayAPI())
|
||||
if (context.HttpContext.GetIsBitpayAPI())
|
||||
{
|
||||
var identity = ((ClaimsIdentity)principal.Identity);
|
||||
if (principal.IsInRole(Roles.ServerAdmin))
|
||||
return;
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
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, userid);
|
||||
if (store == null)
|
||||
{
|
||||
var store = await _StoreRepository.FindStore((string)storeId, claim.Value);
|
||||
if (store == null)
|
||||
context.Result = new ChallengeResult(Policies.CookieAuthentication);
|
||||
else
|
||||
context.Result = new ChallengeResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
context.HttpContext.SetStoreData(store);
|
||||
if (store != null)
|
||||
{
|
||||
context.HttpContext.SetStoreData(store);
|
||||
if (store != null)
|
||||
{
|
||||
identity.AddClaims(store.GetClaims());
|
||||
}
|
||||
identity.AddClaims(store.GetClaims());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -10,13 +8,9 @@ using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Authentication;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NBitcoin;
|
||||
using NBitcoin.DataEncoders;
|
||||
@@ -27,7 +21,6 @@ using BTCPayServer.Logging;
|
||||
using Microsoft.AspNetCore.Http.Internal;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace BTCPayServer.Security
|
||||
{
|
||||
@@ -185,10 +178,10 @@ namespace BTCPayServer.Security
|
||||
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) => { });
|
||||
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";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
<h1 class="text-danger">
|
||||
@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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user