Rename permissions for offerings (#7021)
What changed, and why it matters
This commit simply renames two permission strings from 'membership' to 'offerings' across the codebase. It is a non-functional refactor that updates labels, constants, authorization checks, and API documentation to match the new terminology. There is no security-relevant change.
No action required; this is a benign terminology refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change renames the permission constants CanViewMembership/CanModifyMembership to CanViewOfferings/CanModifyOfferings and updates all references in policy lists, controller [Authorize] attributes, Razor view permission/not-permission directives, and the Swagger description. The permission semantics and access-control behavior remain identical.
Changed components
BTCPayServer.Client/Permissions.csBTCPayServer/Controllers/UIManageController.APIKeys.csBTCPayServer/Plugins/Subscriptions/Controllers/UIOfferingController.csBTCPayServer/Plugins/Subscriptions/Views/NavExtension.cshtmlBTCPayServer/Plugins/Subscriptions/Views/UIOffering/Offering.cshtmlBTCPayServer/wwwroot/swagger/v1/swagger.template.jsonInspect captured patch +25 / −26
diff --git a/BTCPayServer.Client/Permissions.cs b/BTCPayServer.Client/Permissions.cs
index 8a1fc9f..9f46be3 100644
--- a/BTCPayServer.Client/Permissions.cs
+++ b/BTCPayServer.Client/Permissions.cs
@@ -40,8 +40,8 @@ namespace BTCPayServer.Client
public const string CanViewPayouts = "btcpay.store.canviewpayouts";
public const string CanCreatePullPayments = "btcpay.store.cancreatepullpayments";
public const string CanViewPullPayments = "btcpay.store.canviewpullpayments";
- public const string CanViewMembership = "btcpay.store.canviewmembership";
- public const string CanModifyMembership = "btcpay.store.canmodifymembership";
+ public const string CanViewOfferings = "btcpay.store.canviewofferings";
+ public const string CanModifyOfferings = "btcpay.store.canmodifyofferings";
public const string CanCreateNonApprovedPullPayments = "btcpay.store.cancreatenonapprovedpullpayments";
public const string Unrestricted = "unrestricted";
public static IEnumerable<string> AllPolicies
@@ -76,8 +76,8 @@ namespace BTCPayServer.Client
yield return CanArchivePullPayments;
yield return CanCreatePullPayments;
yield return CanViewPullPayments;
- yield return CanViewMembership;
- yield return CanModifyMembership;
+ yield return CanViewOfferings;
+ yield return CanModifyOfferings;
yield return CanCreateNonApprovedPullPayments;
yield return CanManageUsers;
yield return CanManagePayouts;
@@ -265,7 +265,7 @@ namespace BTCPayServer.Client
Policies.CanModifyWebhooks,
Policies.CanModifyPaymentRequests,
Policies.CanManagePayouts,
- Policies.CanModifyMembership,
+ Policies.CanModifyOfferings,
Policies.CanUseLightningNodeInStore);
PolicyHasChild(policyMap,Policies.CanManageUsers, Policies.CanCreateUser);
@@ -274,7 +274,7 @@ namespace BTCPayServer.Client
PolicyHasChild(policyMap, Policies.CanCreateNonApprovedPullPayments, Policies.CanViewPullPayments);
PolicyHasChild(policyMap,Policies.CanModifyPaymentRequests, Policies.CanViewPaymentRequests);
PolicyHasChild(policyMap,Policies.CanModifyProfile, Policies.CanViewProfile);
- PolicyHasChild(policyMap,Policies.CanModifyMembership, Policies.CanViewMembership);
+ PolicyHasChild(policyMap,Policies.CanModifyOfferings, Policies.CanViewOfferings);
PolicyHasChild(policyMap,Policies.CanUseLightningNodeInStore, Policies.CanViewLightningInvoiceInStore, Policies.CanCreateLightningInvoiceInStore);
PolicyHasChild(policyMap,Policies.CanManageNotificationsForUser, Policies.CanViewNotificationsForUser);
PolicyHasChild(policyMap,Policies.CanModifyServerSettings,
diff --git a/BTCPayServer/Controllers/UIManageController.APIKeys.cs b/BTCPayServer/Controllers/UIManageController.APIKeys.cs
index 77ba431..46b71f5 100644
--- a/BTCPayServer/Controllers/UIManageController.APIKeys.cs
+++ b/BTCPayServer/Controllers/UIManageController.APIKeys.cs
@@ -538,10 +538,10 @@ namespace BTCPayServer.Controllers
{$"{Policies.CanViewPaymentRequests}:", ("View your payment requests", "Allows viewing the selected stores' payment requests.")},
{Policies.CanViewPullPayments, ("View your pull payments", "Allows viewing pull payments on all your stores.")},
{$"{Policies.CanViewPullPayments}:", ("View selected stores' pull payments", "Allows viewing pull payments on the selected stores.")},
- {Policies.CanViewMembership, ("View your membership", "Allows viewing membership on all your stores.")},
- {$"{Policies.CanViewMembership}:", ("View your membership", "Allows viewing membership on the selected stores.")},
- {Policies.CanModifyMembership, ("Modify your membership", "Allows modifying membership on all your stores.")},
- {$"{Policies.CanModifyMembership}:", ("Modify your membership", "Allows modifying membership on the selected stores.")},
+ {Policies.CanViewOfferings, ("View your offerings", "Allows viewing offerings on all your stores.")},
+ {$"{Policies.CanViewOfferings}:", ("View your offerings", "Allows viewing offerings on the selected stores.")},
+ {Policies.CanModifyOfferings, ("Modify your offerings", "Allows modifying offerings on all your stores.")},
+ {$"{Policies.CanModifyOfferings}:", ("Modify your offerings", "Allows modifying offerings on the selected stores.")},
{Policies.CanManagePullPayments, ("Manage your pull payments", "Allows viewing, modifying, deleting and creating pull payments on all your stores.")},
{$"{Policies.CanManagePullPayments}:", ("Manage selected stores' pull payments", "Allows viewing, modifying, deleting and creating pull payments on the selected stores.")},
{Policies.CanArchivePullPayments, ("Archive your pull payments", "Allows deleting pull payments on all your stores.")},
diff --git a/BTCPayServer/Plugins/Subscriptions/Controllers/UIOfferingController.cs b/BTCPayServer/Plugins/Subscriptions/Controllers/UIOfferingController.cs
index 8d3ac6d..974d427 100644
--- a/BTCPayServer/Plugins/Subscriptions/Controllers/UIOfferingController.cs
+++ b/BTCPayServer/Plugins/Subscriptions/Controllers/UIOfferingController.cs
@@ -1,6 +1,5 @@
#nullable enable
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Constants;
@@ -28,7 +27,7 @@ using DisplayFormatter = BTCPayServer.Services.DisplayFormatter;
namespace BTCPayServer.Plugins.Subscriptions.Controllers;
-[Authorize(Policy = Policies.CanViewMembership, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
+[Authorize(Policy = Policies.CanViewOfferings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
[AutoValidateAntiforgeryToken]
[Area(SubscriptionsPlugin.Area)]
public partial class UIOfferingController(
@@ -45,7 +44,7 @@ public partial class UIOfferingController(
) : UISubscriptionControllerBase(dbContextFactory, linkGenerator, stringLocalizer, subsService)
{
[HttpPost("stores/{storeId}/offerings/{offeringId}/new-subscriber")]
- [Authorize(Policy = Policies.CanModifyMembership, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
+ [Authorize(Policy = Policies.CanModifyOfferings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> NewSubscriber(
string storeId, string offeringId,
string planId,
@@ -97,7 +96,7 @@ public partial class UIOfferingController(
=> displayFormatter.Currency(req?.Amount ?? 0m, req?.Currency ?? "USD", DisplayFormatter.CurrencyFormat.CodeAndSymbol);
[HttpPost("stores/{storeId}/offerings/{offeringId}/Subscribers")]
- [Authorize(Policy = Policies.CanModifyMembership, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
+ [Authorize(Policy = Policies.CanModifyOfferings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> SubscriberSuspend(string storeId, string offeringId, string customerId, string? command = null,
string? suspensionReason = null, decimal? amount = null, string? description = null)
{
@@ -346,7 +345,7 @@ public partial class UIOfferingController(
}
[HttpGet("stores/{storeId}/offerings/{offeringId}/configure")]
- [Authorize(Policy = Policies.CanModifyMembership, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
+ [Authorize(Policy = Policies.CanModifyOfferings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> ConfigureOffering(string storeId, string offeringId)
{
await using var ctx = DbContextFactory.CreateContext();
@@ -435,7 +434,7 @@ public partial class UIOfferingController(
}
[HttpPost("stores/{storeId}/offerings/{offeringId}/plans/{planId}/delete-plan")]
- [Authorize(Policy = Policies.CanModifyMembership, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
+ [Authorize(Policy = Policies.CanModifyOfferings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> DeletePlan(string storeId, string offeringId, string planId)
{
await using var ctx = DbContextFactory.CreateContext();
@@ -463,7 +462,7 @@ public partial class UIOfferingController(
[HttpGet("stores/{storeId}/offerings/{offeringId}/add-plan")]
[HttpGet("stores/{storeId}/offerings/{offeringId}/plans/{planId}/edit")]
- [Authorize(Policy = Policies.CanModifyMembership, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
+ [Authorize(Policy = Policies.CanModifyOfferings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> AddPlan(string storeId, string offeringId, string? planId = null)
{
await using var ctx = DbContextFactory.CreateContext();
@@ -513,7 +512,7 @@ public partial class UIOfferingController(
[HttpPost("stores/{storeId}/offerings/{offeringId}/add-plan")]
[HttpPost("stores/{storeId}/offerings/{offeringId}/plans/{planId}/edit")]
- [Authorize(Policy = Policies.CanModifyMembership, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
+ [Authorize(Policy = Policies.CanModifyOfferings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> AddPlan(string storeId, string offeringId, AddEditPlanViewModel vm, string? planId = null, string? command = null,
int? removeIndex = null)
{
@@ -604,7 +603,7 @@ public partial class UIOfferingController(
}
[HttpGet("stores/{storeId}/offerings/{offeringId}/subscribers/{customerId}/create-portal")]
- [Authorize(Policy = Policies.CanModifyMembership, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
+ [Authorize(Policy = Policies.CanModifyOfferings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task<IActionResult> CreatePortalSession(string storeId, string offeringId, string customerId)
{
await using var ctx = DbContextFactory.CreateContext();
diff --git a/BTCPayServer/Plugins/Subscriptions/Views/NavExtension.cshtml b/BTCPayServer/Plugins/Subscriptions/Views/NavExtension.cshtml
index 0f98530..d71a151 100644
--- a/BTCPayServer/Plugins/Subscriptions/Views/NavExtension.cshtml
+++ b/BTCPayServer/Plugins/Subscriptions/Views/NavExtension.cshtml
@@ -15,7 +15,7 @@
{
var appType = SubscriptionsAppType.AppType;
var apps = Model.Apps.Where(app => app.AppType == appType).ToList();
- <li class="nav-item" permission="@Policies.CanModifyMembership">
+ <li class="nav-item" permission="@Policies.CanModifyOfferings">
<a layout-menu-item="@nameof(SubscriptionsPlugin)" asp-area="Subscriptions" asp- asp-controller="UIOffering" asp-action="CreateOffering" asp-route-storeId="@store.Id">
<vc:icon symbol="nav-reporting" />
<span text-translate="true">Subscriptions</span>
@@ -23,7 +23,7 @@
</li>
@if (apps.Any())
{
- <li layout-menu-item="@nameof(SubscriptionsPlugin)" not-permission="@Policies.CanModifyMembership" permission="@Policies.CanViewStoreSettings">
+ <li layout-menu-item="@nameof(SubscriptionsPlugin)" not-permission="@Policies.CanModifyOfferings" permission="@Policies.CanViewStoreSettings">
<span class="nav-link">
<vc:icon symbol="nav-reporting" />
<span text-translate="true">Subscriptions</span>
@@ -34,12 +34,12 @@
{
var offeringId = app.Data.GetSettings<SubscriptionsAppType.AppConfig>().OfferingId ?? "";
- <li class="nav-item nav-item-sub" permission="@Policies.CanViewMembership">
+ <li class="nav-item nav-item-sub" permission="@Policies.CanViewOfferings">
<a layout-menu-item="@nameof(SubscriptionsPlugin)-@offeringId" asp-area="Subscriptions" asp-controller="UIOffering" asp-action="Offering" asp-route-storeId="@Model.Store.Id" asp-route-offeringId="@offeringId" asp-route-section="Plans">
<span>@app.AppName</span>
</a>
</li>
- <li class="nav-item nav-item-sub" not-permission="@Policies.CanViewMembership">
+ <li class="nav-item nav-item-sub" not-permission="@Policies.CanViewOfferings">
<a layout-menu-item="@nameof(SubscriptionsPlugin)-@offeringId" asp-area="Subscriptions" asp-controller="UIOffering" asp-action="Offering" asp-route-storeId="@Model.Store.Id" asp-route-offeringId="@offeringId" asp-route-section="Plans" class="nav-link">
<span>@app.AppName</span>
</a>
diff --git a/BTCPayServer/Plugins/Subscriptions/Views/UIOffering/Offering.cshtml b/BTCPayServer/Plugins/Subscriptions/Views/UIOffering/Offering.cshtml
index e27a846..ffb920d 100644
--- a/BTCPayServer/Plugins/Subscriptions/Views/UIOffering/Offering.cshtml
+++ b/BTCPayServer/Plugins/Subscriptions/Views/UIOffering/Offering.cshtml
@@ -75,7 +75,7 @@
{
<div class="d-flex justify-content-between align-items-center">
<h4>Plans</h4>
- <a id="page-primary" permission="@Policies.CanModifyMembership" asp-route-storeId="@storeId" asp-route-offeringId="@offeringId" asp-action="AddPlan"
+ <a id="page-primary" permission="@Policies.CanModifyOfferings" asp-route-storeId="@storeId" asp-route-offeringId="@offeringId" asp-action="AddPlan"
class="btn btn-primary"
role="button"
text-translate="true">Add Plan</a>
@@ -180,7 +180,7 @@
{
<a
href="#"
- permission="@Policies.CanModifyMembership"
+ permission="@Policies.CanModifyOfferings"
text-translate="true"
role="button"
id="page-primary"
diff --git a/BTCPayServer/wwwroot/swagger/v1/swagger.template.json b/BTCPayServer/wwwroot/swagger/v1/swagger.template.json
index b5c6d25..b64beb8 100644
--- a/BTCPayServer/wwwroot/swagger/v1/swagger.template.json
+++ b/BTCPayServer/wwwroot/swagger/v1/swagger.template.json
@@ -206,7 +206,7 @@
"securitySchemes": {
"API_Key": {
"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.\n\n The following permissions are available to the context of the user creating the API Key:\n\n* `unrestricted`: Unrestricted access\n* `btcpay.user.candeleteuser`: Delete user\n* `btcpay.user.canviewprofile`: View your profile\n* `btcpay.user.canmodifyprofile`: Manage your profile\n* `btcpay.user.canmanagenotificationsforuser`: Manage your notifications\n* `btcpay.user.canviewnotificationsforuser`: View your notifications\n\nThe following permissions are available if the user is an administrator:\n\n* `btcpay.server.canviewusers`: View users\n* `btcpay.server.cancreateuser`: Create new users\n* `btcpay.server.canmanageusers`: Manage users\n* `btcpay.server.canmodifyserversettings`: Manage your server\n* `btcpay.server.canuseinternallightningnode`: Use the internal lightning node\n* `btcpay.server.canviewlightninginvoiceinternalnode`: View invoices from internal lightning node\n* `btcpay.server.cancreatelightninginvoiceinternalnode`: Create invoices with internal lightning node\n\nThe following permissions applies to all stores of the user, you can limit to a specific store with the following format: `btcpay.store.cancreateinvoice:6HSHAEU4iYWtjxtyRs9KyPjM9GAQp8kw2T9VWbGG1FnZ`:\n\n* `btcpay.store.canmodifystoresettings`: Modify your stores\n* `btcpay.store.webhooks.canmodifywebhooks`: Modify stores webhooks\n* `btcpay.store.canviewstoresettings`: View your stores\n* `btcpay.store.canviewreports`: View your reports\n* `btcpay.store.cancreateinvoice`: Create an invoice\n* `btcpay.store.canviewinvoices`: View invoices\n* `btcpay.store.canmodifyinvoices`: Modify invoices\n* `btcpay.store.canmodifypaymentrequests`: Modify your payment requests\n* `btcpay.store.canviewpaymentrequests`: View your payment requests\n* `btcpay.store.canviewpullpayments`: View your pull payments\n* `btcpay.store.canviewmembership`: View your membership\n* `btcpay.store.canmodifymembership`: Modify your membership\n* `btcpay.store.canmanagepullpayments`: Manage your pull payments\n* `btcpay.store.canarchivepullpayments`: Archive your pull payments\n* `btcpay.store.cancreatepullpayments`: Create pull payments\n* `btcpay.store.canmanagepayouts`: Manage payouts\n* `btcpay.store.canviewpayouts`: View payouts\n* `btcpay.store.cancreatenonapprovedpullpayments`: Create non-approved pull payments\n* `btcpay.store.canuselightningnode`: Use the lightning nodes associated with your stores\n* `btcpay.store.canviewlightninginvoice`: View the lightning invoices associated with your stores\n* `btcpay.store.cancreatelightninginvoice`: Create invoices from the lightning nodes associated with your stores\n\nNote that API Keys only limits permission of a user and can never expand it. If an API Key has the permission `btcpay.server.canmodifyserversettings` but that the user account creating this API Key is not administrator, the API Key will not be able to modify the server settings.\nSome permissions may include other permissions, see [this operation](#operation/permissionsMetadata).\n",
+ "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.\n\n The following permissions are available to the context of the user creating the API Key:\n\n* `unrestricted`: Unrestricted access\n* `btcpay.user.candeleteuser`: Delete user\n* `btcpay.user.canviewprofile`: View your profile\n* `btcpay.user.canmodifyprofile`: Manage your profile\n* `btcpay.user.canmanagenotificationsforuser`: Manage your notifications\n* `btcpay.user.canviewnotificationsforuser`: View your notifications\n\nThe following permissions are available if the user is an administrator:\n\n* `btcpay.server.canviewusers`: View users\n* `btcpay.server.cancreateuser`: Create new users\n* `btcpay.server.canmanageusers`: Manage users\n* `btcpay.server.canmodifyserversettings`: Manage your server\n* `btcpay.server.canuseinternallightningnode`: Use the internal lightning node\n* `btcpay.server.canviewlightninginvoiceinternalnode`: View invoices from internal lightning node\n* `btcpay.server.cancreatelightninginvoiceinternalnode`: Create invoices with internal lightning node\n\nThe following permissions applies to all stores of the user, you can limit to a specific store with the following format: `btcpay.store.cancreateinvoice:6HSHAEU4iYWtjxtyRs9KyPjM9GAQp8kw2T9VWbGG1FnZ`:\n\n* `btcpay.store.canmodifystoresettings`: Modify your stores\n* `btcpay.store.webhooks.canmodifywebhooks`: Modify stores webhooks\n* `btcpay.store.canviewstoresettings`: View your stores\n* `btcpay.store.canviewreports`: View your reports\n* `btcpay.store.cancreateinvoice`: Create an invoice\n* `btcpay.store.canviewinvoices`: View invoices\n* `btcpay.store.canmodifyinvoices`: Modify invoices\n* `btcpay.store.canmodifypaymentrequests`: Modify your payment requests\n* `btcpay.store.canviewpaymentrequests`: View your payment requests\n* `btcpay.store.canviewpullpayments`: View your pull payments\n* `btcpay.store.canviewofferings`: View your offerings\n* `btcpay.store.canmodifyofferings`: Modify your offerings\n* `btcpay.store.canmanagepullpayments`: Manage your pull payments\n* `btcpay.store.canarchivepullpayments`: Archive your pull payments\n* `btcpay.store.cancreatepullpayments`: Create pull payments\n* `btcpay.store.canmanagepayouts`: Manage payouts\n* `btcpay.store.canviewpayouts`: View payouts\n* `btcpay.store.cancreatenonapprovedpullpayments`: Create non-approved pull payments\n* `btcpay.store.canuselightningnode`: Use the lightning nodes associated with your stores\n* `btcpay.store.canviewlightninginvoice`: View the lightning invoices associated with your stores\n* `btcpay.store.cancreatelightninginvoice`: Create invoices from the lightning nodes associated with your stores\n\nNote that API Keys only limits permission of a user and can never expand it. If an API Key has the permission `btcpay.server.canmodifyserversettings` but that the user account creating this API Key is not administrator, the API Key will not be able to modify the server settings.\nSome permissions may include other permissions, see [this operation](#operation/permissionsMetadata).\n",
"name": "Authorization",
"in": "header"
},
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.