keycloak-uncached
Changes
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java 14(+9 -5)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermission.java 8(+6 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermissionForm.java 71(+68 -3)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermission.java 12(+10 -2)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermissionForm.java 71(+68 -3)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java 38(+0 -38)
testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/PolicySelect.java 59(+59 -0)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java 33(+32 -1)
testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java 68(+67 -1)
themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html 37(+21 -16)
Details
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
index fcb5b8c..2872658 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java
@@ -56,16 +56,16 @@ public class Permissions extends Form {
return table;
}
- public <P extends PolicyTypeUI> P create(AbstractPolicyRepresentation expected) {
+ public <P extends PolicyTypeUI> P create(AbstractPolicyRepresentation expected, boolean save) {
String type = expected.getType();
createSelect.selectByValue(type);
if ("resource".equals(type)) {
- resourcePermission.form().populate((ResourcePermissionRepresentation) expected);
+ resourcePermission.form().populate((ResourcePermissionRepresentation) expected, save);
return (P) resourcePermission;
} else if ("scope".equals(type)) {
- scopePermission.form().populate((ScopePermissionRepresentation) expected);
+ scopePermission.form().populate((ScopePermissionRepresentation) expected, save);
return (P) scopePermission;
}
@@ -73,6 +73,10 @@ public class Permissions extends Form {
}
public void update(String name, AbstractPolicyRepresentation representation) {
+ update(name, representation, true);
+ }
+
+ public void update(String name, AbstractPolicyRepresentation representation, boolean save) {
for (WebElement row : permissions().rows()) {
PolicyRepresentation actual = permissions().toRepresentation(row);
if (actual.getName().equalsIgnoreCase(name)) {
@@ -81,9 +85,9 @@ public class Permissions extends Form {
String type = representation.getType();
if ("resource".equals(type)) {
- resourcePermission.form().populate((ResourcePermissionRepresentation) representation);
+ resourcePermission.form().populate((ResourcePermissionRepresentation) representation, save);
} else if ("scope".equals(type)) {
- scopePermission.form().populate((ScopePermissionRepresentation) representation);
+ scopePermission.form().populate((ScopePermissionRepresentation) representation, save);
}
return;
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermission.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermission.java
index d6c4f3a..ba5302d 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermission.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermission.java
@@ -17,7 +17,7 @@
package org.keycloak.testsuite.console.page.clients.authorization.permission;
import org.jboss.arquillian.graphene.page.Page;
-import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicyTypeUI;
@@ -38,6 +38,10 @@ public class ResourcePermission implements PolicyTypeUI {
}
public void update(ResourcePermissionRepresentation expected) {
- form().populate(expected);
+ form().populate(expected, true);
+ }
+
+ public void createPolicy(AbstractPolicyRepresentation expected) {
+ form().createPolicy(expected);
}
}
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermissionForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermissionForm.java
index d53f820..b473044 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermissionForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ResourcePermissionForm.java
@@ -16,8 +16,27 @@
*/
package org.keycloak.testsuite.console.page.clients.authorization.permission;
+import static org.keycloak.testsuite.util.UIUtils.performOperationWithPageReload;
+
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
+import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
+import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.RulePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.ClientPolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.GroupPolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.JSPolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicySelect;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.RolePolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.RulePolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.TimePolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.UserPolicy;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
@@ -53,12 +72,36 @@ public class ResourcePermissionForm extends Form {
protected ModalDialog modalDialog;
@FindBy(id = "s2id_policies")
- private MultipleStringSelect2 policySelect;
+ private PolicySelect policySelect;
@FindBy(id = "s2id_resources")
private MultipleStringSelect2 resourceSelect;
- public void populate(ResourcePermissionRepresentation expected) {
+ @FindBy(id = "create-policy")
+ private Select createPolicySelect;
+
+ @Page
+ private RolePolicy rolePolicy;
+
+ @Page
+ private UserPolicy userPolicy;
+
+ @Page
+ private ClientPolicy clientPolicy;
+
+ @Page
+ private JSPolicy jsPolicy;
+
+ @Page
+ private TimePolicy timePolicy;
+
+ @Page
+ private RulePolicy rulePolicy;
+
+ @Page
+ private GroupPolicy groupPolicy;
+
+ public void populate(ResourcePermissionRepresentation expected, boolean save) {
setInputValue(name, expected.getName());
setInputValue(description, expected.getDescription());
decisionStrategy.selectByValue(expected.getDecisionStrategy().name());
@@ -76,7 +119,9 @@ public class ResourcePermissionForm extends Form {
policySelect.update(expected.getPolicies());
}
- save();
+ if (save) {
+ save();
+ }
}
public void delete() {
@@ -101,4 +146,24 @@ public class ResourcePermissionForm extends Form {
return representation;
}
+
+ public void createPolicy(AbstractPolicyRepresentation expected) {
+ performOperationWithPageReload(() -> createPolicySelect.selectByValue(expected.getType()));
+
+ if ("role".equals(expected.getType())) {
+ rolePolicy.form().populate((RolePolicyRepresentation) expected, true);
+ } else if ("user".equalsIgnoreCase(expected.getType())) {
+ userPolicy.form().populate((UserPolicyRepresentation) expected, true);
+ } else if ("client".equalsIgnoreCase(expected.getType())) {
+ clientPolicy.form().populate((ClientPolicyRepresentation) expected, true);
+ } else if ("js".equalsIgnoreCase(expected.getType())) {
+ jsPolicy.form().populate((JSPolicyRepresentation) expected, true);
+ } else if ("time".equalsIgnoreCase(expected.getType())) {
+ timePolicy.form().populate((TimePolicyRepresentation) expected, true);
+ } else if ("rules".equalsIgnoreCase(expected.getType())) {
+ rulePolicy.form().populate((RulePolicyRepresentation) expected, true);
+ } else if ("group".equalsIgnoreCase(expected.getType())) {
+ groupPolicy.form().populate((GroupPolicyRepresentation) expected, true);
+ }
+ }
}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermission.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermission.java
index 5b392ad..cfeba8e 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermission.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermission.java
@@ -17,7 +17,7 @@
package org.keycloak.testsuite.console.page.clients.authorization.permission;
import org.jboss.arquillian.graphene.page.Page;
-import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
+import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicyTypeUI;
@@ -38,6 +38,14 @@ public class ScopePermission implements PolicyTypeUI {
}
public void update(ScopePermissionRepresentation expected) {
- form().populate(expected);
+ update(expected, true);
+ }
+
+ public void update(ScopePermissionRepresentation expected, boolean save) {
+ form().populate(expected, save);
+ }
+
+ public void createPolicy(AbstractPolicyRepresentation expected) {
+ form().createPolicy(expected);
}
}
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermissionForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermissionForm.java
index 696ff22..4172843 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermissionForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/ScopePermissionForm.java
@@ -16,11 +16,30 @@
*/
package org.keycloak.testsuite.console.page.clients.authorization.permission;
+import static org.keycloak.testsuite.util.UIUtils.performOperationWithPageReload;
+
import java.util.Set;
import java.util.function.Function;
+import org.jboss.arquillian.graphene.page.Page;
+import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
+import org.keycloak.representations.idm.authorization.GroupPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
+import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.RulePolicyRepresentation;
import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
+import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
+import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.ClientPolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.GroupPolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.JSPolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicySelect;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.RolePolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.RulePolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.TimePolicy;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.UserPolicy;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
import org.keycloak.testsuite.console.page.fragment.SingleStringSelect2;
@@ -50,7 +69,7 @@ public class ScopePermissionForm extends Form {
protected ModalDialog modalDialog;
@FindBy(id = "s2id_policies")
- private MultipleStringSelect2 policySelect;
+ private PolicySelect policySelect;
@FindBy(id = "s2id_scopes")
private MultipleStringSelect2 scopeSelect;
@@ -61,7 +80,31 @@ public class ScopePermissionForm extends Form {
@FindBy(id = "s2id_resources")
private ResourceSelect resourceSelect;
- public void populate(ScopePermissionRepresentation expected) {
+ @FindBy(id = "create-policy")
+ private Select createPolicySelect;
+
+ @Page
+ private RolePolicy rolePolicy;
+
+ @Page
+ private UserPolicy userPolicy;
+
+ @Page
+ private ClientPolicy clientPolicy;
+
+ @Page
+ private JSPolicy jsPolicy;
+
+ @Page
+ private TimePolicy timePolicy;
+
+ @Page
+ private RulePolicy rulePolicy;
+
+ @Page
+ private GroupPolicy groupPolicy;
+
+ public void populate(ScopePermissionRepresentation expected, boolean save) {
setInputValue(name, expected.getName());
setInputValue(description, expected.getDescription());
decisionStrategy.selectByValue(expected.getDecisionStrategy().name());
@@ -79,7 +122,9 @@ public class ScopePermissionForm extends Form {
policySelect.update(expected.getPolicies());
}
- save();
+ if (save) {
+ save();
+ }
}
public void delete() {
@@ -107,4 +152,24 @@ public class ScopePermissionForm extends Form {
return super.representation().andThen(s -> "".equals(s) || s.contains("Any resource...") ? null : s);
}
}
+
+ public void createPolicy(AbstractPolicyRepresentation expected) {
+ performOperationWithPageReload(() -> createPolicySelect.selectByValue(expected.getType()));
+
+ if ("role".equals(expected.getType())) {
+ rolePolicy.form().populate((RolePolicyRepresentation) expected, true);
+ } else if ("user".equalsIgnoreCase(expected.getType())) {
+ userPolicy.form().populate((UserPolicyRepresentation) expected, true);
+ } else if ("client".equalsIgnoreCase(expected.getType())) {
+ clientPolicy.form().populate((ClientPolicyRepresentation) expected, true);
+ } else if ("js".equalsIgnoreCase(expected.getType())) {
+ jsPolicy.form().populate((JSPolicyRepresentation) expected, true);
+ } else if ("time".equalsIgnoreCase(expected.getType())) {
+ timePolicy.form().populate((TimePolicyRepresentation) expected, true);
+ } else if ("rules".equalsIgnoreCase(expected.getType())) {
+ rulePolicy.form().populate((RulePolicyRepresentation) expected, true);
+ } else if ("group".equalsIgnoreCase(expected.getType())) {
+ groupPolicy.form().populate((GroupPolicyRepresentation) expected, true);
+ }
+ }
}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java
index 8ed8c39..732f820 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/AggregatePolicyForm.java
@@ -17,13 +17,8 @@
package org.keycloak.testsuite.console.page.clients.authorization.policy;
import static org.keycloak.testsuite.util.UIUtils.performOperationWithPageReload;
-import static org.openqa.selenium.By.tagName;
-import java.util.List;
import java.util.Set;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.stream.Collectors;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
@@ -37,9 +32,7 @@ import org.keycloak.representations.idm.authorization.RulePolicyRepresentation;
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
import org.keycloak.testsuite.console.page.fragment.ModalDialog;
-import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
import org.keycloak.testsuite.page.Form;
-import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.Select;
@@ -162,35 +155,4 @@ public class AggregatePolicyForm extends Form {
groupPolicy.form().populate((GroupPolicyRepresentation) expected, true);
}
}
-
- public class PolicySelect extends MultipleStringSelect2 {
-
- @Override
- protected List<WebElement> getSelectedElements() {
- return getRoot().findElements(By.xpath("(//table[@id='selected-policies'])/tbody/tr")).stream()
- .filter(webElement -> webElement.findElements(tagName("td")).size() > 1)
- .collect(Collectors.toList());
- }
-
- @Override
- protected BiFunction<WebElement, String, Boolean> deselect() {
- return (webElement, name) -> {
- List<WebElement> tds = webElement.findElements(tagName("td"));
-
- if (!tds.get(0).getText().isEmpty()) {
- if (tds.get(0).getText().equals(name)) {
- tds.get(3).click();
- return true;
- }
- }
-
- return false;
- };
- }
-
- @Override
- protected Function<WebElement, String> representation() {
- return webElement -> webElement.findElements(tagName("td")).get(0).getText();
- }
- }
}
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/PolicySelect.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/PolicySelect.java
new file mode 100644
index 0000000..ffae31d
--- /dev/null
+++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/PolicySelect.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.console.page.clients.authorization.policy;
+
+import static org.openqa.selenium.By.tagName;
+
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.keycloak.testsuite.console.page.fragment.MultipleStringSelect2;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+public class PolicySelect extends MultipleStringSelect2 {
+
+ @Override
+ protected List<WebElement> getSelectedElements() {
+ return getRoot().findElements(By.xpath("(//table[@id='selected-policies'])/tbody/tr")).stream()
+ .filter(webElement -> webElement.findElements(tagName("td")).size() > 1)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ protected BiFunction<WebElement, String, Boolean> deselect() {
+ return (webElement, name) -> {
+ List<WebElement> tds = webElement.findElements(tagName("td"));
+
+ if (!tds.get(0).getText().isEmpty()) {
+ if (tds.get(0).getText().equals(name)) {
+ tds.get(3).click();
+ return true;
+ }
+ }
+
+ return false;
+ };
+ }
+
+ @Override
+ protected Function<WebElement, String> representation() {
+ return webElement -> webElement.findElements(tagName("td")).get(0).getText();
+ }
+}
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java
index 8ac8b3b..7c3597c 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourcePermissionManagementTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.util.UUID;
import java.util.stream.Collectors;
import org.junit.Before;
@@ -30,12 +31,14 @@ import org.keycloak.admin.client.resource.ResourcesResource;
import org.keycloak.admin.client.resource.RolePoliciesResource;
import org.keycloak.admin.client.resource.RolesResource;
import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
import org.keycloak.testsuite.console.page.clients.authorization.permission.ResourcePermission;
+import org.keycloak.testsuite.console.page.clients.authorization.policy.AggregatePolicy;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
@@ -207,8 +210,36 @@ public class ResourcePermissionManagementTest extends AbstractAuthorizationSetti
assertNull(authorizationPage.authorizationTabs().permissions().permissions().findByName(expected.getName()));
}
+ @Test
+ public void testCreateWithChild() {
+ ResourcePermissionRepresentation expected = new ResourcePermissionRepresentation();
+
+ expected.setName(UUID.randomUUID().toString());
+ expected.setDescription("description");
+ expected.addResource("Resource B");
+ expected.addPolicy("Policy C");
+
+ ResourcePermission policy = authorizationPage.authorizationTabs().permissions().create(expected, false);
+
+ RolePolicyRepresentation childPolicy = new RolePolicyRepresentation();
+
+ childPolicy.setName(UUID.randomUUID().toString());
+ childPolicy.addRole("Role A");
+
+ policy.createPolicy(childPolicy);
+ policy.form().save();
+
+ assertAlertSuccess();
+
+ expected.addPolicy(childPolicy.getName());
+
+ authorizationPage.navigateTo();
+ ResourcePermission actual = authorizationPage.authorizationTabs().permissions().name(expected.getName());
+ assertPolicy(expected, actual);
+ }
+
private ResourcePermissionRepresentation createPermission(ResourcePermissionRepresentation expected) {
- ResourcePermission policy = authorizationPage.authorizationTabs().permissions().create(expected);
+ ResourcePermission policy = authorizationPage.authorizationTabs().permissions().create(expected, true);
assertAlertSuccess();
return assertPolicy(expected, policy);
}
diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java
index 7599537..2e2804f 100644
--- a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java
+++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopePermissionManagementTest.java
@@ -20,6 +20,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.util.UUID;
+
import org.junit.Before;
import org.junit.Test;
import org.keycloak.admin.client.resource.AuthorizationResource;
@@ -29,11 +31,13 @@ import org.keycloak.admin.client.resource.RolePoliciesResource;
import org.keycloak.admin.client.resource.RolesResource;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.authorization.DecisionStrategy;
+import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation;
import org.keycloak.representations.idm.authorization.ScopeRepresentation;
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
+import org.keycloak.testsuite.console.page.clients.authorization.permission.ResourcePermission;
import org.keycloak.testsuite.console.page.clients.authorization.permission.ScopePermission;
/**
@@ -210,8 +214,70 @@ public class ScopePermissionManagementTest extends AbstractAuthorizationSettings
assertNull(authorizationPage.authorizationTabs().permissions().permissions().findByName(expected.getName()));
}
+ @Test
+ public void testCreateUpdateWithChild() {
+ ScopePermissionRepresentation expected = new ScopePermissionRepresentation();
+
+ expected.setName(UUID.randomUUID().toString());
+ expected.setDescription("description");
+ expected.addScope("Scope C");
+ expected.addPolicy("Policy C");
+
+ ScopePermission policy = authorizationPage.authorizationTabs().permissions().create(expected, false);
+
+ RolePolicyRepresentation childPolicy = new RolePolicyRepresentation();
+
+ childPolicy.setName(UUID.randomUUID().toString());
+ childPolicy.addRole("Role A");
+
+ policy.createPolicy(childPolicy);
+ policy.form().save();
+ assertAlertSuccess();
+
+ expected.addPolicy(childPolicy.getName());
+
+ authorizationPage.navigateTo();
+ ScopePermission actual = authorizationPage.authorizationTabs().permissions().name(expected.getName());
+ assertPolicy(expected, actual);
+
+ RolePolicyRepresentation childPolicy2 = new RolePolicyRepresentation();
+
+ childPolicy2.setName(UUID.randomUUID().toString());
+ childPolicy2.addRole("Role A");
+
+ policy.createPolicy(childPolicy2);
+ policy.form().save();
+ assertAlertSuccess();
+ expected.addPolicy(childPolicy2.getName());
+
+ authorizationPage.navigateTo();
+ actual = authorizationPage.authorizationTabs().permissions().name(expected.getName());
+ assertPolicy(expected, actual);
+
+ expected.addResource("Resource B");
+ expected.getScopes().clear();
+ expected.addScope("Scope B", "Scope C");
+ expected.getScopes().remove("Policy C");
+
+ RolePolicyRepresentation childPolicy3 = new RolePolicyRepresentation();
+
+ childPolicy3.setName(UUID.randomUUID().toString());
+ childPolicy3.addRole("Role A");
+
+ policy.update(expected, false);
+
+ policy.createPolicy(childPolicy3);
+ policy.form().save();
+ assertAlertSuccess();
+ expected.addPolicy(childPolicy3.getName());
+
+ authorizationPage.navigateTo();
+ actual = authorizationPage.authorizationTabs().permissions().name(expected.getName());
+ assertPolicy(expected, actual);
+ }
+
private ScopePermissionRepresentation createPermission(ScopePermissionRepresentation expected) {
- ScopePermission policy = authorizationPage.authorizationTabs().permissions().create(expected);
+ ScopePermission policy = authorizationPage.authorizationTabs().permissions().create(expected, true);
assertAlertSuccess();
return assertPolicy(expected, policy);
}
diff --git a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
index e6f7d5c..ab50fb7 100644
--- a/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
+++ b/themes/src/main/resources/theme/base/admin/resources/js/authz/authz-controller.js
@@ -1309,8 +1309,10 @@ module.controller('ResourceServerPolicyScopeDetailCtrl', function($scope, $route
var policies = [];
- for (i = 0; i < $scope.selectedPolicies.length; i++) {
- policies.push($scope.selectedPolicies[i].id);
+ if ($scope.selectedPolicies) {
+ for (i = 0; i < $scope.selectedPolicies.length; i++) {
+ policies.push($scope.selectedPolicies[i].id);
+ }
}
$scope.policy.policies = policies;
@@ -1355,8 +1357,10 @@ module.controller('ResourceServerPolicyScopeDetailCtrl', function($scope, $route
var policies = [];
- for (i = 0; i < $scope.selectedPolicies.length; i++) {
- policies.push($scope.selectedPolicies[i].id);
+ if ($scope.selectedPolicies) {
+ for (i = 0; i < $scope.selectedPolicies.length; i++) {
+ policies.push($scope.selectedPolicies[i].id);
+ }
}
$scope.policy.policies = policies;
@@ -2286,6 +2290,7 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
var policy = angular.copy(data);
$scope.changed = $scope.historyBackOnSaveOrCancel || PolicyController.isBackNewAssociatedPolicy();
+ $scope.policy = angular.copy(policy);
if (PolicyController.isBackNewAssociatedPolicy()) {
if (delegate.onRestoreState) {
@@ -2296,8 +2301,6 @@ module.service("PolicyController", function($http, $route, $location, ResourceSe
delegate.onInitUpdate(policy);
}
- $scope.policy = angular.copy(policy);
-
$scope.$watch('policy', function() {
if (!angular.equals($scope.policy, policy)) {
$scope.changed = true;
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html
index cbd06fd..4716d7f 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-resource-detail.html
@@ -55,36 +55,41 @@
<div class="form-group clearfix">
<label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
<div class="col-sm-6">
- <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." />
- <p/>
- <table class="table table-striped table-bordered" id="selected-policies">
+ <table class="table table-striped table-bordered" style="margin-top: 0px" id="selected-policies">
<thead>
<tr>
- <th class="kc-table-actions" colspan="3">
- <div class="form-inline">
- <div class="form-group">
- </div>
- <div class="pull-right">
- <select id="create-policy" class="form-control" ng-model="policyType"
- ng-options="p.name for p in policyProviders track by p.type"
- data-ng-change="addPolicy(policyType);">
- <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
- </select>
+ <th class="kc-table-actions" colspan="2">
+ <div class="form-inline col-md-12" style="width: 107%">
+ <div class="form-group" style="width: 100%">
+ <div class="input-group" style="width: 100%">
+ <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..."/>
+ </div>
</div>
</div>
</th>
+ <th class="kc-table-actions">
+ <div class="pull-right" style="width: 100%">
+ <select id="create-policy" class="form-control" ng-model="policyType"
+ ng-options="p.name for p in policyProviders track by p.type"
+ data-ng-change="addPolicy(policyType);"
+ data-ng-hide="historyBackOnSaveOrCancel">
+ <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
+ </select>
+ </div>
+ </th>
</tr>
<tr data-ng-hide="!selectedPolicies || selectedPolicies.length == 0">
<th>{{:: 'name' | translate}}</th>
<th>{{:: 'description' | translate}}</th>
- <th>{{:: 'actions' | translate}}</th>
+ <th width="20%">{{:: 'actions' | translate}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="policy in selectedPolicies">
- <td><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td>
+ <td data-ng-hide="historyBackOnSaveOrCancel"><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td>
+ <td data-ng-show="historyBackOnSaveOrCancel">{{policy.name}}</td>
<td>{{policy.description}}</td>
- <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);">
+ <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);" style="vertical-align: middle">
{{:: 'remove' | translate}}
</td>
</tr>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
index 4f469a2..a7c5f3d 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/permission/provider/resource-server-policy-scope-detail.html
@@ -59,36 +59,41 @@
<div class="form-group clearfix">
<label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
<div class="col-sm-6">
- <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." />
- <p/>
- <table class="table table-striped table-bordered" id="selected-policies">
+ <table class="table table-striped table-bordered" style="margin-top: 0px" id="selected-policies">
<thead>
<tr>
- <th class="kc-table-actions" colspan="3">
- <div class="form-inline">
- <div class="form-group">
- </div>
- <div class="pull-right">
- <select id="create-policy" class="form-control" ng-model="policyType"
- ng-options="p.name for p in policyProviders track by p.type"
- data-ng-change="addPolicy(policyType);">
- <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
- </select>
+ <th class="kc-table-actions" colspan="2">
+ <div class="form-inline col-md-12" style="width: 107%">
+ <div class="form-group" style="width: 100%">
+ <div class="input-group" style="width: 100%">
+ <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..."/>
+ </div>
</div>
</div>
</th>
+ <th class="kc-table-actions">
+ <div class="pull-right" style="width: 100%">
+ <select id="create-policy" class="form-control" ng-model="policyType"
+ ng-options="p.name for p in policyProviders track by p.type"
+ data-ng-change="addPolicy(policyType);"
+ data-ng-hide="historyBackOnSaveOrCancel">
+ <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
+ </select>
+ </div>
+ </th>
</tr>
<tr data-ng-hide="!selectedPolicies || selectedPolicies.length == 0">
<th>{{:: 'name' | translate}}</th>
<th>{{:: 'description' | translate}}</th>
- <th>{{:: 'actions' | translate}}</th>
+ <th width="20%">{{:: 'actions' | translate}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="policy in selectedPolicies">
- <td><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td>
+ <td data-ng-hide="historyBackOnSaveOrCancel"><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td>
+ <td data-ng-show="historyBackOnSaveOrCancel">{{policy.name}}</td>
<td>{{policy.description}}</td>
- <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);">
+ <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);" style="vertical-align: middle">
{{:: 'remove' | translate}}
</td>
</tr>
diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html
index acaa7a2..25be65b 100644
--- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html
+++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/policy/provider/resource-server-policy-aggregate-detail.html
@@ -35,30 +35,33 @@
<div class="form-group clearfix">
<label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
<div class="col-sm-6">
- <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." data-ng-required="!selectedPolicies || selectedPolicies.length == 0"/>
- <p/>
- <table class="table table-striped table-bordered" id="selected-policies">
+ <table class="table table-striped table-bordered" style="margin-top: 0px" id="selected-policies">
<thead>
<tr>
- <th class="kc-table-actions" colspan="3">
- <div class="form-inline">
- <div class="form-group">
- </div>
- <div class="pull-right">
- <select id="create-policy" class="form-control" ng-model="policyType"
- ng-options="p.name for p in policyProviders track by p.type"
- data-ng-change="addPolicy(policyType);"
- data-ng-hide="historyBackOnSaveOrCancel">
- <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
- </select>
+ <th class="kc-table-actions" colspan="2">
+ <div class="form-inline col-md-12" style="width: 107%">
+ <div class="form-group" style="width: 100%">
+ <div class="input-group" style="width: 100%">
+ <input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-change="selectPolicy(selectedPolicy);" data-ng-model="selectedPolicy" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." data-ng-required="!selectedPolicies || selectedPolicies.length == 0"/>
+ </div>
</div>
</div>
</th>
+ <th class="kc-table-actions">
+ <div class="pull-right" style="width: 100%">
+ <select id="create-policy" class="form-control" ng-model="policyType"
+ ng-options="p.name for p in policyProviders track by p.type"
+ data-ng-change="addPolicy(policyType);"
+ data-ng-hide="historyBackOnSaveOrCancel">
+ <option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
+ </select>
+ </div>
+ </th>
</tr>
<tr data-ng-hide="!selectedPolicies || selectedPolicies.length == 0">
<th>{{:: 'name' | translate}}</th>
<th>{{:: 'description' | translate}}</th>
- <th>{{:: 'actions' | translate}}</th>
+ <th width="20%">{{:: 'actions' | translate}}</th>
</tr>
</thead>
<tbody>
@@ -66,7 +69,7 @@
<td data-ng-hide="historyBackOnSaveOrCancel"><a href="" data-ng-click="detailPolicy(policy)">{{policy.name}}</a></td>
<td data-ng-show="historyBackOnSaveOrCancel">{{policy.name}}</td>
<td>{{policy.description}}</td>
- <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);">
+ <td class="kc-action-cell" ng-click="removePolicy(selectedPolicies, policy);" style="vertical-align: middle">
{{:: 'remove' | translate}}
</td>
</tr>