Refactor: User User.GetId instead of using the UserManager
What changed, and why it matters
This is a large internal code cleanup that replaces calls to ASP.NET Core's UserManager for getting the current user's ID with a new direct helper that reads the value from the user's identity claims. Most changes are mechanical refactors across many controllers and views. There are a few small behavior changes worth watching: the new helper returns an empty string instead of "???" for missing users, some places now treat a missing user ID as a validation failure rather than passing it through, and a couple of user-not-found cases now return NotFound instead of throwing an exception. The commit does not describe itself as a security fix and no external advisory is provided.
Treat this as a routine refactor with minor hardening. Review the new `GetId`/`GetIdOrNull` helpers to ensure they behave identically to `UserManager.GetUserId` for all authentication schemes (cookie, Greenfield API key, etc.). Pay special attention to the `StoreRepository.FindStore` admin path and the places that switched from exception-throwing to `NotFound()` to confirm no authorization bypass was introduced. No urgent patching is indicated absent additional context.
Security signals we found
Refactor of identity/user-ID retrieval across many authorization-sensitive controllers
Some missing-user paths changed from exception-throwing to NotFound returns
A few endpoints now explicitly reject null user IDs before performing operations
Store lookup logic changed to consolidate admin access through a new principal-aware overload
No explicit security claim, CVE, or advisory referenced in commit or supplied materials
Evidence from the diff
The commit refactors user-ID retrieval from UserManager.GetUserId(User) to new extension methods User.GetId() / User.GetIdOrNull() which read ClaimTypes.NameIdentifier directly. It touches 44 files, removing many UserManager<ApplicationUser> constructor dependencies. Notable non-mechanical changes include: Extensions.GetId() returns "" when no claim exists (previously GetUserId returned "" too, but some code compared against "???"); GreenfieldFilesController.UploadFile now validates userId is null before upload; GreenfieldAppsController.GetItemStats adds an offset clamp; UIManageController 2FA/manage actions now return NotFound() instead of throwing ApplicationException when the user is null; StoreRepository.FindStore gains an overload accepting IPrincipal with an adminCanAccess flag; BuiltInPermissionHandler now calls FindStore(storeId, principal, true) for admins instead of a separate unscoped lookup. The diff is a refactor with incidental hardening, not a disclosed vulnerability patch.
Changed components
BTCPayServer/Controllers/GreenField/*BTCPayServer/Controllers/UI*Controller*BTCPayServer/Security/BuiltInPermissionHandler.csBTCPayServer/Security/PermissionAuthorizationHandler.csBTCPayServer/Security/SetContextFilter.csBTCPayServer/Services/Stores/StoreRepository.csBTCPayServer/Extensions.csBTCPayServer/Blazor/*BTCPayServer/Components/*Inspect captured patch +154 / −289
diff --git a/BTCPayServer/Blazor/NotificationsDropDown.razor b/BTCPayServer/Blazor/NotificationsDropDown.razor
index 35bc2cd..c616b5b 100644
--- a/BTCPayServer/Blazor/NotificationsDropDown.razor
+++ b/BTCPayServer/Blazor/NotificationsDropDown.razor
@@ -1,14 +1,11 @@
@using BTCPayServer.Abstractions.Contracts;
@using BTCPayServer.Configuration;
-@using BTCPayServer.Data;
@using BTCPayServer.Services.Notifications;
-@using Microsoft.AspNetCore.Identity;
@using Microsoft.AspNetCore.Routing;
@using Microsoft.Extensions.Localization
@implements IDisposable
@inject AuthenticationStateProvider _AuthenticationStateProvider
@inject NotificationManager _NotificationManager
-@inject UserManager<ApplicationUser> _UserManager
@inject IStringLocalizer StringLocalizer
@inject IJSRuntime _JSRuntime
@inject LinkGenerator _LinkGenerator
@@ -126,9 +123,7 @@
async Task<string> GetUserId()
{
var state = await _AuthenticationStateProvider.GetAuthenticationStateAsync();
- if (!state.User.Identity.IsAuthenticated)
- return null;
- return _UserManager.GetUserId(state.User);
+ return state.User.GetIdOrNull();
}
private async Task MarkAllAsSeen()
diff --git a/BTCPayServer/Blazor/UserLoginCode.razor b/BTCPayServer/Blazor/UserLoginCode.razor
index 74c8335..1522868 100644
--- a/BTCPayServer/Blazor/UserLoginCode.razor
+++ b/BTCPayServer/Blazor/UserLoginCode.razor
@@ -30,7 +30,7 @@
@code {
[Parameter]
public string UserId { get; set; }
-
+
[Parameter]
public string RedirectUrl { get; set; }
@@ -84,7 +84,7 @@
{
var state = await AuthenticationStateProvider.GetAuthenticationStateAsync();
return state.User.Identity?.IsAuthenticated is true
- ? UserManager.GetUserId(state.User)
+ ? state.User.GetIdOrNull()
: null;
}
diff --git a/BTCPayServer/Components/MainNav/MainNav.cs b/BTCPayServer/Components/MainNav/MainNav.cs
index 1888757..3d3271d 100644
--- a/BTCPayServer/Components/MainNav/MainNav.cs
+++ b/BTCPayServer/Components/MainNav/MainNav.cs
@@ -1,3 +1,4 @@
+#nullable enable
using System;
using System.Linq;
using System.Threading;
@@ -10,7 +11,6 @@ using BTCPayServer.Payments.Lightning;
using BTCPayServer.Services;
using BTCPayServer.Services.Apps;
using BTCPayServer.Services.Invoices;
-using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
@@ -26,8 +26,7 @@ namespace BTCPayServer.Components.MainNav
SettingsRepository settingsRepository,
IMemoryCache cache,
UriResolver uriResolver,
- PoliciesSettings policiesSettings,
- StoreRepository storeRepository)
+ PoliciesSettings policiesSettings)
: ViewComponent
{
public PoliciesSettings PoliciesSettings { get; } = policiesSettings;
@@ -85,7 +84,7 @@ namespace BTCPayServer.Components.MainNav
vm.LightningNodes = lightningNodes;
// Apps
- var apps = await appService.GetAllApps(UserId, false, navStore.Id, true);
+ var apps = await appService.GetAllApps(HttpContext.User.GetIdOrNull(), false, navStore.Id, true);
vm.Apps = apps
.Where(a => !a.Archived)
.Select(a => new StoreApp
@@ -111,7 +110,5 @@ namespace BTCPayServer.Components.MainNav
return View(vm);
}
-
- private string UserId => userManager.GetUserId(HttpContext.User);
}
}
diff --git a/BTCPayServer/Components/StoreRecentInvoices/StoreRecentInvoices.cs b/BTCPayServer/Components/StoreRecentInvoices/StoreRecentInvoices.cs
index 3ddf99f..65704ea 100644
--- a/BTCPayServer/Components/StoreRecentInvoices/StoreRecentInvoices.cs
+++ b/BTCPayServer/Components/StoreRecentInvoices/StoreRecentInvoices.cs
@@ -10,19 +10,9 @@ using Microsoft.AspNetCore.Mvc;
namespace BTCPayServer.Components.StoreRecentInvoices;
-public class StoreRecentInvoices : ViewComponent
+public class StoreRecentInvoices(
+ InvoiceRepository invoiceRepo) : ViewComponent
{
- private readonly InvoiceRepository _invoiceRepo;
- private readonly UserManager<ApplicationUser> _userManager;
-
- public StoreRecentInvoices(
- InvoiceRepository invoiceRepo,
- UserManager<ApplicationUser> userManager)
- {
- _invoiceRepo = invoiceRepo;
- _userManager = userManager;
- }
-
public async Task<IViewComponentResult> InvokeAsync(StoreData store, bool initialRendering)
{
var vm = new StoreRecentInvoicesViewModel
@@ -34,8 +24,8 @@ public class StoreRecentInvoices : ViewComponent
if (vm.InitialRendering)
return View(vm);
- var userId = _userManager.GetUserId(UserClaimsPrincipal);
- var invoiceEntities = await _invoiceRepo.GetInvoices(new InvoiceQuery
+ var userId = UserClaimsPrincipal.GetIdOrNull();
+ var invoiceEntities = await invoiceRepo.GetInvoices(new InvoiceQuery
{
UserId = userId,
StoreId = [store.Id],
diff --git a/BTCPayServer/Components/StoreSelector/StoreSelector.cs b/BTCPayServer/Components/StoreSelector/StoreSelector.cs
index 20338ff..b6d491c 100644
--- a/BTCPayServer/Components/StoreSelector/StoreSelector.cs
+++ b/BTCPayServer/Components/StoreSelector/StoreSelector.cs
@@ -4,21 +4,19 @@ using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Data;
using BTCPayServer.Services;
using BTCPayServer.Services.Stores;
-using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace BTCPayServer.Components.StoreSelector
{
public class StoreSelector(
StoreRepository storeRepo,
- UriResolver uriResolver,
- UserManager<ApplicationUser> userManager)
+ UriResolver uriResolver)
: ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
- var userId = userManager.GetUserId(UserClaimsPrincipal);
- var stores = await storeRepo.GetStoresByUserId(userId ?? "");
+ var userId = UserClaimsPrincipal.GetId();
+ var stores = await storeRepo.GetStoresByUserId(userId);
var currentStore = ViewContext.HttpContext.GetNavStoreData();
var archivedCount = stores.Count(s => s.Archived);
var options = stores
diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldApiKeysController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldApiKeysController.cs
index fc75d39..c9f76bb 100644
--- a/BTCPayServer/Controllers/GreenField/GreenfieldApiKeysController.cs
+++ b/BTCPayServer/Controllers/GreenField/GreenfieldApiKeysController.cs
@@ -44,9 +44,7 @@ namespace BTCPayServer.Controllers.Greenfield
[HttpPost("~/api/v1/api-keys")]
[Authorize(Policy = Policies.Unrestricted, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public Task<IActionResult> CreateAPIKey(CreateApiKeyRequest request)
- {
- return CreateUserAPIKey(_userManager.GetUserId(User), request);
- }
+ => CreateUserAPIKey(User.GetId(), request);
[HttpPost("~/api/v1/users/{idOrEmail}/api-keys")]
[Authorize(Policy = Policies.CanManageUsers, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
@@ -87,9 +85,7 @@ namespace BTCPayServer.Controllers.Greenfield
[HttpDelete("~/api/v1/api-keys/{apikey}", Order = 1)]
[Authorize(Policy = Policies.Unrestricted, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public Task<IActionResult> RevokeAPIKey(string apikey)
- {
- return RevokeAPIKey(_userManager.GetUserId(User), apikey);
- }
+ => RevokeAPIKey(User.GetId(), apikey);
[HttpDelete("~/api/v1/users/{idOrEmail}/api-keys/{apikey}", Order = 1)]
[Authorize(Policy = Policies.CanManageUsers, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldAppsController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldAppsController.cs
index 8cb2bd5..eab6f94 100644
--- a/BTCPayServer/Controllers/GreenField/GreenfieldAppsController.cs
+++ b/BTCPayServer/Controllers/GreenField/GreenfieldAppsController.cs
@@ -36,7 +36,6 @@ namespace BTCPayServer.Controllers.Greenfield
private readonly UriResolver _uriResolver;
private readonly StoreRepository _storeRepository;
private readonly CurrencyNameTable _currencies;
- private readonly UserManager<ApplicationUser> _userManager;
private readonly IFileService _fileService;
public Safe Safe { get; }
@@ -47,7 +46,6 @@ namespace BTCPayServer.Controllers.Greenfield
StoreRepository storeRepository,
CurrencyNameTable currencies,
IFileService fileService,
- UserManager<ApplicationUser> userManager,
Safe safe
)
{
@@ -56,7 +54,6 @@ namespace BTCPayServer.Controllers.Greenfield
_storeRepository = storeRepository;
_currencies = currencies;
_fileService = fileService;
- _userManager = userManager;
Safe = safe;
}
@@ -172,7 +169,7 @@ namespace BTCPayServer.Controllers.Greenfield
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public async Task<IActionResult> GetAllApps()
{
- var apps = await _appService.GetAllApps(_userManager.GetUserId(User), includeArchived: true);
+ var apps = await _appService.GetAllApps(User.GetId(), includeArchived: true);
return Ok(apps.Select(ToModel).ToArray());
}
@@ -181,7 +178,7 @@ namespace BTCPayServer.Controllers.Greenfield
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public async Task<IActionResult> GetAllApps(string storeId)
{
- var apps = await _appService.GetAllApps(_userManager.GetUserId(User), false, storeId, true);
+ var apps = await _appService.GetAllApps(User.GetId(), false, storeId, true);
return Ok(apps.Select(ToModel).ToArray());
}
@@ -242,9 +239,10 @@ namespace BTCPayServer.Controllers.Greenfield
{
var app = await _appService.GetApp(appId, null, includeArchived: true);
if (app == null) return AppNotFound();
-
var stats = (await _appService.GetItemStats(app)).ToList();
- var max = Math.Min(count, stats.Count - offset);
+ if (stats.Count < offset)
+ offset = stats.Count;
+ var max = Math.Min(count, stats.Count - offset);
var items = stats.GetRange(offset, max);
return Ok(items);
}
@@ -254,9 +252,9 @@ namespace BTCPayServer.Controllers.Greenfield
public async Task<IActionResult> UploadAppItemImage(string appId, IFormFile? file)
{
var app = await _appService.GetApp(appId, null, includeArchived: true);
- var userId = _userManager.GetUserId(User);
+ var userId = User.GetIdOrNull();
if (app == null || userId == null) return AppNotFound();
-
+
UploadImageResultModel? upload = null;
if (file is null)
ModelState.AddModelError(nameof(file), "Invalid file");
@@ -268,7 +266,7 @@ namespace BTCPayServer.Controllers.Greenfield
}
if (!ModelState.IsValid)
return this.CreateValidationError(ModelState);
-
+
try
{
var storedFile = upload!.StoredFile!;
@@ -294,12 +292,12 @@ namespace BTCPayServer.Controllers.Greenfield
public async Task<IActionResult> DeleteAppItemImage(string appId, string fileId)
{
var app = await _appService.GetApp(appId, null, includeArchived: true);
- var userId = _userManager.GetUserId(User);
+ var userId = User.GetIdOrNull();
if (app == null || userId == null) return AppNotFound();
if (!string.IsNullOrEmpty(fileId)) await _fileService.RemoveFile(fileId, userId);
return Ok();
}
-
+
private IActionResult AppNotFound()
{
return this.CreateAPIError(404, "app-not-found", "The app with specified ID was not found");
@@ -408,7 +406,7 @@ namespace BTCPayServer.Controllers.Greenfield
var settings = appData.GetSettings<PointOfSaleSettings>();
Enum.TryParse<PosViewType>(settings.DefaultView.ToString(), true, out var defaultView);
var items = AppService.Parse(settings.Template);
-
+
return new PointOfSaleAppData
{
Id = appData.Id,
@@ -552,7 +550,7 @@ namespace BTCPayServer.Controllers.Greenfield
ModelState.AddModelError(nameof(request.ResetEveryAmount), "You must reset the goal at a minimum of 1");
}
}
-
+
if (request.Sounds != null && ValidateStringArray(request.Sounds) == null)
{
ModelState.AddModelError(nameof(request.Sounds), "Sounds must be a non-empty array of non-empty strings");
diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldFilesController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldFilesController.cs
index e82fad0..daeebf1 100644
--- a/BTCPayServer/Controllers/GreenField/GreenfieldFilesController.cs
+++ b/BTCPayServer/Controllers/GreenField/GreenfieldFilesController.cs
@@ -20,7 +20,6 @@ namespace BTCPayServer.Controllers.Greenfield;
[EnableCors(CorsPolicies.All)]
[Authorize(Policy = Policies.CanModifyServerSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
public class GreenfieldFilesController(
- UserManager<ApplicationUser> userManager,
IFileService fileService,
StoredFileRepository fileRepository)
: ControllerBase
@@ -47,16 +46,16 @@ public class GreenfieldFilesController(
[HttpPost("~/api/v1/files")]
public async Task<IActionResult> UploadFile(IFormFile file)
{
+ var userId = User.GetIdOrNull();
if (file is null)
ModelState.AddModelError(nameof(file), "Invalid file");
else if (!file.FileName.IsValidFileName())
ModelState.AddModelError(nameof(file.FileName), "Invalid filename");
- if (!ModelState.IsValid)
+ if (!ModelState.IsValid || userId is null)
return this.CreateValidationError(ModelState);
try
{
- var userId = userManager.GetUserId(User)!;
var newFile = await fileService.AddFile(file!, userId);
return Ok(await ToFileData(newFile));
}
diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldNotificationsController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldNotificationsController.cs
index 744ab13..7c5c9f0 100644
--- a/BTCPayServer/Controllers/GreenField/GreenfieldNotificationsController.cs
+++ b/BTCPayServer/Controllers/GreenField/GreenfieldNotificationsController.cs
@@ -44,7 +44,7 @@ namespace BTCPayServer.Controllers.Greenfield
var items = await _notificationManager.GetNotifications(new NotificationsQuery
{
Seen = seen,
- UserId = _userManager.GetUserId(User),
+ UserId = User.GetId(),
Skip = skip,
Take = take,
StoreIds = storeId,
@@ -60,7 +60,7 @@ namespace BTCPayServer.Controllers.Greenfield
var items = await _notificationManager.GetNotifications(new NotificationsQuery
{
Ids = [id],
- UserId = _userManager.GetUserId(User)
+ UserId = User.GetId()
});
return items.Count == 0 ? NotificationNotFound() : Ok(ToModel(items.Items.First()));
@@ -71,7 +71,7 @@ namespace BTCPayServer.Controllers.Greenfield
public async Task<IActionResult> UpdateNotification(string id, UpdateNotification request)
{
var items = await _notificationManager.ToggleSeen(
- new NotificationsQuery { Ids = [id], UserId = _userManager.GetUserId(User) }, request.Seen);
+ new NotificationsQuery { Ids = [id], UserId = User.GetId() }, request.Seen);
return items.Count == 0 ? NotificationNotFound() : Ok(ToModel(items.First()));
}
@@ -83,7 +83,7 @@ namespace BTCPayServer.Controllers.Greenfield
await _notificationManager.Remove(new NotificationsQuery
{
Ids = [id],
- UserId = _userManager.GetUserId(User)
+ UserId = User.GetId()
});
return Ok();
diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldPaymentRequestsController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldPaymentRequestsController.cs
index 775310c..bc704d5 100644
--- a/BTCPayServer/Controllers/GreenField/GreenfieldPaymentRequestsController.cs
+++ b/BTCPayServer/Controllers/GreenField/GreenfieldPaymentRequestsController.cs
@@ -30,7 +30,6 @@ namespace BTCPayServer.Controllers.Greenfield
private readonly UIInvoiceController _invoiceController;
private readonly PaymentRequestRepository _paymentRequestRepository;
private readonly CurrencyNameTable _currencyNameTable;
- private readonly UserManager<ApplicationUser> _userManager;
private readonly LinkGenerator _linkGenerator;
public GreenfieldPaymentRequestsController(
@@ -39,7 +38,6 @@ namespace BTCPayServer.Controllers.Greenfield
PaymentRequestRepository paymentRequestRepository,
PaymentRequestService paymentRequestService,
CurrencyNameTable currencyNameTable,
- UserManager<ApplicationUser> userManager,
LinkGenerator linkGenerator)
{
_InvoiceRepository = invoiceRepository;
@@ -47,7 +45,6 @@ namespace BTCPayServer.Controllers.Greenfield
_paymentRequestRepository = paymentRequestRepository;
PaymentRequestService = paymentRequestService;
_currencyNameTable = currencyNameTable;
- _userManager = userManager;
_linkGenerator = linkGenerator;
}
@@ -233,7 +230,7 @@ namespace BTCPayServer.Controllers.Greenfield
public PaymentRequestService PaymentRequestService { get; }
- private string GetUserId() => _userManager.GetUserId(User);
+ private string GetUserId() => User.GetIdOrNull();
private static Client.Models.PaymentRequestBaseData FromModel(PaymentRequestData data)
{
diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldStoresController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldStoresController.cs
index 43fdace..88982f0 100644
--- a/BTCPayServer/Controllers/GreenField/GreenfieldStoresController.cs
+++ b/BTCPayServer/Controllers/GreenField/GreenfieldStoresController.cs
@@ -82,7 +82,7 @@ namespace BTCPayServer.Controllers.Greenfield
var store = HttpContext.GetStoreData();
if (store == null) return StoreNotFound();
- await _storeRepository.RemoveStore(storeId, _userManager.GetUserId(User) ?? "");
+ await _storeRepository.RemoveStore(storeId, User.GetId());
return Ok();
}
@@ -95,7 +95,7 @@ namespace BTCPayServer.Controllers.Greenfield
var validationResult = Validate(request);
if (validationResult != null) return validationResult;
ToModel(request, store);
- await _storeRepository.CreateStore(_userManager.GetUserId(User) ?? "", store);
+ await _storeRepository.CreateStore(User.GetId(), store);
return Ok(await FromModel(store));
}
@@ -168,13 +168,12 @@ namespace BTCPayServer.Controllers.Greenfield
public async Task<IActionResult> DeleteStoreLogo(string storeId)
{
var store = HttpContext.GetStoreData();
- if (store == null) return StoreNotFound();
+ if (store == null || User.GetIdOrNull() is not string userId) return StoreNotFound();
var blob = store.GetStoreBlob();
var fileId = (blob.LogoUrl as UnresolvedUri.FileIdUri)?.FileId;
if (!string.IsNullOrEmpty(fileId))
{
- var userId = _userManager.GetUserId(User)!;
await _fileService.RemoveFile(fileId, userId);
blob.LogoUrl = null;
store.SetStoreBlob(blob);
diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldTestApiKeyController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldTestApiKeyController.cs
index d75429c..6ef7993 100644
--- a/BTCPayServer/Controllers/GreenField/GreenfieldTestApiKeyController.cs
+++ b/BTCPayServer/Controllers/GreenField/GreenfieldTestApiKeyController.cs
@@ -32,10 +32,7 @@ namespace BTCPayServer.Controllers.Greenfield
[HttpGet("me/id")]
[Authorize(Policy = Policies.CanViewProfile, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
- public string GetCurrentUserId()
- {
- return _userManager.GetUserId(User);
- }
+ public string GetCurrentUserId() => User.GetId();
[HttpGet("me")]
[Authorize(Policy = Policies.CanViewProfile, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldUsersController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldUsersController.cs
index 06915b4..5809a55 100644
--- a/BTCPayServer/Controllers/GreenField/GreenfieldUsersController.cs
+++ b/BTCPayServer/Controllers/GreenField/GreenfieldUsersController.cs
@@ -302,10 +302,7 @@ namespace BTCPayServer.Controllers.Greenfield
[Authorize(Policy = Policies.CanDeleteUser, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
[HttpDelete("~/api/v1/users/me")]
- public async Task<IActionResult> DeleteCurrentUser()
- {
- return await DeleteUser(_userManager.GetUserId(User)!);
- }
+ public Task<IActionResult> DeleteCurrentUser() => DeleteUser(User.GetId());
[AllowAnonymous]
[HttpPost("~/api/v1/users")]
diff --git a/BTCPayServer/Controllers/UIAccountController.cs b/BTCPayServer/Controllers/UIAccountController.cs
index 42b3631..1c06562 100644
--- a/BTCPayServer/Controllers/UIAccountController.cs
+++ b/BTCPayServer/Controllers/UIAccountController.cs
@@ -636,8 +636,6 @@ namespace BTCPayServer.Controllers
[HttpGet("/logout")]
public async Task<IActionResult> Logout()
{
- var userId = signInManager.UserManager.GetUserId(HttpContext.User);
- var user = await userManager.FindByIdAsync(userId);
await signInManager.SignOutAsync();
HttpContext.DeleteUserPrefsCookie();
return RedirectToAction(nameof(Login));
diff --git a/BTCPayServer/Controllers/UIAppsController.cs b/BTCPayServer/Controllers/UIAppsController.cs
index f0d78c2..01b6316 100644
--- a/BTCPayServer/Controllers/UIAppsController.cs
+++ b/BTCPayServer/Controllers/UIAppsController.cs
@@ -13,7 +13,6 @@ using BTCPayServer.Services.Invoices;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
using Microsoft.AspNetCore.Mvc.Rendering;
@@ -25,7 +24,6 @@ namespace BTCPayServer.Controllers
public partial class UIAppsController : Controller
{
public UIAppsController(
- UserManager<ApplicationUser> userManager,
PaymentMethodHandlerDictionary handlers,
BTCPayNetworkProvider networkProvider,
StoreRepository storeRepository,
@@ -35,7 +33,6 @@ namespace BTCPayServer.Controllers
ViewLocalizer viewLocalizer,
IHtmlHelper html)
{
- _userManager = userManager;
_handlers = handlers;
_networkProvider = networkProvider;
_storeRepository = storeRepository;
@@ -46,7 +43,6 @@ namespace BTCPayServer.Controllers
ViewLocalizer = viewLocalizer;
}
- private readonly UserManager<ApplicationUser> _userManager;
private readonly PaymentMethodHandlerDictionary _handlers;
private readonly BTCPayNetworkProvider _networkProvider;
private readonly StoreRepository _storeRepository;
@@ -256,7 +252,7 @@ namespace BTCPayServer.Controllers
public async Task<IActionResult> FileUpload(IFormFile file)
{
var app = GetCurrentApp();
- var userId = GetUserId();
+ var userId = User.GetIdOrNull();
if (app is null || userId is null)
return NotFound();
@@ -300,7 +296,7 @@ namespace BTCPayServer.Controllers
return currency?.Trim().ToUpperInvariant();
}
- private string GetUserId() => _userManager.GetUserId(User);
+ private string GetUserId() => User.GetId();
private StoreData GetCurrentStore() => HttpContext.GetStoreData();
diff --git a/BTCPayServer/Controllers/UIHomeController.cs b/BTCPayServer/Controllers/UIHomeController.cs
index 6d1b20b..d9151fd 100644
--- a/BTCPayServer/Controllers/UIHomeController.cs
+++ b/BTCPayServer/Controllers/UIHomeController.cs
@@ -58,7 +58,7 @@ namespace BTCPayServer.Controllers
if (SignInManager.IsSignedIn(User))
{
- var userId = SignInManager.UserManager.GetUserId(HttpContext.User);
+ var userId = HttpContext.User.GetIdOrNull();
var storeId = HttpContext.GetUserPrefsCookie()?.CurrentStoreId;
if (storeId != null && userId != null)
{
diff --git a/BTCPayServer/Controllers/UIInvoiceController.UI.cs b/BTCPayServer/Controllers/UIInvoiceController.UI.cs
index 962895f..782af19 100644
--- a/BTCPayServer/Controllers/UIInvoiceController.UI.cs
+++ b/BTCPayServer/Controllers/UIInvoiceController.UI.cs
@@ -12,7 +12,6 @@ using BTCPayServer.Client;
using BTCPayServer.Client.Models;
using BTCPayServer.Data;
using BTCPayServer.Filters;
-using BTCPayServer.HostedServices;
using BTCPayServer.Models;
using BTCPayServer.Models.AppViewModels;
using BTCPayServer.Models.InvoicingModels;
@@ -30,7 +29,6 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
using Microsoft.AspNetCore.Mvc.Rendering;
-using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using NBitcoin;
@@ -286,7 +284,7 @@ namespace BTCPayServer.Controllers
if (invoice is null)
return NotFound();
var currentRefund = invoice.Refunds.OrderByDescending(r => r.PullPaymentData.StartDate).FirstOrDefault();
- if (currentRefund?.PullPaymentDataId is null && GetUserId() is null)
+ if (currentRefund?.PullPaymentDataId is null && User.GetIdOrNull() is null)
return NotFound();
if (!invoice.GetInvoiceState().CanRefund())
return NotFound();
@@ -335,8 +333,6 @@ namespace BTCPayServer.Controllers
await using var ctx = _dbContextFactory.CreateContext();
var invoice = GetCurrentInvoice();
- if (invoice == null)
- return NotFound();
if (!invoice.GetInvoiceState().CanRefund())
return NotFound();
@@ -654,7 +650,7 @@ namespace BTCPayServer.Controllers
var explorer = network is null ? null : _ExplorerClients.GetExplorerClient(network);
if (explorer is null || network is null)
return NotSupported(StringLocalizer["This feature is only available to BTC wallets"]);
- if (!GetCurrentStore().HasPolicy(GetUserId(), Policies.CanModifyStoreSettings, _permissionService))
+ if (!GetCurrentStore().HasPolicy(User.GetId(), Policies.CanModifyStoreSettings, _permissionService))
return Forbid();
var derivationScheme = GetCurrentStore().GetDerivationSchemeSettings(_handlers, network.CryptoCode)?.AccountDerivation;
@@ -848,9 +844,9 @@ namespace BTCPayServer.Controllers
.Replace("{InvoiceId}", Uri.EscapeDataString(invoice.Id))
: null;
- string GetPaymentMethodImage(PaymentMethodId paymentMethodId)
+ string GetPaymentMethodImage(PaymentMethodId paymentMethodId2)
{
- _paymentModelExtensions.TryGetValue(paymentMethodId, out var extension);
+ _paymentModelExtensions.TryGetValue(paymentMethodId2, out var extension);
return extension?.Image ?? "";
}
@@ -1075,7 +1071,7 @@ namespace BTCPayServer.Controllers
model.Search = fs;
model.SearchText = fs.TextCombined;
- var apps = await _appService.GetAllApps(GetUserId(), false, storeId);
+ var apps = await _appService.GetAllApps(User.GetIdOrNull(), false, storeId);
InvoiceQuery invoiceQuery = GetInvoiceQuery(fs, apps, timezoneOffset);
invoiceQuery.StoreId = storeIds.ToArray();
invoiceQuery.Take = model.Count;
@@ -1121,7 +1117,7 @@ namespace BTCPayServer.Controllers
{
var appsById = apps.ToDictionary(a => a.Id);
var searchTexts = appIds.Select(a => appsById.TryGet(a)).Where(a => a != null)
- .Select(a => AppService.GetAppSearchTerm(a!.AppType, a!.Id))
+ .Select(a => AppService.GetAppSearchTerm(a!.AppType, a.Id))
.ToList();
searchTexts.Add(fs.TextSearch);
textSearch = string.Join(' ', searchTexts.Where(t => !string.IsNullOrEmpty(t)).ToList());
@@ -1300,10 +1296,8 @@ namespace BTCPayServer.Controllers
private InvoiceEntity GetCurrentInvoice() => HttpContext.GetInvoiceData();
- private string GetUserId() => _UserManager.GetUserId(User)!;
-
// Let server admin lookup invoices from users, see #6489
- private string? GetUserIdForInvoiceQuery() => User.IsInRole(Roles.ServerAdmin) ? null : GetUserId();
+ private string? GetUserIdForInvoiceQuery() => User.IsInRole(Roles.ServerAdmin) ? null : User.GetIdOrNull();
private SelectList GetPaymentMethodsSelectList(StoreData store)
{
diff --git a/BTCPayServer/Controllers/UIInvoiceController.cs b/BTCPayServer/Controllers/UIInvoiceController.cs
index 4047dfa..f5c33b3 100644
--- a/BTCPayServer/Controllers/UIInvoiceController.cs
+++ b/BTCPayServer/Controllers/UIInvoiceController.cs
@@ -60,7 +60,6 @@ namespace BTCPayServer.Controllers
private readonly Dictionary<PaymentMethodId, ICheckoutModelExtension> _paymentModelExtensions;
private readonly PrettyNameProvider _prettyName;
private readonly AppService _appService;
- private readonly IFileService _fileService;
private readonly UriResolver _uriResolver;
private readonly PermissionService _permissionService;
@@ -89,7 +88,6 @@ namespace BTCPayServer.Controllers
InvoiceActivator invoiceActivator,
LinkGenerator linkGenerator,
AppService appService,
- IFileService fileService,
UriResolver uriResolver,
DefaultRulesCollection defaultRules,
IAuthorizationService authorizationService,
@@ -124,7 +122,6 @@ namespace BTCPayServer.Controllers
_paymentModelExtensions = paymentModelExtensions;
GlobalCheckoutModelExtensions = globalCheckoutModelExtensions;
_prettyName = prettyName;
- _fileService = fileService;
_uriResolver = uriResolver;
_defaultRules = defaultRules;
_appService = appService;
diff --git a/BTCPayServer/Controllers/UILNURLAuthController.cs b/BTCPayServer/Controllers/UILNURLAuthController.cs
index bed3f1d..a6eba26 100644
--- a/BTCPayServer/Controllers/UILNURLAuthController.cs
+++ b/BTCPayServer/Controllers/UILNURLAuthController.cs
@@ -21,15 +21,13 @@ namespace BTCPayServer
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie, Policy = Policies.CanViewProfile)]
public class UILNURLAuthController : Controller
{
- private readonly UserManager<ApplicationUser> _userManager;
private readonly LnurlAuthService _lnurlAuthService;
private readonly LinkGenerator _linkGenerator;
public IStringLocalizer StringLocalizer { get; }
- public UILNURLAuthController(UserManager<ApplicationUser> userManager, LnurlAuthService lnurlAuthService,
+ public UILNURLAuthController(LnurlAuthService lnurlAuthService,
IStringLocalizer stringLocalizer, LinkGenerator linkGenerator)
{
- _userManager = userManager;
_lnurlAuthService = lnurlAuthService;
_linkGenerator = linkGenerator;
StringLocalizer = stringLocalizer;
@@ -47,7 +45,7 @@ namespace BTCPayServer
[HttpPost("{id}/delete")]
public async Task<IActionResult> RemoveP(string id)
{
- await _lnurlAuthService.Remove(id, _userManager.GetUserId(User));
+ await _lnurlAuthService.Remove(id, User.GetId());
TempData.SetStatusMessageModel(new StatusMessageModel
{
@@ -61,7 +59,7 @@ namespace BTCPayServer
[HttpGet("register")]
public async Task<IActionResult> Create(string name)
{
- var userId = _userManager.GetUserId(User);
+ var userId = User.GetId();
var options = await _lnurlAuthService.RequestCreation(userId);
if (options is null)
{
@@ -90,7 +88,7 @@ namespace BTCPayServer
[HttpGet("register/check")]
public Task<IActionResult> CreateCheck()
{
- var userId = _userManager.GetUserId(User);
+ var userId = User.GetId();
if (_lnurlAuthService.CreationStore.TryGetValue(userId, out _))
{
return Task.FromResult<IActionResult>(Ok());
diff --git a/BTCPayServer/Controllers/UIManageController.2FA.cs b/BTCPayServer/Controllers/UIManageController.2FA.cs
index 44170c3..fc59e0a 100644
--- a/BTCPayServer/Controllers/UIManageController.2FA.cs
+++ b/BTCPayServer/Controllers/UIManageController.2FA.cs
@@ -21,15 +21,13 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var model = new TwoFactorAuthenticationViewModel
{
Is2faEnabled = user.TwoFactorEnabled,
RecoveryCodesLeft = await _userManager.CountRecoveryCodesAsync(user),
- Credentials = await _fido2Service.GetCredentials(_userManager.GetUserId(User))
+ Credentials = await _fido2Service.GetCredentials(User.GetId())
};
return View(model);
@@ -39,9 +37,7 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var disable2faResult = await _userManager.SetTwoFactorEnabledAsync(user, false);
if (!disable2faResult.Succeeded)
@@ -59,9 +55,7 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var model = new EnableAuthenticatorViewModel();
await LoadSharedKeyAndQrCodeUriAsync(user, model);
@@ -75,9 +69,7 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
if (!ModelState.IsValid)
{
@@ -111,9 +103,7 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
await _userManager.SetTwoFactorEnabledAsync(user, false);
await _userManager.ResetAuthenticatorKeyAsync(user);
@@ -129,9 +119,7 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
recoveryCodes = (await _userManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10)).ToArray();
}
diff --git a/BTCPayServer/Controllers/UIManageController.APIKeys.cs b/BTCPayServer/Controllers/UIManageController.APIKeys.cs
index e590c88..4578476 100644
--- a/BTCPayServer/Controllers/UIManageController.APIKeys.cs
+++ b/BTCPayServer/Controllers/UIManageController.APIKeys.cs
@@ -26,7 +26,7 @@ namespace BTCPayServer.Controllers
{
ApiKeyDatas = await _apiKeyRepository.GetKeys(new APIKeyRepository.APIKeyQuery()
{
- UserId = new[] { _userManager.GetUserId(User) }
+ UserId = new[] { User.GetId() }
})
});
}
@@ -35,7 +35,7 @@ namespace BTCPayServer.Controllers
public async Task<IActionResult> DeleteAPIKey(string id)
{
var key = await _apiKeyRepository.GetKey(id);
- if (key == null || key.UserId != _userManager.GetUserId(User))
+ if (key == null || key.UserId != User.GetId())
{
return NotFound();
}
@@ -52,11 +52,11 @@ namespace BTCPayServer.Controllers
public async Task<IActionResult> DeleteAPIKeyPost(string id)
{
var key = await _apiKeyRepository.GetKey(id);
- if (key == null || key.UserId != _userManager.GetUserId(User))
+ if (key == null || key.UserId != User.GetId())
{
return NotFound();
}
- await _apiKeyRepository.Remove(id, _userManager.GetUserId(User));
+ await _apiKeyRepository.Remove(id, User.GetId());
TempData.SetStatusMessageModel(new StatusMessageModel
{
Severity = StatusMessageModel.StatusSeverity.Success,
@@ -260,7 +260,7 @@ namespace BTCPayServer.Controllers
//check if there is an app identifier that matches and belongs to the current user
var keys = await _apiKeyRepository.GetKeys(new APIKeyRepository.APIKeyQuery
{
- UserId = new[] { _userManager.GetUserId(User) }
+ UserId = new[] { User.GetId() }
});
foreach (var key in keys)
{
@@ -435,7 +435,7 @@ namespace BTCPayServer.Controllers
{
Id = Encoders.Hex.EncodeData(RandomUtils.GetBytes(20)),
Type = APIKeyType.Permanent,
- UserId = _userManager.GetUserId(User),
+ UserId = User.GetId(),
Label = viewModel.Label,
};
key.SetBlob(new APIKeyBlob
@@ -474,7 +474,7 @@ namespace BTCPayServer.Controllers
private async Task<T> SetViewModelValues<T>(T viewModel) where T : AddApiKeyViewModel
{
- var stores = await _StoreRepository.GetStoresByUserId(_userManager.GetUserId(User) ?? "");
+ var stores = await _StoreRepository.GetStoresByUserId(User.GetId());
viewModel.Stores = stores.OrderBy(store => store.StoreName, StringComparer.InvariantCultureIgnoreCase).ToArray();
var isAdmin = (await _authorizationService.AuthorizeAsync(User, Policies.CanModifyServerSettings))
diff --git a/BTCPayServer/Controllers/UIManageController.cs b/BTCPayServer/Controllers/UIManageController.cs
index e10c754..26f93ad 100644
--- a/BTCPayServer/Controllers/UIManageController.cs
+++ b/BTCPayServer/Controllers/UIManageController.cs
@@ -87,9 +87,7 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var blob = user.GetBlob() ?? new();
var model = new IndexViewModel
{
@@ -109,9 +107,7 @@ namespace BTCPayServer.Controllers
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var blob = user.GetBlob() ?? new();
blob.ShowInvoiceStatusChangeHint = false;
@@ -126,9 +122,7 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
bool needUpdate = false;
var email = user.Email;
@@ -214,9 +208,7 @@ namespace BTCPayServer.Controllers
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var callbackUrl = await _callbackGenerator.ForEmailConfirmation(user);
_eventAggregator.Publish(new UserEvent.ConfirmationEmailRequested(user, callbackUrl));
@@ -229,9 +221,7 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var hasPassword = await _userManager.HasPasswordAsync(user);
if (!hasPassword)
@@ -254,9 +244,7 @@ namespace BTCPayServer.Controllers
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var changePasswordResult = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
if (!changePasswordResult.Succeeded)
@@ -277,9 +265,7 @@ namespace BTCPayServer.Controllers
{
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var hasPassword = await _userManager.HasPasswordAsync(user);
@@ -303,9 +289,7 @@ namespace BTCPayServer.Controllers
var user = await _userManager.GetUserAsync(User);
if (user == null)
- {
- throw new ApplicationException($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
- }
+ return NotFound();
var addPasswordResult = await _userManager.AddPasswordAsync(user, model.NewPassword);
if (!addPasswordResult.Succeeded)
diff --git a/BTCPayServer/Controllers/UINotificationsController.cs b/BTCPayServer/Controllers/UINotificationsController.cs
index a311537..35e75b8 100644
--- a/BTCPayServer/Controllers/UINotificationsController.cs
+++ b/BTCPayServer/Controllers/UINotificationsController.cs
@@ -15,22 +15,10 @@ namespace BTCPayServer.Controllers
{
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie, Policy = Policies.CanViewNotificationsForUser)]
[Route("notifications/{action:lowercase=Index}")]
- public class UINotificationsController : Controller
+ public class UINotificationsController(
+ StoreRepository storeRepo,
+ NotificationManager notificationManager) : Controller
{
- private readonly StoreRepository _storeRepo;
- private readonly UserManager<ApplicationUser> _userManager;
- private readonly NotificationManager _notificationManager;
-
- public UINotificationsController(
- StoreRepository storeRepo,
- UserManager<ApplicationUser> userManager,
- NotificationManager notificationManager)
- {
- _storeRepo = storeRepo;
- _userManager = userManager;
- _notificationManager = notificationManager;
- }
-
[HttpGet]
public async Task<IActionResult> Index(NotificationIndexViewModel model = null)
{
@@ -38,13 +26,13 @@ namespace BTCPayServer.Controllers
var timezoneOffset = model.TimezoneOffset ?? 0;
model.Status ??= "Unread";
ViewBag.Status = model.Status;
- if (!ValidUserClaim(out var userId))
+ if (User.GetIdOrNull() is not string userId)
return RedirectToAction("Index", "UIHome");
var searchTerm = string.IsNullOrEmpty(model.SearchText) ? model.SearchTerm : $"{model.SearchText},{model.SearchTerm}";
var fs = new SearchString(searchTerm, timezoneOffset);
var storeIds = fs.GetFilterArray("storeid");
- var stores = await _storeRepo.GetStoresByUserId(userId);
+ var stores = await storeRepo.GetStoresByUserId(userId);
model.StoreFilterOptions = stores
.Where(store => !store.Archived)
.OrderBy(s => s.StoreName)
@@ -58,7 +46,7 @@ namespace BTCPayServer.Controllers
model.Search = fs;
- var res = await _notificationManager.GetNotifications(new NotificationsQuery
+ var res = await notificationManager.GetNotifications(new NotificationsQuery
{
Skip = model.Skip,
Take = model.Count,
@@ -77,9 +65,9 @@ namespace BTCPayServer.Controllers
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie, Policy = Policies.CanManageNotificationsForUser)]
public async Task<IActionResult> FlipRead(string id)
{
- if (ValidUserClaim(out var userId))
+ if (User.GetIdOrNull() is string userId)
{
- await _notificationManager.ToggleSeen(new NotificationsQuery { Ids = [id], UserId = userId }, null);
+ await notificationManager.ToggleSeen(new NotificationsQuery { Ids = [id], UserId = userId }, null);
return RedirectToAction(nameof(Index));
}
@@ -89,10 +77,10 @@ namespace BTCPayServer.Controllers
[HttpGet]
public async Task<IActionResult> NotificationPassThrough(string id)
{
- if (ValidUserClaim(out var userId))
+ if (User.GetIdOrNull() is string userId)
{
var items = await
- _notificationManager.ToggleSeen(new NotificationsQuery
+ notificationManager.ToggleSeen(new NotificationsQuery
{
Ids = [id],
UserId = userId
@@ -114,10 +102,8 @@ namespace BTCPayServer.Controllers
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie, Policy = Policies.CanManageNotificationsForUser)]
public async Task<IActionResult> MassAction(string command, string[] selectedItems)
{
- if (!ValidUserClaim(out var userId))
- {
+ if (User.GetIdOrNull() is not string userId)
return NotFound();
- }
if (command.StartsWith("flip-individual", StringComparison.InvariantCulture))
{
@@ -130,7 +116,7 @@ namespace BTCPayServer.Controllers
switch (command)
{
case "delete":
- await _notificationManager.Remove(new NotificationsQuery()
+ await notificationManager.Remove(new NotificationsQuery()
{
UserId = userId,
Ids = selectedItems
@@ -138,7 +124,7 @@ namespace BTCPayServer.Controllers
break;
case "mark-seen":
- await _notificationManager.ToggleSeen(new NotificationsQuery()
+ await notificationManager.ToggleSeen(new NotificationsQuery()
{
UserId = userId,
Ids = selectedItems,
@@ -147,7 +133,7 @@ namespace BTCPayServer.Controllers
break;
case "mark-unseen":
- await _notificationManager.ToggleSeen(new NotificationsQuery()
+ await notificationManager.ToggleSeen(new NotificationsQuery()
{
UserId = userId,
Ids = selectedItems,
@@ -155,7 +141,6 @@ namespace BTCPayServer.Controllers
}, false);
break;
}
- return RedirectToAction(nameof(Index));
}
return RedirectToAction(nameof(Index));
@@ -165,18 +150,10 @@ namespace BTCPayServer.Controllers
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie, Policy = Policies.CanManageNotificationsForUser)]
public async Task<IActionResult> MarkAllAsSeen(string returnUrl)
{
- if (!ValidUserClaim(out var userId))
- {
+ if (User.GetIdOrNull() is not string userId)
return NotFound();
- }
- await _notificationManager.ToggleSeen(new NotificationsQuery { Seen = false, UserId = userId }, true);
+ await notificationManager.ToggleSeen(new NotificationsQuery { Seen = false, UserId = userId }, true);
return LocalRedirect(returnUrl);
}
-
- private bool ValidUserClaim(out string userId)
- {
- userId = _userManager.GetUserId(User);
- return userId != null;
- }
}
}
diff --git a/BTCPayServer/Controllers/UIPaymentRequestController.cs b/BTCPayServer/Controllers/UIPaymentRequestController.cs
index 83caf32..d7392e4 100644
--- a/BTCPayServer/Controllers/UIPaymentRequestController.cs
+++ b/BTCPayServer/Controllers/UIPaymentRequestController.cs
@@ -40,7 +40,6 @@ namespace BTCPayServer.Controllers
{
private readonly UIInvoiceController _InvoiceController;
private readonly PaymentMethodHandlerDictionary _handlers;
- private readonly UserManager<ApplicationUser> _UserManager;
private readonly PaymentRequestRepository _PaymentRequestRepository;
private readonly PaymentRequestService _PaymentRequestService;
private readonly CurrencyNameTable _Currencies;
@@ -61,7 +60,6 @@ namespace BTCPayServer.Controllers
public UIPaymentRequestController(
UIInvoiceController invoiceController,
PaymentMethodHandlerDictionary handlers,
- UserManager<ApplicationUser> userManager,
PaymentRequestRepository paymentRequestRepository,
PaymentRequestService paymentRequestService,
CurrencyNameTable currencies,
@@ -79,7 +77,6 @@ namespace BTCPayServer.Controllers
{
_InvoiceController = invoiceController;
_handlers = handlers;
- _UserManager = userManager;
_PaymentRequestRepository = paymentRequestRepository;
_PaymentRequestService = paymentRequestService;
_Currencies = currencies;
@@ -673,7 +670,7 @@ namespace BTCPayServer.Controllers
return RedirectToAction(nameof(PaymentRequestLabels), new { storeId });
}
- private string GetUserId() => _UserManager.GetUserId(User);
+ private string GetUserId() => User.GetIdOrNull();
private StoreData GetCurrentStore() => HttpContext.GetStoreData();
diff --git a/BTCPayServer/Controllers/UIServerController.Storage.cs b/BTCPayServer/Controllers/UIServerController.Storage.cs
index b3f5b9e..1b422b0 100644
--- a/BTCPayServer/Controllers/UIServerController.Storage.cs
+++ b/BTCPayServer/Controllers/UIServerController.Storage.cs
@@ -223,10 +223,7 @@ namespace BTCPayServer.Controllers
}
}
- private string GetUserId()
- {
- return _UserManager.GetUserId(ControllerContext.HttpContext.User);
- }
+ private string GetUserId() => ControllerContext.HttpContext.User.GetIdOrNull();
[HttpGet("server/storage")]
public async Task<IActionResult> Storage(bool forceChoice = false)
diff --git a/BTCPayServer/Controllers/UIStoresController.cs b/BTCPayServer/Controllers/UIStoresController.cs
index af2ffd2..1492bc5 100644
--- a/BTCPayServer/Controllers/UIStoresController.cs
+++ b/BTCPayServer/Controllers/UIStoresController.cs
@@ -131,11 +131,7 @@ public partial class UIStoresController : Controller
[HttpGet("{storeId}/index")]
public async Task<IActionResult> Index(string storeId)
{
- var userId = _userManager.GetUserId(User);
- if (string.IsNullOrEmpty(userId))
- return Forbid();
-
- var store = await _storeRepo.FindStore(storeId, userId);
+ var store = await _storeRepo.FindStore(storeId, User.GetId());
if (store is null)
return NotFound();
@@ -168,8 +164,5 @@ public partial class UIStoresController : Controller
}).ToArray();
}
- private string? GetUserId()
- {
- return User.Identity?.AuthenticationType != AuthenticationSchemes.Cookie ? null : _userManager.GetUserId(User);
- }
+ private string? GetUserId() => User.Identity?.AuthenticationType != AuthenticationSchemes.Cookie ? null : User.GetIdOrNull();
}
diff --git a/BTCPayServer/Controllers/UIUserStoresController.cs b/BTCPayServer/Controllers/UIUserStoresController.cs
index d9675e3..0459d24 100644
--- a/BTCPayServer/Controllers/UIUserStoresController.cs
+++ b/BTCPayServer/Controllers/UIUserStoresController.cs
@@ -7,11 +7,9 @@ using BTCPayServer.Abstractions.Models;
using BTCPayServer.Client;
using BTCPayServer.Data;
using BTCPayServer.Models.StoreViewModels;
-using BTCPayServer.Services;
using BTCPayServer.Services.Rates;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Localization;
@@ -23,13 +21,11 @@ namespace BTCPayServer.Controllers
{
private readonly StoreRepository _repo;
private readonly IStringLocalizer StringLocalizer;
- private readonly UserManager<ApplicationUser> _userManager;
private readonly DefaultRulesCollection _defaultRules;
private readonly RateFetcher _rateFactory;
public string CreatedStoreId { get; set; }
public UIUserStoresController(
- UserManager<ApplicationUser> userManager,
DefaultRulesCollection defaultRules,
StoreRepository storeRepository,
IStringLocalizer stringLocalizer,
@@ -37,7 +33,6 @@ namespace BTCPayServer.Controllers
{
_repo = storeRepository;
StringLocalizer = stringLocalizer;
- _userManager = userManager;
_defaultRules = defaultRules;
_rateFactory = rateFactory;
}
@@ -67,7 +62,7 @@ namespace BTCPayServer.Controllers
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie, Policy = Policies.CanModifyStoreSettingsUnscoped)]
public async Task<IActionResult> CreateStore(bool skipWizard)
{
- var stores = await _repo.GetStoresByUserId(GetUserId());
+ var stores = await _repo.GetStoresByUserId(User.GetId());
var defaultTemplate = await _repo.GetDefaultStoreTemplate();
var blob = defaultTemplate.GetStoreBlob();
var vm = new CreateStoreViewModel
@@ -89,7 +84,7 @@ namespace BTCPayServer.Controllers
{
if (!ModelState.IsValid)
{
- var stores = await _repo.GetStoresByUserId(GetUserId());
+ var stores = await _repo.GetStoresByUserId(User.GetId());
vm.IsFirstStore = !stores.Any();
var template = await _repo.GetDefaultStoreTemplate();
var defaultCurrency = template.GetStoreBlob().DefaultCurrency ?? StoreBlob.StandardDefaultCurrency;
@@ -108,7 +103,7 @@ namespace BTCPayServer.Controllers
rate.RateScripting = false;
}
store.SetStoreBlob(blob);
- await _repo.CreateStore(GetUserId(), store);
+ await _repo.CreateStore(User.GetId(), store);
CreatedStoreId = store.Id;
TempData.SetStatusSuccess(StringLocalizer["Store successfully created"]);
return RedirectToAction(nameof(UIStoresController.Index), "UIStores", new
@@ -131,17 +126,14 @@ namespace BTCPayServer.Controllers
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie, Policy = Policies.CanModifyStoreSettings)]
public async Task<IActionResult> DeleteStorePost(string storeId)
{
- var userId = GetUserId();
var store = HttpContext.GetStoreData();
if (store == null)
return NotFound();
- await _repo.RemoveStore(storeId, userId);
+ await _repo.RemoveStore(storeId, User.GetId());
TempData.SetStatusSuccess(StringLocalizer["Store removed successfully"]);
return RedirectToAction(nameof(UIHomeController.Index), "UIHome");
}
- private string GetUserId() => _userManager.GetUserId(User);
-
internal SelectList GetExchangesSelectList(string defaultCurrency, StoreBlob.RateSettings rateSettings)
{
if (rateSettings is null)
diff --git a/BTCPayServer/Controllers/UIWalletsController.cs b/BTCPayServer/Controllers/UIWalletsController.cs
index 355e463..80f945b 100644
--- a/BTCPayServer/Controllers/UIWalletsController.cs
+++ b/BTCPayServer/Controllers/UIWalletsController.cs
@@ -61,8 +61,6 @@ namespace BTCPayServer.Controllers
private IServiceProvider ServiceProvider { get; }
private RateFetcher RateFetcher { get; }
private IStringLocalizer StringLocalizer { get; }
-
- private readonly UserManager<ApplicationUser> _userManager;
private readonly NBXplorerDashboard _dashboard;
private readonly IAuthorizationService _authorizationService;
private readonly IFeeProviderFactory _feeRateProvider;
@@ -90,7 +88,6 @@ namespace BTCPayServer.Controllers
WalletRepository walletRepository,
CurrencyNameTable currencyTable,
BTCPayNetworkProvider networkProvider,
- UserManager<ApplicationUser> userManager,
NBXplorerDashboard dashboard,
WalletHistogramService walletHistogramService,
RateFetcher rateProvider,
@@ -126,7 +123,6 @@ namespace BTCPayServer.Controllers
RateFetcher = rateProvider;
_authorizationService = authorizationService;
NetworkProvider = networkProvider;
- _userManager = userManager;
_dashboard = dashboard;
ExplorerClientProvider = explorerProvider;
_feeRateProvider = feeRateProvider;
@@ -1980,7 +1976,7 @@ namespace BTCPayServer.Controllers
return null;
}
- private string? GetUserId() => _userManager.GetUserId(User)!;
+ private string? GetUserId() => User.GetIdOrNull();
private StoreData GetCurrentStore() => HttpContext.GetStoreData();
}
diff --git a/BTCPayServer/Data/Payouts/LightningLike/UILightningLikePayoutController.cs b/BTCPayServer/Data/Payouts/LightningLike/UILightningLikePayoutController.cs
index ccf6e13..3ffb39a 100644
--- a/BTCPayServer/Data/Payouts/LightningLike/UILightningLikePayoutController.cs
+++ b/BTCPayServer/Data/Payouts/LightningLike/UILightningLikePayoutController.cs
@@ -16,7 +16,6 @@ using BTCPayServer.Services;
using BTCPayServer.Services.Invoices;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
@@ -28,7 +27,6 @@ namespace BTCPayServer.Data.Payouts.LightningLike
{
private readonly ApplicationDbContextFactory _applicationDbContextFactory;
private readonly LightningAutomatedPayoutSenderFactory _lightningAutomatedPayoutSenderFactory;
- private readonly UserManager<ApplicationUser> _userManager;
private readonly BTCPayNetworkJsonSerializerSettings _btcPayNetworkJsonSerializerSettings;
private readonly PayoutMethodHandlerDictionary _payoutHandlers;
private readonly PaymentMethodHandlerDictionary _handlers;
@@ -40,7 +38,6 @@ namespace BTCPayServer.Data.Payouts.LightningLike
public UILightningLikePayoutController(ApplicationDbContextFactory applicationDbContextFactory,
LightningAutomatedPayoutSenderFactory lightningAutomatedPayoutSenderFactory,
- UserManager<ApplicationUser> userManager,
BTCPayNetworkJsonSerializerSettings btcPayNetworkJsonSerializerSettings,
PayoutMethodHandlerDictionary payoutHandlers,
PaymentMethodHandlerDictionary handlers,
@@ -52,7 +49,6 @@ namespace BTCPayServer.Data.Payouts.LightningLike
{
_applicationDbContextFactory = applicationDbContextFactory;
_lightningAutomatedPayoutSenderFactory = lightningAutomatedPayoutSenderFactory;
- _userManager = userManager;
_btcPayNetworkJsonSerializerSettings = btcPayNetworkJsonSerializerSettings;
_payoutHandlers = payoutHandlers;
_handlers = handlers;
@@ -66,7 +62,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
private async Task<List<PayoutData>> GetPayouts(ApplicationDbContext dbContext, PayoutMethodId pmi,
string[] payoutIds)
{
- var userId = _userManager.GetUserId(User);
+ var userId = User.GetId();
if (string.IsNullOrEmpty(userId))
{
return new List<PayoutData>();
@@ -198,7 +194,7 @@ namespace BTCPayServer.Data.Payouts.LightningLike
if (string.IsNullOrEmpty(storeId))
return;
- var userId = _userManager.GetUserId(User);
+ var userId = User.GetId();
var store = await _storeRepository.FindStore(storeId, userId);
if (store != null)
{
diff --git a/BTCPayServer/Extensions.cs b/BTCPayServer/Extensions.cs
index 2a44807..db7a32c 100644
--- a/BTCPayServer/Extensions.cs
+++ b/BTCPayServer/Extensions.cs
@@ -743,12 +743,19 @@ namespace BTCPayServer
}
#nullable enable
- public static string GetUserId(this IPrincipal? principal)
+ /// <summary>
+ /// Returns the user ID or empty string
+ /// </summary>
+ /// <param name="principal"></param>
+ /// <returns></returns>
+ public static string GetId(this IPrincipal? principal)
+ => GetIdOrNull(principal) ?? "";
+ public static string? GetIdOrNull(this IPrincipal? principal)
{
var claimsPrincipal = principal as ClaimsPrincipal;
if (claimsPrincipal is null)
- return "";
- return claimsPrincipal.FindFirstValue(ClaimTypes.NameIdentifier) ?? "";
+ return null;
+ return claimsPrincipal.FindFirstValue(ClaimTypes.NameIdentifier) ?? null;
}
public static StoreData AddCachedStoreData(this HttpContext ctx, StoreData storeData)
diff --git a/BTCPayServer/Fido2/UIFido2Controller.cs b/BTCPayServer/Fido2/UIFido2Controller.cs
index 0fe30a9..592f3ee 100644
--- a/BTCPayServer/Fido2/UIFido2Controller.cs
+++ b/BTCPayServer/Fido2/UIFido2Controller.cs
@@ -3,10 +3,8 @@ using BTCPayServer.Abstractions.Constants;
using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Abstractions.Models;
using BTCPayServer.Client;
-using BTCPayServer.Data;
using BTCPayServer.Fido2.Models;
using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
@@ -14,21 +12,11 @@ namespace BTCPayServer.Fido2
{
[Route("fido2")]
[Authorize(AuthenticationSchemes = AuthenticationSchemes.Cookie, Policy = Policies.CanViewProfile)]
- public class UIFido2Controller : Controller
+ public class UIFido2Controller(
+ Fido2Service fido2Service,
+ IStringLocalizer stringLocalizer) : Controller
{
- private readonly UserManager<ApplicationUser> _userManager;
- private readonly Fido2Service _fido2Service;
- private IStringLocalizer StringLocalizer { get; }
-
- public UIFido2Controller(
- UserManager<ApplicationUser> userManager,
- Fido2Service fido2Service,
- IStringLocalizer stringLocalizer)
- {
- _userManager = userManager;
- _fido2Service = fido2Service;
- StringLocalizer = stringLocalizer;
- }
+ private IStringLocalizer StringLocalizer { get; } = stringLocalizer;
[HttpGet("{id}/delete")]
public IActionResult Remove(string id)
@@ -39,7 +27,7 @@ namespace BTCPayServer.Fido2
[HttpPost("{id}/delete")]
public async Task<IActionResult> RemoveP(string id)
{
- await _fido2Service.Remove(id, _userManager.GetUserId(User));
+ await fido2Service.Remove(id, User.GetId());
TempData.SetStatusMessageModel(new StatusMessageModel
{
@@ -53,7 +41,7 @@ namespace BTCPayServer.Fido2
[HttpGet("register")]
public async Task<IActionResult> Create(AddFido2CredentialViewModel viewModel)
{
- var options = await _fido2Service.RequestCreation(_userManager.GetUserId(User));
+ var options = await fido2Service.RequestCreation(User.GetId());
if (options is null)
{
TempData.SetStatusMessageModel(new StatusMessageModel
@@ -72,7 +60,7 @@ namespace BTCPayServer.Fido2
[HttpPost("register")]
public async Task<IActionResult> CreateResponse([FromForm] string data, [FromForm] string name)
{
- if (await _fido2Service.CompleteCreation(_userManager.GetUserId(User), name, data))
+ if (await fido2Service.CompleteCreation(User.GetId(), name, data))
{
TempData.SetStatusMessageModel(new StatusMessageModel
diff --git a/BTCPayServer/Plugins/Bitpay/Controllers/UIStoresTokenController.cs b/BTCPayServer/Plugins/Bitpay/Controllers/UIStoresTokenController.cs
index a2a4528..3c6be52 100644
--- a/BTCPayServer/Plugins/Bitpay/Controllers/UIStoresTokenController.cs
+++ b/BTCPayServer/Plugins/Bitpay/Controllers/UIStoresTokenController.cs
@@ -32,14 +32,13 @@ public class UIStoresTokenController(
BitpayAccessTokenController tokenController,
IStringLocalizer stringLocalizer,
StoreRepository storeRepository,
- UserManager<ApplicationUser> userManager,
IHtmlHelper html,
PaymentMethodHandlerDictionary handlers,
PermissionService permissionService) : Controller
{
public IStringLocalizer StringLocalizer { get; } = stringLocalizer;
public StoreData CurrentStore => HttpContext.GetStoreData() ?? throw new InvalidOperationException("Store not found");
- private string? GetUserId() => userManager.GetUserId(User);
+ private string? GetUserId() => User.GetIdOrNull();
[TempData]
public bool StoreNotConfigured { get; set; }
diff --git a/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs b/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs
index 2078b4b..1218229 100644
--- a/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs
+++ b/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs
@@ -25,7 +25,6 @@ using BTCPayServer.Services.Rates;
using BTCPayServer.Services.Stores;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
-using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using NBitcoin;
@@ -47,7 +46,6 @@ namespace BTCPayServer.Plugins.Crowdfund.Controllers
StoreRepository storeRepository,
IFileService fileService,
UIInvoiceController invoiceController,
- UserManager<ApplicationUser> userManager,
FormDataService formDataService,
IStringLocalizer stringLocalizer,
CrowdfundAppType appType,
@@ -587,7 +585,7 @@ namespace BTCPayServer.Plugins.Crowdfund.Controllers
private AppData GetCurrentApp() => HttpContext.GetAppData();
- private string GetUserId() => userManager.GetUserId(User);
+ private string GetUserId() => User.GetIdOrNull();
private async Task<ViewCrowdfundViewModel> GetAppInfo(string appId)
{
diff --git a/BTCPayServer/Plugins/Monetization/Controllers/UIServerMonetizationController.cs b/BTCPayServer/Plugins/Monetization/Controllers/UIServerMonetizationController.cs
index fe180ce..d50ac5d 100644
--- a/BTCPayServer/Plugins/Monetization/Controllers/UIServerMonetizationController.cs
+++ b/BTCPayServer/Plugins/Monetization/Controllers/UIServerMonetizationController.cs
@@ -39,7 +39,6 @@ public class UIServerMonetizationController(
SettingsRepository settingsRepository,
AppService appService,
CurrencyNameTable currencyNameTable,
- UserManager<ApplicationUser> userManager,
StoreRepository storeRepo,
ViewLocalizer viewLocalizer,
EmailSenderFactory emailSenderFactory,
@@ -83,7 +82,7 @@ public class UIServerMonetizationController(
.ToArrayAsync()).ToHashSet();
}
- var stores = await storeRepo.GetStoresByUserId(userManager.GetUserId(User)!);
+ var stores = await storeRepo.GetStoresByUserId(User.GetId());
if (vm.Offering is null)
{
var vmSelect = new SelectExistingOfferingModalViewModel();
@@ -152,7 +151,7 @@ public class UIServerMonetizationController(
if (command == "activate-monetization" && vm.ActivateModal is {} activateModal)
{
var selectedStore = vm.ActivateModal?.SelectedStoreId ?? "";
- var store = await storeRepo.FindStore(selectedStore, userManager.GetUserId(User) ?? "");
+ var store = await storeRepo.FindStore(selectedStore, User.GetId());
if (store is null)
{
TempData.SetStatusMessageModel(new()
@@ -318,7 +317,7 @@ public class UIServerMonetizationController(
var settings = await settingsRepository.GetSettingAsync<MonetizationSettings>();
var offeringAndPlan = await ctx.GetOfferingAndPlan(settings);
if (offeringAndPlan is { Offering: { } offering } &&
- await storeRepo.FindStore(offering.App.StoreDataId, userManager.GetUserId(User) ?? "") is { } store)
+ await storeRepo.FindStore(offering.App.StoreDataId, User.GetId()) is { } store)
{
var storeBlob = store.GetStoreBlob();
var policies = await settingsRepository.GetSettingAsync<PoliciesSettings>() ?? new();
diff --git a/BTCPayServer/Plugins/Monetization/Controllers/UIUserMonetizationController.cs b/BTCPayServer/Plugins/Monetization/Controllers/UIUserMonetizationController.cs
index 630f441..1661e33 100644
--- a/BTCPayServer/Plugins/Monetization/Controllers/UIUserMonetizationController.cs
+++ b/BTCPayServer/Plugins/Monetization/Controllers/UIUserMonetizationController.cs
@@ -21,7 +21,6 @@ public class UIUserMonetizationController(
ApplicationDbContext ctx,
MonetizationSettings settings,
PoliciesSettings policies,
- UserManager<ApplicationUser> userManager,
LinkGenerator linkGenerator
) : Controller
{
@@ -55,7 +54,7 @@ public class UIUserMonetizationController(
{
if (settings.OfferingId is not { } offeringId)
return NotFound();
- var userId = userManager.GetUserId(User);
+ var userId = User.GetId();
var sub = await ctx.Subscribers.GetBySelector(offeringId, CustomerSelector.ByIdentity(SubscriberDataExtensions.IdentityType, userId));
if (sub is null)
return NotFound();
diff --git a/BTCPayServer/Plugins/PayButton/Controllers/UIPayButtonController.cs b/BTCPayServer/Plugins/PayButton/Controllers/UIPayButtonController.cs
index 07f4254..4316df6 100644
--- a/BTCPayServer/Plugins/PayButton/Controllers/UIPayButtonController.cs
+++ b/BTCPayServer/Plugins/PayButton/Controllers/UIPayButtonController.cs
@@ -23,7 +23,6 @@ namespace BTCPayServer.Plugins.PayButton.Controllers
public class UIPayButtonController(
StoreRepository repo,
UIStoresController storesController,
- UserManager<ApplicationUser> userManager,
IStringLocalizer stringLocalizer,
AppService appService)
: Controller
@@ -51,7 +50,7 @@ namespace BTCPayServer.Plugins.PayButton.Controllers
return View("Enable", null);
}
- var apps = await appService.GetAllApps(userManager.GetUserId(User), false, store.Id);
+ var apps = await appService.GetAllApps(User.GetId(), false, store.Id);
// unset app store data, because we don't need it and inclusion leads to circular references when serializing to JSON
foreach (var app in apps)
{
diff --git a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs
index 98a9b92..0c2ecc4 100644
--- a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs
+++ b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs
@@ -59,7 +59,6 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
DisplayFormatter displayFormatter,
IRateLimitService rateLimitService,
IAuthorizationService authorizationService,
- UserManager<ApplicationUser> userManager,
HtmlSanitizer htmlSanitizer,
Safe safe)
{
@@ -72,7 +71,6 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
_displayFormatter = displayFormatter;
_rateLimitService = rateLimitService;
_authorizationService = authorizationService;
- _userManager = userManager;
_htmlSanitizer = htmlSanitizer;
_safe = safe;
StringLocalizer = stringLocalizer;
@@ -88,7 +86,6 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
private readonly DisplayFormatter _displayFormatter;
private readonly IRateLimitService _rateLimitService;
private readonly IAuthorizationService _authorizationService;
- private readonly UserManager<ApplicationUser> _userManager;
private readonly HtmlSanitizer _htmlSanitizer;
private readonly Safe _safe;
public FormDataService FormDataService { get; }
@@ -752,7 +749,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers
var users = await _storeRepository.GetStoreUsers(GetCurrentStore().Id);
if (!User.IsInRole(Roles.ServerAdmin))
- users = users.Where(u => u.Id == _userManager.GetUserId(User)).ToArray();
+ users = users.Where(u => u.Id == User.GetId()).ToArray();
vm.StoreUsers = users.Select(u => (u.Id, u.Email, u.StoreRole.Role))
.ToDictionary(u => u.Id, u => $"{u.Email} ({u.Role})");
diff --git a/BTCPayServer/Security/BuiltInPermissionHandler.cs b/BTCPayServer/Security/BuiltInPermissionHandler.cs
index d474204..6d50a20 100644
--- a/BTCPayServer/Security/BuiltInPermissionHandler.cs
+++ b/BTCPayServer/Security/BuiltInPermissionHandler.cs
@@ -92,9 +92,8 @@ public class BuiltInPermissionHandler(
store.UserStores.Any(u => u.ApplicationUserId == permContext.UserId))
return store;
}
- store = await storeRepository.FindStore(storeId, permContext.UserId);
- if (store is null && isAdmin)
- store = await storeRepository.FindStore(storeId);
+ if (store is null)
+ store = await storeRepository.FindStore(storeId, permContext.HttpContext.User, true);
if (store is not null)
permContext.HttpContext.AddCachedStoreData(store);
return store;
diff --git a/BTCPayServer/Security/BuiltInPermissionScopeProvider.cs b/BTCPayServer/Security/BuiltInPermissionScopeProvider.cs
index e6d808e..4e4545c 100644
--- a/BTCPayServer/Security/BuiltInPermissionScopeProvider.cs
+++ b/BTCPayServer/Security/BuiltInPermissionScopeProvider.cs
@@ -60,7 +60,7 @@ public class BuiltInPermissionScopeProvider(
if (storeId == null)
{
if (httpContext.Request.HasFormContentType &&
- httpContext.Request.Form.TryGetValue("storeId", out var sv))
+ (await httpContext.Request.ReadFormAsync()).TryGetValue("storeId", out var sv))
{
storeId = sv.FirstOrDefault();
}
diff --git a/BTCPayServer/Security/PermissionAuthorizationHandler.cs b/BTCPayServer/Security/PermissionAuthorizationHandler.cs
index 42f2756..a28a8dd 100644
--- a/BTCPayServer/Security/PermissionAuthorizationHandler.cs
+++ b/BTCPayServer/Security/PermissionAuthorizationHandler.cs
@@ -21,8 +21,8 @@ public class PermissionAuthorizationHandler(
{
if (context.User.Identity is not ({ AuthenticationType: AuthenticationSchemes.Cookie } or { AuthenticationType: GreenfieldConstants.AuthenticationType }))
return;
- var userId = context.User.GetUserId();
- if (httpContext.HttpContext is null)
+ var userId = context.User.GetIdOrNull();
+ if (httpContext.HttpContext is null || userId is null)
return;
httpContext.HttpContext.Items[PolicyRequirementKey] = requirement;
diff --git a/BTCPayServer/Security/SetContextFilter.cs b/BTCPayServer/Security/SetContextFilter.cs
index 94f1912..214bb39 100644
--- a/BTCPayServer/Security/SetContextFilter.cs
+++ b/BTCPayServer/Security/SetContextFilter.cs
@@ -21,7 +21,7 @@ public class SetContextFilter(
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var httpContext = context.HttpContext;
- var userId = context.HttpContext.User.GetUserId();
+ var userId = context.HttpContext.User.GetId();
var isCookie = context.HttpContext.User.Identity is { AuthenticationType: AuthenticationSchemes.Cookie };
if (httpContext.Items.TryGetValue(BuiltInPermissionHandler.StoreKey, out var oo) && oo is StoreData store)
@@ -35,7 +35,7 @@ public class SetContextFilter(
var nav = httpContext.GetCachedStoreData(preferredStoreId);
if (nav is null)
{
- nav = await storeRepository.FindStore(preferredStoreId, httpContext.User.GetUserId());
+ nav = await storeRepository.FindStore(preferredStoreId, httpContext.User, true);
if (nav is not null)
httpContext.AddCachedStoreData(nav);
}
diff --git a/BTCPayServer/Services/BTCPayServerSecurityStampValidator.cs b/BTCPayServer/Services/BTCPayServerSecurityStampValidator.cs
index 8ab27da..ffdc080 100644
--- a/BTCPayServer/Services/BTCPayServerSecurityStampValidator.cs
+++ b/BTCPayServer/Services/BTCPayServerSecurityStampValidator.cs
@@ -17,7 +17,6 @@ public class BTCPayServerSecurityStampValidator(
IOptions<SecurityStampValidatorOptions> options,
SignInManager<ApplicationUser> signInManager,
ILoggerFactory logger,
- UserManager<ApplicationUser> userManager,
BTCPayServerSecurityStampValidator.DisabledUsers disabledUsers)
: SecurityStampValidator<ApplicationUser>(options, signInManager, logger)
{
@@ -58,8 +57,7 @@ public class BTCPayServerSecurityStampValidator(
public override async Task ValidateAsync(CookieValidatePrincipalContext context)
{
if (disabledUsers.HasAny &&
- context.Principal is not null &&
- userManager.GetUserId(context.Principal) is string id &&
+ context.Principal.GetIdOrNull() is string id &&
disabledUsers.Contains(id))
{
context.Properties.IssuedUtc = null;
diff --git a/BTCPayServer/Services/Stores/StoreRepository.cs b/BTCPayServer/Services/Stores/StoreRepository.cs
index 80e039d..0442113 100644
--- a/BTCPayServer/Services/Stores/StoreRepository.cs
+++ b/BTCPayServer/Services/Stores/StoreRepository.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Security.Principal;
using System.Threading.Tasks;
using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Client;
@@ -50,11 +51,25 @@ namespace BTCPayServer.Services.Stores
return result;
}
+ public async Task<StoreData?> FindStore(string storeId, IPrincipal user, bool adminCanAccess = false)
+ {
+ if (adminCanAccess && user.IsInRole(Roles.ServerAdmin))
+ {
+ await using var ctx = _ContextFactory.CreateContext();
+ return await ctx
+ .Stores.Where(s => s.Id == storeId)
+ .Include(store => store.UserStores)
+ .ThenInclude(store => store.StoreRole)
+ .FirstOrDefaultAsync();
+ }
+ return await FindStore(storeId, user.GetId());
+ }
+
public async Task<StoreData?> FindStore(string storeId, string userId)
{
ArgumentNullException.ThrowIfNull(userId);
if (string.IsNullOrEmpty(storeId) ||
- string.IsNullOrEmpty(userId) || userId == "???")
+ string.IsNullOrEmpty(userId))
return null;
await using var ctx = _ContextFactory.CreateContext();
return await ctx
@@ -250,6 +265,8 @@ namespace BTCPayServer.Services.Stores
public async Task<StoreData[]> GetStoresByUserId(string userId, IEnumerable<string>? storeIds = null)
{
+ if (userId == "")
+ return Array.Empty<StoreData>();
await using var ctx = _ContextFactory.CreateContext();
return (await ctx.UserStore
.Where(u => u.ApplicationUserId == userId && (storeIds == null || storeIds.Contains(u.StoreDataId)))
diff --git a/BTCPayServer/Views/UIManage/LoginCodes.cshtml b/BTCPayServer/Views/UIManage/LoginCodes.cshtml
index 40a88f6..be74977 100644
--- a/BTCPayServer/Views/UIManage/LoginCodes.cshtml
+++ b/BTCPayServer/Views/UIManage/LoginCodes.cshtml
@@ -1,4 +1,3 @@
-@inject UserManager<ApplicationUser> UserManager;
@{
ViewData.SetLayoutModel(new LayoutModel(nameof(ManageNavPages.LoginCodes), StringLocalizer["Login Codes"])
.SetCategory(nameof(ManageNavPages)));
@@ -9,4 +8,4 @@
</div>
<partial name="_StatusMessage" />
<p text-translate="true">Easily log into BTCPay Server on another device using a simple login code from an already authenticated device.</p>
-<component type="typeof(BTCPayServer.Blazor.UserLoginCode)" render-mode="ServerPrerendered" param-UserId="@UserManager.GetUserId(User)" param-id="@("LoginCode")"/>
+<component type="typeof(BTCPayServer.Blazor.UserLoginCode)" render-mode="ServerPrerendered" param-UserId="@User.GetId()" param-id="@("LoginCode")"/>
Why this scored 34/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.