mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-20 13:34:37 +01:00
Remove unused scope, assert policy on store listing
This commit is contained in:
parent
8643c04a39
commit
da2e8665a1
9 changed files with 76 additions and 194 deletions
|
@ -133,50 +133,51 @@ namespace BTCPayServer.Tests
|
|||
results = url.Split("#").Last().Split("&").ToDictionary(s1 => s1.Split("=")[0], s1 => s1.Split("=")[1]);
|
||||
await TestApiAgainstAccessToken(results["access_token"], tester, user);
|
||||
|
||||
LogoutFlow(tester, id, s);
|
||||
var stores = await TestApiAgainstAccessToken<StoreData[]>(results["access_token"],
|
||||
$"api/test/me/stores",
|
||||
tester.PayTester.HttpClient);
|
||||
Assert.NotEmpty(stores);
|
||||
|
||||
Assert.True(await TestApiAgainstAccessToken<bool>(results["access_token"],
|
||||
$"api/test/me/stores/{stores[0].Id}/can-edit",
|
||||
tester.PayTester.HttpClient));
|
||||
|
||||
//we dont ask for consent after acquiring it the first time for the same scopes.
|
||||
LogoutFlow(tester, id, s);
|
||||
s.Driver.Navigate().GoToUrl(implicitAuthorizeUrl);
|
||||
s.Login(user.RegisterDetails.Email, user.RegisterDetails.Password);
|
||||
|
||||
Assert.Throws<NoSuchElementException>(() => s.Driver.FindElement(By.Id("consent-yes")));
|
||||
results = url.Split("#").Last().Split("&")
|
||||
.ToDictionary(s1 => s1.Split("=")[0], s1 => s1.Split("=")[1]);
|
||||
await TestApiAgainstAccessToken(results["access_token"], tester, user);
|
||||
|
||||
//let's test out scopes!
|
||||
s.Driver.AssertElementNotFound(By.Id("consent-yes"));
|
||||
|
||||
// Let's asks without scopes
|
||||
LogoutFlow(tester, id, s);
|
||||
id = Guid.NewGuid().ToString();
|
||||
openIdClient = await user.RegisterOpenIdClient(
|
||||
new OpenIddictApplicationDescriptor()
|
||||
{
|
||||
ClientId = id,
|
||||
DisplayName = id,
|
||||
Permissions = { OpenIddictConstants.Permissions.GrantTypes.Implicit },
|
||||
RedirectUris = { redirecturi },
|
||||
});
|
||||
implicitAuthorizeUrl = new Uri(tester.PayTester.ServerUri,
|
||||
$"connect/authorize?response_type=token&client_id={id}&redirect_uri={redirecturi.AbsoluteUri}&scope=openid {RestAPIPolicies.BTCPayScopes.AppManagement} {RestAPIPolicies.BTCPayScopes.ViewStores} &nonce={Guid.NewGuid().ToString()}");
|
||||
|
||||
$"connect/authorize?response_type=token&client_id={id}&redirect_uri={redirecturi.AbsoluteUri}&scope=openid&nonce={Guid.NewGuid().ToString()}");
|
||||
s.Driver.Navigate().GoToUrl(implicitAuthorizeUrl);
|
||||
//authorize form should show now that we have asked for more scopes
|
||||
s.Login(user.RegisterDetails.Email, user.RegisterDetails.Password);
|
||||
s.Driver.FindElement(By.Id("consent-yes")).Click();
|
||||
url = s.Driver.Url;
|
||||
results = url.Split("#").Last().Split("&")
|
||||
results = s.Driver.Url.Split("#").Last().Split("&")
|
||||
.ToDictionary(s1 => s1.Split("=")[0], s1 => s1.Split("=")[1]);
|
||||
|
||||
|
||||
Assert.True(await TestApiAgainstAccessToken<bool>(results["access_token"],
|
||||
$"api/test/ScopeCanViewApps",
|
||||
tester.PayTester.HttpClient));
|
||||
|
||||
Assert.True(await TestApiAgainstAccessToken<bool>(results["access_token"],
|
||||
$"api/test/ScopeCanManageApps",
|
||||
tester.PayTester.HttpClient));
|
||||
|
||||
Assert.True(await TestApiAgainstAccessToken<bool>(results["access_token"],
|
||||
$"api/test/ScopeCanViewStores",
|
||||
tester.PayTester.HttpClient));
|
||||
await Assert.ThrowsAnyAsync<HttpRequestException>(async () =>
|
||||
{
|
||||
await TestApiAgainstAccessToken<bool>(results["access_token"],
|
||||
$"api/test/ScopeCanManageStores",
|
||||
tester.PayTester.HttpClient);
|
||||
await TestApiAgainstAccessToken<StoreData[]>(results["access_token"],
|
||||
$"api/test/me/stores",
|
||||
tester.PayTester.HttpClient);
|
||||
});
|
||||
await Assert.ThrowsAnyAsync<HttpRequestException>(async () =>
|
||||
{
|
||||
await TestApiAgainstAccessToken<bool>(results["access_token"],
|
||||
$"api/test/ScopeCanViewProfile",
|
||||
tester.PayTester.HttpClient);
|
||||
$"api/test/me/stores/{stores[0].Id}/can-edit",
|
||||
tester.PayTester.HttpClient);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using OpenIddict.Abstractions;
|
||||
|
||||
namespace BTCPayServer.Authentication
|
||||
{
|
||||
public static class RestAPIPolicies
|
||||
{
|
||||
public static class BTCPayScopes
|
||||
{
|
||||
public const string ViewStores = "view_stores";
|
||||
|
||||
//Create and manage stores
|
||||
public const string StoreManagement = "store_management";
|
||||
|
||||
//create and manage invoices
|
||||
public const string ViewInvoices = "view_invoices";
|
||||
|
||||
//create and manage invoices
|
||||
public const string CreateInvoices = "create_invoice";
|
||||
|
||||
public const string InvoiceManagement = "manage_invoices";
|
||||
|
||||
//view apps
|
||||
public const string ViewApps = "view_apps";
|
||||
|
||||
//create and manage apps
|
||||
public const string AppManagement = "app_management";
|
||||
public const string WalletManagement = "wallet_management";
|
||||
public const string ServerManagement = "server_management";
|
||||
}
|
||||
|
||||
public const string CanViewStores = nameof(CanViewStores);
|
||||
public const string CanManageStores = nameof(CanManageStores);
|
||||
public const string CanViewInvoices = nameof(CanViewInvoices);
|
||||
public const string CanCreateInvoices = nameof(CanCreateInvoices);
|
||||
public const string CanManageInvoices = nameof(CanManageInvoices);
|
||||
public const string CanManageApps = nameof(CanManageApps);
|
||||
public const string CanViewApps = nameof(CanViewApps);
|
||||
public const string CanManageWallet = nameof(CanManageWallet);
|
||||
public const string CanViewProfile = nameof(CanViewProfile);
|
||||
}
|
||||
}
|
|
@ -48,6 +48,8 @@ namespace BTCPayServer.Controllers.RestApi
|
|||
}
|
||||
|
||||
[HttpGet("me/stores")]
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings.Key,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
public async Task<StoreData[]> GetCurrentUserStores()
|
||||
{
|
||||
return await _storeRepository.GetStoresByUserId(_userManager.GetUserId(User));
|
||||
|
@ -61,56 +63,5 @@ namespace BTCPayServer.Controllers.RestApi
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#region scopes tests
|
||||
|
||||
[Authorize(Policy = RestAPIPolicies.CanViewStores,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
[HttpGet(nameof(ScopeCanViewStores))]
|
||||
public bool ScopeCanViewStores() { return true; }
|
||||
|
||||
[Authorize(Policy = RestAPIPolicies.CanManageStores,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
[HttpGet(nameof(ScopeCanManageStores))]
|
||||
public bool ScopeCanManageStores() { return true; }
|
||||
|
||||
[Authorize(Policy = RestAPIPolicies.CanViewInvoices,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
[HttpGet(nameof(ScopeCanViewInvoices))]
|
||||
public bool ScopeCanViewInvoices() { return true; }
|
||||
|
||||
[Authorize(Policy = RestAPIPolicies.CanCreateInvoices,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
[HttpGet(nameof(ScopeCanCreateInvoices))]
|
||||
public bool ScopeCanCreateInvoices() { return true; }
|
||||
|
||||
[Authorize(Policy = RestAPIPolicies.CanManageInvoices,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
[HttpGet(nameof(ScopeCanManageInvoices))]
|
||||
public bool ScopeCanManageInvoices() { return true; }
|
||||
|
||||
[Authorize(Policy = RestAPIPolicies.CanManageApps,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
[HttpGet(nameof(ScopeCanManageApps))]
|
||||
public bool ScopeCanManageApps() { return true; }
|
||||
|
||||
[Authorize(Policy = RestAPIPolicies.CanViewApps,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
|
||||
[HttpGet(nameof(ScopeCanViewApps))]
|
||||
public bool ScopeCanViewApps() { return true; }
|
||||
|
||||
[Authorize(Policy = RestAPIPolicies.CanManageWallet,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
[HttpGet(nameof(ScopeCanManageWallet))]
|
||||
public bool ScopeCanManageWallet() { return true; }
|
||||
|
||||
[Authorize(Policy = RestAPIPolicies.CanViewProfile,
|
||||
AuthenticationSchemes = AuthenticationSchemes.OpenId)]
|
||||
[HttpGet(nameof(ScopeCanViewProfile))]
|
||||
public bool ScopeCanViewProfile() { return true; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,13 +184,9 @@ namespace BTCPayServer.Hosting
|
|||
|
||||
options.RegisterScopes(
|
||||
OpenIddictConstants.Scopes.OpenId,
|
||||
RestAPIPolicies.BTCPayScopes.ViewStores,
|
||||
RestAPIPolicies.BTCPayScopes.CreateInvoices,
|
||||
RestAPIPolicies.BTCPayScopes.StoreManagement,
|
||||
RestAPIPolicies.BTCPayScopes.ViewApps,
|
||||
RestAPIPolicies.BTCPayScopes.ServerManagement,
|
||||
RestAPIPolicies.BTCPayScopes.AppManagement
|
||||
);
|
||||
BTCPayScopes.StoreManagement,
|
||||
BTCPayScopes.ServerManagement
|
||||
);
|
||||
options.AddEventHandler(PasswordGrantTypeEventHandler.Descriptor);
|
||||
options.AddEventHandler(OpenIdGrantHandlerCheckCanSignIn.Descriptor);
|
||||
options.AddEventHandler(ClientCredentialsGrantTypeEventHandler.Descriptor);
|
||||
|
|
19
BTCPayServer/Security/OpenId/BTCPayScopes.cs
Normal file
19
BTCPayServer/Security/OpenId/BTCPayScopes.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using OpenIddict.Abstractions;
|
||||
|
||||
namespace BTCPayServer.Security.OpenId
|
||||
{
|
||||
public static class BTCPayScopes
|
||||
{
|
||||
public const string StoreManagement = "store_management";
|
||||
public const string ServerManagement = "server_management";
|
||||
}
|
||||
public static class RestAPIPolicies
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Identity;
|
|||
using OpenIddict.Abstractions;
|
||||
using OpenIddict.Core;
|
||||
using OpenIddict.Server;
|
||||
using static BTCPayServer.Authentication.RestAPIPolicies;
|
||||
|
||||
namespace BTCPayServer.Security.OpenId
|
||||
{
|
||||
|
@ -93,7 +92,7 @@ namespace BTCPayServer.Security.OpenId
|
|||
await Task.WhenAll(scopeTasks.Select((tuple) => tuple.Item1));
|
||||
|
||||
var authorizationsWithSufficientScopes = scopeTasks
|
||||
.Select((tuple) => (tuple.Id, Scopes: tuple.Item1.Result))
|
||||
.Select((tuple) => (Id: tuple.Id, Scopes: tuple.Item1.Result))
|
||||
.Where((tuple) => !request.GetScopes().Except(tuple.Scopes).Any());
|
||||
|
||||
if (authorizationsWithSufficientScopes.Any())
|
||||
|
|
|
@ -11,8 +11,9 @@ using Microsoft.AspNetCore.Routing;
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
using BTCPayServer.Authentication;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using static BTCPayServer.Authentication.RestAPIPolicies;
|
||||
using static BTCPayServer.Security.OpenId.RestAPIPolicies;
|
||||
using OpenIddict.Abstractions;
|
||||
using BTCPayServer.Security.OpenId;
|
||||
|
||||
namespace BTCPayServer.Security
|
||||
{
|
||||
|
@ -38,33 +39,6 @@ namespace BTCPayServer.Security
|
|||
bool success = false;
|
||||
switch (requirement.Policy)
|
||||
{
|
||||
case RestAPIPolicies.CanViewStores:
|
||||
success = context.HasScopes(BTCPayScopes.StoreManagement) || context.HasScopes(BTCPayScopes.ViewStores);
|
||||
break;
|
||||
case RestAPIPolicies.CanManageStores:
|
||||
success = context.HasScopes(BTCPayScopes.StoreManagement);
|
||||
break;
|
||||
case RestAPIPolicies.CanViewInvoices:
|
||||
success = context.HasScopes(BTCPayScopes.ViewInvoices) || context.HasScopes(BTCPayScopes.InvoiceManagement);
|
||||
break;
|
||||
case RestAPIPolicies.CanCreateInvoices:
|
||||
success = context.HasScopes(BTCPayScopes.CreateInvoices) || context.HasScopes(BTCPayScopes.InvoiceManagement);
|
||||
break;
|
||||
case RestAPIPolicies.CanViewApps:
|
||||
success = context.HasScopes(BTCPayScopes.AppManagement) || context.HasScopes(BTCPayScopes.ViewApps);
|
||||
break;
|
||||
case RestAPIPolicies.CanManageInvoices:
|
||||
success = context.HasScopes(BTCPayScopes.InvoiceManagement);
|
||||
break;
|
||||
case RestAPIPolicies.CanManageApps:
|
||||
success = context.HasScopes(BTCPayScopes.AppManagement);
|
||||
break;
|
||||
case RestAPIPolicies.CanManageWallet:
|
||||
success = context.HasScopes(BTCPayScopes.WalletManagement);
|
||||
break;
|
||||
case RestAPIPolicies.CanViewProfile:
|
||||
success = context.HasScopes(OpenIddictConstants.Scopes.Profile);
|
||||
break;
|
||||
case Policies.CanModifyStoreSettings.Key:
|
||||
if (!context.HasScopes(BTCPayScopes.StoreManagement))
|
||||
break;
|
||||
|
@ -73,15 +47,20 @@ namespace BTCPayServer.Security
|
|||
// to the access_token
|
||||
string storeId = _HttpContext.GetImplicitStoreId();
|
||||
if (storeId == null)
|
||||
break;
|
||||
var userid = _userManager.GetUserId(context.User);
|
||||
if (string.IsNullOrEmpty(userid))
|
||||
break;
|
||||
var store = await _storeRepository.FindStore((string)storeId, userid);
|
||||
if (store == null)
|
||||
break;
|
||||
success = true;
|
||||
_HttpContext.SetStoreData(store);
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var userid = _userManager.GetUserId(context.User);
|
||||
if (string.IsNullOrEmpty(userid))
|
||||
break;
|
||||
var store = await _storeRepository.FindStore((string)storeId, userid);
|
||||
if (store == null)
|
||||
break;
|
||||
success = true;
|
||||
_HttpContext.SetStoreData(store);
|
||||
}
|
||||
break;
|
||||
case Policies.CanModifyServerSettings.Key:
|
||||
if (!context.HasScopes(BTCPayScopes.ServerManagement))
|
||||
|
|
|
@ -15,16 +15,6 @@ namespace BTCPayServer.Security
|
|||
options.AddPolicy(CanCreateInvoice.Key);
|
||||
options.AddPolicy(CanGetRates.Key);
|
||||
options.AddPolicy(CanModifyServerSettings.Key);
|
||||
|
||||
options.AddPolicy(RestAPIPolicies.CanCreateInvoices);
|
||||
options.AddPolicy(RestAPIPolicies.CanManageApps);
|
||||
options.AddPolicy(RestAPIPolicies.CanManageInvoices);
|
||||
options.AddPolicy(RestAPIPolicies.CanManageStores);
|
||||
options.AddPolicy(RestAPIPolicies.CanManageWallet);
|
||||
options.AddPolicy(RestAPIPolicies.CanViewApps);
|
||||
options.AddPolicy(RestAPIPolicies.CanViewInvoices);
|
||||
options.AddPolicy(RestAPIPolicies.CanViewProfile);
|
||||
options.AddPolicy(RestAPIPolicies.CanViewStores);
|
||||
return options;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,20 +1,13 @@
|
|||
@using BTCPayServer.Authentication
|
||||
@using BTCPayServer.Security.OpenId
|
||||
@using OpenIddict.Abstractions
|
||||
@model BTCPayServer.Models.Authorization.AuthorizeViewModel
|
||||
@{
|
||||
|
||||
var scopeMappings = new Dictionary<string, (string Title, string Description)>()
|
||||
{
|
||||
{RestAPIPolicies.BTCPayScopes.AppManagement, ("Manage your apps", "The app will be able to create, modify and delete all your apps.")},
|
||||
{RestAPIPolicies.BTCPayScopes.ViewApps, ("View your apps", "The app will be able to list and view all your apps.")},
|
||||
{RestAPIPolicies.BTCPayScopes.CreateInvoices, ("Create invoices", "The app will be able to create new invoices.")},
|
||||
{RestAPIPolicies.BTCPayScopes.InvoiceManagement, ("Manage invoices", "The app will be able to create new invoices and mark existing invoices as complete or invalid.")},
|
||||
{RestAPIPolicies.BTCPayScopes.StoreManagement, ("Manage your stores", "The app will be able to create, modify and delete all your stores.")},
|
||||
{RestAPIPolicies.BTCPayScopes.ViewStores, ("View your stores", "The app will be able to list and view all your stores.")},
|
||||
{RestAPIPolicies.BTCPayScopes.WalletManagement, ("Manage your wallet", "The app will be able to manage your wallet associate to stores. This includes configuring it, transaction creation and signing.")},
|
||||
{RestAPIPolicies.BTCPayScopes.ServerManagement, ("Manage your server", "The app will have total control on your server")},
|
||||
{RestAPIPolicies.BTCPayScopes.ViewInvoices, ("View your invoices", "The app will be able to list and view all your apps.")},
|
||||
};
|
||||
{BTCPayScopes.StoreManagement, ("Manage your stores", "The app will be able to create, modify and delete all your stores.")},
|
||||
{BTCPayScopes.ServerManagement, ("Manage your server", "The app will have total control on your server")},
|
||||
};
|
||||
}
|
||||
<form method="post">
|
||||
<input type="hidden" name="request_id" value="@Model.RequestId"/>
|
||||
|
|
Loading…
Add table
Reference in a new issue