diff --git a/BTCPayServer.Tests/ApiKeysTests.cs b/BTCPayServer.Tests/ApiKeysTests.cs index e19771b11..e18ee5830 100644 --- a/BTCPayServer.Tests/ApiKeysTests.cs +++ b/BTCPayServer.Tests/ApiKeysTests.cs @@ -12,6 +12,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OpenQA.Selenium; using OpenQA.Selenium.Support.Extensions; +using OpenQA.Selenium.Support.UI; using Xunit; using Xunit.Abstractions; using StoreData = BTCPayServer.Data.StoreData; @@ -57,6 +58,7 @@ namespace BTCPayServer.Tests s.GoToProfile(ManageNavPages.APIKeys); s.Driver.FindElement(By.Id("AddApiKey")).Click(); Assert.Contains("btcpay.server.canmodifyserversettings", s.Driver.PageSource); + //server management should show now s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), true); s.Driver.SetCheckbox(By.Id("btcpay.store.canmodifystoresettings"), true); @@ -136,10 +138,26 @@ namespace BTCPayServer.Tests var appidentifier = "testapp"; var callbackUrl = s.ServerUri + "postredirect-callback-test"; var authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri, + new[] { Policies.CanModifyServerSettings }, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString(); + + // No upfront store selection with only server settings + TestLogs.LogInformation($"Going to auth URL {authUrl}"); + s.GoToUrl(authUrl); + Assert.Contains(appidentifier, s.Driver.PageSource); + Assert.False(s.Driver.FindElement(By.Id("SpecificStores")).Displayed); + + // Now with store settings + authUrl = BTCPayServerClient.GenerateAuthorizeUri(s.ServerUri, new[] { Policies.CanModifyStoreSettings, Policies.CanModifyServerSettings }, applicationDetails: (appidentifier, new Uri(callbackUrl))).ToString(); TestLogs.LogInformation($"Going to auth URL {authUrl}"); s.GoToUrl(authUrl); Assert.Contains(appidentifier, s.Driver.PageSource); + + // Select a store + var select = new SelectElement(s.Driver.FindElement(By.Id("SpecificStores"))); + select.SelectByIndex(0); + s.Driver.FindElement(By.Id("continue")).Click(); + Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant()); Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant()); Assert.Equal("hidden", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant()); @@ -168,13 +186,17 @@ namespace BTCPayServer.Tests TestLogs.LogInformation("On auth URL 2"); Assert.DoesNotContain("kukksappname", s.Driver.PageSource); + // Select a store + select = new SelectElement(s.Driver.FindElement(By.Id("SpecificStores"))); + select.SelectByIndex(0); + s.Driver.FindElement(By.Id("continue")).Click(); + Assert.Equal("checkbox", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("type").ToLowerInvariant()); Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.store.canmodifystoresettings")).GetAttribute("value").ToLowerInvariant()); Assert.Equal("checkbox", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("type").ToLowerInvariant()); Assert.Equal("true", s.Driver.FindElement(By.Id("btcpay.server.canmodifyserversettings")).GetAttribute("value").ToLowerInvariant()); s.Driver.SetCheckbox(By.Id("btcpay.server.canmodifyserversettings"), false); - Assert.Contains("change-store-mode", s.Driver.PageSource); TestLogs.LogInformation("Going to callback URL 2"); s.Driver.WaitForAndClick(By.Id("consent-yes")); diff --git a/BTCPayServer.Tests/SeleniumTester.cs b/BTCPayServer.Tests/SeleniumTester.cs index 37c366258..fb4402e42 100644 --- a/BTCPayServer.Tests/SeleniumTester.cs +++ b/BTCPayServer.Tests/SeleniumTester.cs @@ -362,6 +362,10 @@ namespace BTCPayServer.Tests public void Logout() { + if (!Driver.PageSource.Contains("id=\"Nav-Logout\"")) + { + Driver.Navigate().GoToUrl(ServerUri); + } Driver.FindElement(By.Id("Nav-Account")).Click(); Driver.FindElement(By.Id("Nav-Logout")).Click(); } diff --git a/BTCPayServer/Controllers/UIManageController.APIKeys.cs b/BTCPayServer/Controllers/UIManageController.APIKeys.cs index e20aff642..fff2c2dc4 100644 --- a/BTCPayServer/Controllers/UIManageController.APIKeys.cs +++ b/BTCPayServer/Controllers/UIManageController.APIKeys.cs @@ -191,6 +191,7 @@ namespace BTCPayServer.Controllers private void AdjustVMForAuthorization(AuthorizeApiKeysViewModel vm) { + var storeIds = vm.SpecificStores.ToArray(); var permissions = vm.Permissions?.Split(';') ?? Array.Empty(); var permissionsWithStoreIDs = new List(); @@ -198,20 +199,18 @@ namespace BTCPayServer.Controllers // Go over each permission and associated store IDs and join them // so that permission for a specific store is parsed correctly - for (var i = 0; i < permissions.Length; i++) + foreach (var permission in permissions) { - var currPerm = permissions[i]; - var storeIds = vm.SpecificStores.ToArray(); - if (storeIds.Length > 0) + if (!Policies.IsStorePolicy(permission) || storeIds.Length == 0) { - for (var x = 0; x < storeIds.Length; x++) - { - permissionsWithStoreIDs.Add($"{currPerm}:{storeIds[x]}"); - } + permissionsWithStoreIDs.Add(permission); } else { - permissionsWithStoreIDs.Add(currPerm); + foreach (var t in storeIds) + { + permissionsWithStoreIDs.Add($"{permission}:{t}"); + } } } @@ -220,7 +219,7 @@ namespace BTCPayServer.Controllers for (var index = vm.PermissionValues.Count - 1; index >= 0; index--) { var permissionValue = vm.PermissionValues[index]; - var wanted = parsedPermissions?.SingleOrDefault(permission => + var wanted = parsedPermissions.SingleOrDefault(permission => permission.Key.Equals(permissionValue.Permission, StringComparison.InvariantCultureIgnoreCase)); if (vm.Strict && !(wanted?.Any() ?? false)) @@ -240,6 +239,9 @@ namespace BTCPayServer.Controllers continue; } + // Set the value to true and adjust the other fields based on the policy type + permissionValue.Value = true; + if (vm.SelectiveStores && Policies.IsStorePolicy(permissionValue.Permission) && wanted.Any(permission => !string.IsNullOrEmpty(permission.Scope))) { @@ -250,7 +252,6 @@ namespace BTCPayServer.Controllers { permissionValue.StoreMode = AddApiKeyViewModel.ApiKeyStoreMode.AllStores; permissionValue.SpecificStores = new List(); - permissionValue.Value = true; } } } diff --git a/BTCPayServer/Views/UIManage/AuthorizeAPIKey.cshtml b/BTCPayServer/Views/UIManage/AuthorizeAPIKey.cshtml index 93380aaf6..16bc2d147 100644 --- a/BTCPayServer/Views/UIManage/AuthorizeAPIKey.cshtml +++ b/BTCPayServer/Views/UIManage/AuthorizeAPIKey.cshtml @@ -83,6 +83,17 @@ + @if (Model.NeedsStorePermission && Model.SpecificStores.Any()) + { +

Stores

+
    + @foreach (var storeId in Model.SpecificStores) + { +
  • @Model.Stores.First(s => s.Id == storeId).StoreName
  • + } +
+ } +

Permissions

@if (!permissions.Any()) { @@ -94,7 +105,7 @@ else {
- @for (int i = 0; i < Model.PermissionValues.Count; i++) + @for (var i = 0; i < Model.PermissionValues.Count; i++) { @@ -102,67 +113,30 @@ @if (Model.PermissionValues[i].Forbidden && !Model.Strict) { continue; - } - @if (Policies.IsStorePolicy(Model.PermissionValues[i].Permission)) - { -
-
- @if (Model.Strict || Model.PermissionValues[i].Forbidden) - { - - - } - else - { - - } - @* Wrapper div prevents the label to be muted in case of disabled checkbox (strict mode) *@ -
- -
-
@Model.PermissionValues[i].Description
- - - @if (Model.PermissionValues[i].Forbidden) - { -
- - This permission is not available for your account. - - } -
-
} - else - { -
-
- @if (Model.Strict || Model.PermissionValues[i].Forbidden) - { - - - } - else - { - - } - @* Wrapper div prevents the label to be muted in case of disabled checkbox (strict mode) *@ -
- -
-
@Model.PermissionValues[i].Description
- - - @if (Model.PermissionValues[i].Forbidden) - { -
- - This permission is not available for your account. - - } +
+
+ @if (Model.Strict || Model.PermissionValues[i].Forbidden) + { + + + } + else + { + + } + @* Wrapper div prevents the label to be muted in case of disabled checkbox (strict mode) *@ +
+
+
@Model.PermissionValues[i].Description
+ + @if (Model.PermissionValues[i].Forbidden) + { +
This permission is not available for your account.
+ }
- } +
}
}