diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index 9841a004e..937d1d5ae 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -62,8 +62,10 @@ namespace BTCPayServer.Tests user.GrantAccess(); await user.MakeAdmin(); string apiKeyProfile = await GenerateAPIKey(tester, user, Permissions.ProfileManagement); + string apiKeyServer = await GenerateAPIKey(tester, user, Permissions.ServerManagement); string apiKeyInsufficient = await GenerateAPIKey(tester, user, Permissions.StoreManagement); var clientProfile = new BTCPayServerClient(tester.PayTester.ServerUri, apiKeyProfile); + var clientServer = new BTCPayServerClient(tester.PayTester.ServerUri, apiKeyServer); var clientInsufficient= new BTCPayServerClient(tester.PayTester.ServerUri, apiKeyInsufficient); var apiKeyProfileUserData = await clientProfile.GetCurrentUser(); @@ -72,6 +74,7 @@ namespace BTCPayServer.Tests Assert.Equal(apiKeyProfileUserData.Email, user.RegisterDetails.Email); await Assert.ThrowsAsync(async () => await clientInsufficient.GetCurrentUser()); + await clientServer.GetCurrentUser(); } } diff --git a/BTCPayServer/Security/APIKeys/APIKeyAuthorizationHandler.cs b/BTCPayServer/Security/APIKeys/APIKeyAuthorizationHandler.cs index fe2f5bfc2..71c27e698 100644 --- a/BTCPayServer/Security/APIKeys/APIKeyAuthorizationHandler.cs +++ b/BTCPayServer/Security/APIKeys/APIKeyAuthorizationHandler.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Security.Claims; using System.Threading.Tasks; using BTCPayServer.Client; using BTCPayServer.Data; @@ -69,20 +70,32 @@ namespace BTCPayServer.Security.APIKeys case Policies.CanModifyServerSettings.Key: if (!context.HasPermissions(Permissions.ServerManagement)) break; - // For this authorization, we stil check in database because it is super sensitive. - var user = await _userManager.GetUserAsync(context.User); - if (user == null) - break; - if (!await _userManager.IsInRoleAsync(user, Roles.ServerAdmin)) - break; - success = true; + // For this authorization, we still check in database because it is super sensitive. + success = await IsUserAdmin(context.User); break; } + //if you do not have the specific permissions, BUT you have server management, we enable god mode + if (!success && context.HasPermissions(Permissions.ServerManagement) && + requirement.Policy != Policies.CanModifyServerSettings.Key) + { + success = await IsUserAdmin(context.User); + } + if (success) { context.Succeed(requirement); } } + + private async Task IsUserAdmin(ClaimsPrincipal contextUser) + { + var user = await _userManager.GetUserAsync(contextUser); + if (user == null) + return false; + if (!await _userManager.IsInRoleAsync(user, Roles.ServerAdmin)) + return false; + return true; + } } }