[KEYCLOAK-3135] - More UI tests
This commit is contained in:
parent
dfec691de0
commit
5972c94dc8
38 changed files with 2595 additions and 45 deletions
|
@ -29,12 +29,13 @@ import org.keycloak.authorization.policy.provider.PolicyProviderAdminService;
|
||||||
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
|
import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
*/
|
*/
|
||||||
public class AggregatePolicyProviderFactory implements PolicyProviderFactory<PolicyRepresentation> {
|
public class AggregatePolicyProviderFactory implements PolicyProviderFactory<AggregatePolicyRepresentation> {
|
||||||
|
|
||||||
private AggregatePolicyProvider provider = new AggregatePolicyProvider();
|
private AggregatePolicyProvider provider = new AggregatePolicyProvider();
|
||||||
|
|
||||||
|
@ -53,23 +54,18 @@ public class AggregatePolicyProviderFactory implements PolicyProviderFactory<Pol
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PolicyProviderAdminService getAdminResource(ResourceServer resourceServer, AuthorizationProvider authorization) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PolicyProvider create(KeycloakSession session) {
|
public PolicyProvider create(KeycloakSession session) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) {
|
public void onCreate(Policy policy, AggregatePolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
verifyCircularReference(policy, new ArrayList<>());
|
verifyCircularReference(policy, new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(Policy policy, PolicyRepresentation representation, AuthorizationProvider authorization) {
|
public void onUpdate(Policy policy, AggregatePolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
verifyCircularReference(policy, new ArrayList<>());
|
verifyCircularReference(policy, new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,10 @@ public class AbstractPolicyRepresentation {
|
||||||
return policies;
|
return policies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPolicies(Set<String> policies) {
|
||||||
|
this.policies = policies;
|
||||||
|
}
|
||||||
|
|
||||||
public void addPolicy(String... id) {
|
public void addPolicy(String... id) {
|
||||||
if (this.policies == null) {
|
if (this.policies == null) {
|
||||||
this.policies = new HashSet<>();
|
this.policies = new HashSet<>();
|
||||||
|
@ -99,6 +103,10 @@ public class AbstractPolicyRepresentation {
|
||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setResources(Set<String> resources) {
|
||||||
|
this.resources = resources;
|
||||||
|
}
|
||||||
|
|
||||||
public void addResource(String id) {
|
public void addResource(String id) {
|
||||||
if (this.resources == null) {
|
if (this.resources == null) {
|
||||||
this.resources = new HashSet<>();
|
this.resources = new HashSet<>();
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.representations.idm.authorization;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class AggregatePolicyRepresentation extends AbstractPolicyRepresentation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "aggregate";
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,11 @@ public class JSPolicyRepresentation extends AbstractPolicyRepresentation {
|
||||||
|
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "js";
|
||||||
|
}
|
||||||
|
|
||||||
public String getCode() {
|
public String getCode() {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,11 @@ public class RolePolicyRepresentation extends AbstractPolicyRepresentation {
|
||||||
|
|
||||||
private Set<RoleDefinition> roles;
|
private Set<RoleDefinition> roles;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "role";
|
||||||
|
}
|
||||||
|
|
||||||
public Set<RoleDefinition> getRoles() {
|
public Set<RoleDefinition> getRoles() {
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,11 @@ public class TimePolicyRepresentation extends AbstractPolicyRepresentation {
|
||||||
private String minute;
|
private String minute;
|
||||||
private String minuteEnd;
|
private String minuteEnd;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "time";
|
||||||
|
}
|
||||||
|
|
||||||
public String getNotBefore() {
|
public String getNotBefore() {
|
||||||
return notBefore;
|
return notBefore;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,11 @@ public class UserPolicyRepresentation extends AbstractPolicyRepresentation {
|
||||||
|
|
||||||
private Set<String> users;
|
private Set<String> users;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return "user";
|
||||||
|
}
|
||||||
|
|
||||||
public Set<String> getUsers() {
|
public Set<String> getUsers() {
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,18 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.console.page.clients.authorization.permission;
|
package org.keycloak.testsuite.console.page.clients.authorization.permission;
|
||||||
|
|
||||||
|
import static org.openqa.selenium.By.tagName;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
|
||||||
|
import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicyTypeUI;
|
||||||
import org.keycloak.testsuite.page.Form;
|
import org.keycloak.testsuite.page.Form;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
import org.openqa.selenium.support.FindBy;
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
import org.openqa.selenium.support.ui.Select;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
@ -27,7 +37,79 @@ public class Permissions extends Form {
|
||||||
@FindBy(css = "table[class*='table']")
|
@FindBy(css = "table[class*='table']")
|
||||||
private PermissionsTable table;
|
private PermissionsTable table;
|
||||||
|
|
||||||
|
@FindBy(id = "create-permission")
|
||||||
|
private Select createSelect;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private ResourcePermission resourcePermission;
|
||||||
|
|
||||||
public PermissionsTable permissions() {
|
public PermissionsTable permissions() {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <P extends PolicyTypeUI> P create(AbstractPolicyRepresentation expected) {
|
||||||
|
String type = expected.getType();
|
||||||
|
|
||||||
|
createSelect.selectByValue(type);
|
||||||
|
|
||||||
|
if ("resource".equals(type)) {
|
||||||
|
resourcePermission.form().populate((ResourcePermissionRepresentation) expected);
|
||||||
|
resourcePermission.form().save();
|
||||||
|
return (P) resourcePermission;
|
||||||
|
} else if ("scope".equals(type)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(String name, AbstractPolicyRepresentation representation) {
|
||||||
|
for (WebElement row : permissions().rows()) {
|
||||||
|
PolicyRepresentation actual = permissions().toRepresentation(row);
|
||||||
|
if (actual.getName().equalsIgnoreCase(name)) {
|
||||||
|
row.findElements(tagName("a")).get(0).click();
|
||||||
|
WaitUtils.waitForPageToLoad(driver);
|
||||||
|
String type = representation.getType();
|
||||||
|
|
||||||
|
if ("resource".equals(type)) {
|
||||||
|
resourcePermission.form().populate((ResourcePermissionRepresentation) representation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <P extends PolicyTypeUI> P name(String name) {
|
||||||
|
for (WebElement row : permissions().rows()) {
|
||||||
|
PolicyRepresentation actual = permissions().toRepresentation(row);
|
||||||
|
if (actual.getName().equalsIgnoreCase(name)) {
|
||||||
|
row.findElements(tagName("a")).get(0).click();
|
||||||
|
WaitUtils.waitForPageToLoad(driver);
|
||||||
|
String type = actual.getType();
|
||||||
|
if ("resource".equals(type)) {
|
||||||
|
return (P) resourcePermission;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(String name) {
|
||||||
|
for (WebElement row : permissions().rows()) {
|
||||||
|
PolicyRepresentation actual = permissions().toRepresentation(row);
|
||||||
|
if (actual.getName().equalsIgnoreCase(name)) {
|
||||||
|
row.findElements(tagName("a")).get(0).click();
|
||||||
|
WaitUtils.waitForPageToLoad(driver);
|
||||||
|
|
||||||
|
String type = actual.getType();
|
||||||
|
|
||||||
|
if ("resource".equals(type)) {
|
||||||
|
resourcePermission.form().delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.permission;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
|
||||||
|
import org.keycloak.testsuite.console.page.clients.authorization.policy.PolicyTypeUI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class ResourcePermission implements PolicyTypeUI {
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private ResourcePermissionForm form;
|
||||||
|
|
||||||
|
public ResourcePermissionForm form() {
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourcePermissionRepresentation toRepresentation() {
|
||||||
|
return form.toRepresentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(ResourcePermissionRepresentation expected) {
|
||||||
|
form().populate(expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,264 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.permission;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.fragment.Root;
|
||||||
|
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
||||||
|
import org.keycloak.representations.idm.authorization.ResourcePermissionRepresentation;
|
||||||
|
import org.keycloak.testsuite.console.page.fragment.OnOffSwitch;
|
||||||
|
import org.keycloak.testsuite.page.Form;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.JavascriptExecutor;
|
||||||
|
import org.openqa.selenium.Keys;
|
||||||
|
import org.openqa.selenium.WebDriver;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.interactions.Actions;
|
||||||
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
import org.openqa.selenium.support.ui.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class ResourcePermissionForm extends Form {
|
||||||
|
|
||||||
|
@FindBy(id = "name")
|
||||||
|
private WebElement name;
|
||||||
|
|
||||||
|
@FindBy(id = "description")
|
||||||
|
private WebElement description;
|
||||||
|
|
||||||
|
@FindBy(id = "decisionStrategy")
|
||||||
|
private Select decisionStrategy;
|
||||||
|
|
||||||
|
@FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='applyToResourceTypeFlag']]")
|
||||||
|
private OnOffSwitch resourceTypeSwitch;
|
||||||
|
|
||||||
|
@FindBy(id = "resourceType")
|
||||||
|
private WebElement resourceType;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
|
||||||
|
private WebElement deleteButton;
|
||||||
|
|
||||||
|
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
|
||||||
|
private WebElement confirmDelete;
|
||||||
|
|
||||||
|
@FindBy(id = "s2id_policies")
|
||||||
|
private PolicyInput policyInput;
|
||||||
|
|
||||||
|
@FindBy(id = "s2id_resources")
|
||||||
|
private ResourceInput resourceInput;
|
||||||
|
|
||||||
|
public void populate(ResourcePermissionRepresentation expected) {
|
||||||
|
setInputValue(name, expected.getName());
|
||||||
|
setInputValue(description, expected.getDescription());
|
||||||
|
decisionStrategy.selectByValue(expected.getDecisionStrategy().name());
|
||||||
|
|
||||||
|
resourceTypeSwitch.setOn(expected.getResourceType() != null);
|
||||||
|
|
||||||
|
if (expected.getResourceType() != null) {
|
||||||
|
setInputValue(resourceType, expected.getResourceType());
|
||||||
|
} else {
|
||||||
|
resourceTypeSwitch.setOn(false);
|
||||||
|
Set<String> selectedResources = resourceInput.getSelected();
|
||||||
|
Set<String> resources = expected.getResources();
|
||||||
|
|
||||||
|
for (String resource : resources) {
|
||||||
|
if (!selectedResources.contains(resource)) {
|
||||||
|
resourceInput.select(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String selected : selectedResources) {
|
||||||
|
boolean isSelected = false;
|
||||||
|
|
||||||
|
for (String resource : resources) {
|
||||||
|
if (selected.equals(resource)) {
|
||||||
|
isSelected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSelected) {
|
||||||
|
resourceInput.unSelect(selected, driver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> selectedPolicies = policyInput.getSelected();
|
||||||
|
Set<String> policies = expected.getPolicies();
|
||||||
|
|
||||||
|
for (String policy : policies) {
|
||||||
|
if (!selectedPolicies.contains(policy)) {
|
||||||
|
policyInput.select(policy, driver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String selected : selectedPolicies) {
|
||||||
|
boolean isSelected = false;
|
||||||
|
|
||||||
|
for (String policy : policies) {
|
||||||
|
if (selected.equals(policy)) {
|
||||||
|
isSelected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSelected) {
|
||||||
|
policyInput.unSelect(selected, driver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
deleteButton.click();
|
||||||
|
confirmDelete.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourcePermissionRepresentation toRepresentation() {
|
||||||
|
ResourcePermissionRepresentation representation = new ResourcePermissionRepresentation();
|
||||||
|
|
||||||
|
representation.setName(getInputValue(name));
|
||||||
|
representation.setDescription(getInputValue(description));
|
||||||
|
representation.setDecisionStrategy(DecisionStrategy.valueOf(decisionStrategy.getFirstSelectedOption().getText().toUpperCase()));
|
||||||
|
representation.setPolicies(policyInput.getSelected());
|
||||||
|
representation.setResources(resourceInput.getSelected());
|
||||||
|
|
||||||
|
return representation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PolicyInput {
|
||||||
|
|
||||||
|
@Root
|
||||||
|
private WebElement root;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//input[contains(@class,'select2-input')]")
|
||||||
|
private WebElement search;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
|
||||||
|
private List<WebElement> result;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
|
||||||
|
private List<WebElement> selection;
|
||||||
|
|
||||||
|
public void select(String name, WebDriver driver) {
|
||||||
|
root.click();
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
|
||||||
|
Actions actions = new Actions(driver);
|
||||||
|
|
||||||
|
actions.sendKeys(name).perform();
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
|
||||||
|
if (result.isEmpty()) {
|
||||||
|
actions.sendKeys(Keys.ESCAPE).perform();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (WebElement result : result) {
|
||||||
|
if (result.getText().equalsIgnoreCase(name)) {
|
||||||
|
result.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getSelected() {
|
||||||
|
HashSet<String> values = new HashSet<>();
|
||||||
|
|
||||||
|
for (WebElement selected : selection) {
|
||||||
|
values.add(selected.findElements(By.tagName("div")).get(0).getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unSelect(String name, WebDriver driver) {
|
||||||
|
for (WebElement selected : selection) {
|
||||||
|
WebElement selection = selected.findElements(By.tagName("div")).get(0);
|
||||||
|
if (name.equals(selection.getText())) {
|
||||||
|
WebElement element = selection.findElement(By.xpath("//a[contains(@class,'select2-search-choice-close')]"));
|
||||||
|
JavascriptExecutor executor = (JavascriptExecutor) driver;
|
||||||
|
executor.executeScript("arguments[0].click();", element);
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ResourceInput {
|
||||||
|
|
||||||
|
@Root
|
||||||
|
private WebElement root;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//input[contains(@class,'select2-input')]")
|
||||||
|
private WebElement search;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
|
||||||
|
private List<WebElement> result;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
|
||||||
|
private List<WebElement> selection;
|
||||||
|
|
||||||
|
public void select(String name) {
|
||||||
|
root.click();
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
setInputValue(search, name);
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
if (result.isEmpty()) {
|
||||||
|
search.sendKeys(Keys.ESCAPE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (WebElement result : result) {
|
||||||
|
if (result.getText().equalsIgnoreCase(name)) {
|
||||||
|
result.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getSelected() {
|
||||||
|
HashSet<String> values = new HashSet<>();
|
||||||
|
|
||||||
|
for (WebElement selected : selection) {
|
||||||
|
values.add(selected.findElements(By.tagName("div")).get(0).getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unSelect(String name, WebDriver driver) {
|
||||||
|
for (WebElement selected : selection) {
|
||||||
|
if (name.equals(selected.findElements(By.tagName("div")).get(0).getText())) {
|
||||||
|
WebElement element = selected.findElement(By.xpath("//a[contains(@class,'select2-search-choice-close')]"));
|
||||||
|
JavascriptExecutor executor = (JavascriptExecutor) driver;
|
||||||
|
executor.executeScript("arguments[0].click();", element);
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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 org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class AggregatePolicy implements PolicyTypeUI {
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private AggregatePolicyForm form;
|
||||||
|
|
||||||
|
public AggregatePolicyForm form() {
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AggregatePolicyRepresentation toRepresentation() {
|
||||||
|
return form.toRepresentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(AggregatePolicyRepresentation expected) {
|
||||||
|
form().populate(expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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 java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.fragment.Root;
|
||||||
|
import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
import org.keycloak.testsuite.page.Form;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.JavascriptExecutor;
|
||||||
|
import org.openqa.selenium.Keys;
|
||||||
|
import org.openqa.selenium.WebDriver;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.interactions.Actions;
|
||||||
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
import org.openqa.selenium.support.ui.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class AggregatePolicyForm extends Form {
|
||||||
|
|
||||||
|
@FindBy(id = "name")
|
||||||
|
private WebElement name;
|
||||||
|
|
||||||
|
@FindBy(id = "description")
|
||||||
|
private WebElement description;
|
||||||
|
|
||||||
|
@FindBy(id = "logic")
|
||||||
|
private Select logic;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
|
||||||
|
private WebElement deleteButton;
|
||||||
|
|
||||||
|
@FindBy(id = "s2id_policies")
|
||||||
|
private PolicyInput policyInput;
|
||||||
|
|
||||||
|
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
|
||||||
|
private WebElement confirmDelete;
|
||||||
|
|
||||||
|
public void populate(AggregatePolicyRepresentation expected) {
|
||||||
|
setInputValue(name, expected.getName());
|
||||||
|
setInputValue(description, expected.getDescription());
|
||||||
|
logic.selectByValue(expected.getLogic().name());
|
||||||
|
|
||||||
|
Set<String> selectedPolicies = policyInput.getSelected();
|
||||||
|
Set<String> policies = expected.getPolicies();
|
||||||
|
|
||||||
|
for (String policy : policies) {
|
||||||
|
if (!selectedPolicies.contains(policy)) {
|
||||||
|
policyInput.select(policy, driver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String selected : selectedPolicies) {
|
||||||
|
boolean isSelected = false;
|
||||||
|
|
||||||
|
for (String policy : policies) {
|
||||||
|
if (selected.equals(policy)) {
|
||||||
|
isSelected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSelected) {
|
||||||
|
policyInput.unSelect(selected, driver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
deleteButton.click();
|
||||||
|
confirmDelete.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AggregatePolicyRepresentation toRepresentation() {
|
||||||
|
AggregatePolicyRepresentation representation = new AggregatePolicyRepresentation();
|
||||||
|
|
||||||
|
representation.setName(getInputValue(name));
|
||||||
|
representation.setDescription(getInputValue(description));
|
||||||
|
representation.setLogic(Logic.valueOf(logic.getFirstSelectedOption().getText().toUpperCase()));
|
||||||
|
representation.setPolicies(policyInput.getSelected());
|
||||||
|
|
||||||
|
return representation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PolicyInput {
|
||||||
|
|
||||||
|
@Root
|
||||||
|
private WebElement root;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//input[contains(@class,'select2-input')]")
|
||||||
|
private WebElement search;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
|
||||||
|
private List<WebElement> result;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
|
||||||
|
private List<WebElement> selection;
|
||||||
|
|
||||||
|
public void select(String name, WebDriver driver) {
|
||||||
|
root.click();
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
|
||||||
|
Actions actions = new Actions(driver);
|
||||||
|
|
||||||
|
actions.sendKeys(name).perform();
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
|
||||||
|
if (result.isEmpty()) {
|
||||||
|
actions.sendKeys(Keys.ESCAPE).perform();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (WebElement result : result) {
|
||||||
|
if (result.getText().equalsIgnoreCase(name)) {
|
||||||
|
result.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getSelected() {
|
||||||
|
HashSet<String> values = new HashSet<>();
|
||||||
|
|
||||||
|
for (WebElement selected : selection) {
|
||||||
|
values.add(selected.findElements(By.tagName("div")).get(0).getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unSelect(String name, WebDriver driver) {
|
||||||
|
for (WebElement selected : selection) {
|
||||||
|
if (name.equals(selected.findElements(By.tagName("div")).get(0).getText())) {
|
||||||
|
WebElement element = selected.findElement(By.xpath("//a[contains(@class,'select2-search-choice-close')]"));
|
||||||
|
JavascriptExecutor executor = (JavascriptExecutor) driver;
|
||||||
|
executor.executeScript("arguments[0].click();", element);
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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 org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class JSPolicy implements PolicyTypeUI {
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private JSPolicyForm form;
|
||||||
|
|
||||||
|
public JSPolicyForm form() {
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSPolicyRepresentation toRepresentation() {
|
||||||
|
return form.toRepresentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(JSPolicyRepresentation expected) {
|
||||||
|
form().populate(expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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 org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
import org.keycloak.testsuite.page.Form;
|
||||||
|
import org.openqa.selenium.JavascriptExecutor;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
import org.openqa.selenium.support.ui.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class JSPolicyForm extends Form {
|
||||||
|
|
||||||
|
@FindBy(id = "name")
|
||||||
|
private WebElement name;
|
||||||
|
|
||||||
|
@FindBy(id = "description")
|
||||||
|
private WebElement description;
|
||||||
|
|
||||||
|
@FindBy(id = "logic")
|
||||||
|
private Select logic;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
|
||||||
|
private WebElement deleteButton;
|
||||||
|
|
||||||
|
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
|
||||||
|
private WebElement confirmDelete;
|
||||||
|
|
||||||
|
public void populate(JSPolicyRepresentation expected) {
|
||||||
|
setInputValue(name, expected.getName());
|
||||||
|
setInputValue(description, expected.getDescription());
|
||||||
|
logic.selectByValue(expected.getLogic().name());
|
||||||
|
|
||||||
|
JavascriptExecutor scriptExecutor = (JavascriptExecutor) driver;
|
||||||
|
|
||||||
|
scriptExecutor.executeScript("angular.element(document.getElementById('code')).scope().policy.code = '" + expected.getCode() + "'");
|
||||||
|
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
deleteButton.click();
|
||||||
|
confirmDelete.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSPolicyRepresentation toRepresentation() {
|
||||||
|
JSPolicyRepresentation representation = new JSPolicyRepresentation();
|
||||||
|
|
||||||
|
representation.setName(getInputValue(name));
|
||||||
|
representation.setDescription(getInputValue(description));
|
||||||
|
representation.setLogic(Logic.valueOf(logic.getFirstSelectedOption().getText().toUpperCase()));
|
||||||
|
|
||||||
|
JavascriptExecutor scriptExecutor = (JavascriptExecutor) driver;
|
||||||
|
|
||||||
|
representation.setCode((String) scriptExecutor.executeScript("return angular.element(document.getElementById('code')).scope().policy.code;"));
|
||||||
|
|
||||||
|
return representation;
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,9 +16,21 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.console.page.clients.authorization.policy;
|
package org.keycloak.testsuite.console.page.clients.authorization.policy;
|
||||||
|
|
||||||
import org.keycloak.testsuite.console.page.clients.authorization.permission.PermissionsTable;
|
import static org.openqa.selenium.By.tagName;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.AggregatePolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
|
||||||
import org.keycloak.testsuite.page.Form;
|
import org.keycloak.testsuite.page.Form;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
import org.openqa.selenium.support.FindBy;
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
import org.openqa.selenium.support.ui.Select;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
@ -26,9 +38,131 @@ import org.openqa.selenium.support.FindBy;
|
||||||
public class Policies extends Form {
|
public class Policies extends Form {
|
||||||
|
|
||||||
@FindBy(css = "table[class*='table']")
|
@FindBy(css = "table[class*='table']")
|
||||||
private PermissionsTable table;
|
private PoliciesTable table;
|
||||||
|
|
||||||
public PermissionsTable policies() {
|
@FindBy(id = "create-policy")
|
||||||
|
private Select createSelect;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private RolePolicy rolePolicy;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private UserPolicy userPolicy;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private AggregatePolicy aggregatePolicy;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private JSPolicy jsPolicy;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private TimePolicy timePolicy;
|
||||||
|
|
||||||
|
public PoliciesTable policies() {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <P extends PolicyTypeUI> P create(AbstractPolicyRepresentation expected) {
|
||||||
|
String type = expected.getType();
|
||||||
|
|
||||||
|
createSelect.selectByValue(type);
|
||||||
|
|
||||||
|
if ("role".equals(type)) {
|
||||||
|
rolePolicy.form().populate((RolePolicyRepresentation) expected);
|
||||||
|
rolePolicy.form().save();
|
||||||
|
return (P) rolePolicy;
|
||||||
|
} else if ("user".equals(type)) {
|
||||||
|
userPolicy.form().populate((UserPolicyRepresentation) expected);
|
||||||
|
userPolicy.form().save();
|
||||||
|
return (P) userPolicy;
|
||||||
|
} else if ("aggregate".equals(type)) {
|
||||||
|
aggregatePolicy.form().populate((AggregatePolicyRepresentation) expected);
|
||||||
|
aggregatePolicy.form().save();
|
||||||
|
return (P) aggregatePolicy;
|
||||||
|
} else if ("js".equals(type)) {
|
||||||
|
jsPolicy.form().populate((JSPolicyRepresentation) expected);
|
||||||
|
jsPolicy.form().save();
|
||||||
|
return (P) jsPolicy;
|
||||||
|
} else if ("time".equals(type)) {
|
||||||
|
timePolicy.form().populate((TimePolicyRepresentation) expected);
|
||||||
|
timePolicy.form().save();
|
||||||
|
return (P) timePolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(String name, AbstractPolicyRepresentation representation) {
|
||||||
|
for (WebElement row : policies().rows()) {
|
||||||
|
PolicyRepresentation actual = policies().toRepresentation(row);
|
||||||
|
if (actual.getName().equalsIgnoreCase(name)) {
|
||||||
|
row.findElements(tagName("a")).get(0).click();
|
||||||
|
WaitUtils.waitForPageToLoad(driver);
|
||||||
|
String type = representation.getType();
|
||||||
|
|
||||||
|
if ("role".equals(type)) {
|
||||||
|
rolePolicy.form().populate((RolePolicyRepresentation) representation);
|
||||||
|
} else if ("user".equals(type)) {
|
||||||
|
userPolicy.form().populate((UserPolicyRepresentation) representation);
|
||||||
|
} else if ("aggregate".equals(type)) {
|
||||||
|
aggregatePolicy.form().populate((AggregatePolicyRepresentation) representation);
|
||||||
|
} else if ("js".equals(type)) {
|
||||||
|
jsPolicy.form().populate((JSPolicyRepresentation) representation);
|
||||||
|
} else if ("time".equals(type)) {
|
||||||
|
timePolicy.form().populate((TimePolicyRepresentation) representation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <P extends PolicyTypeUI> P name(String name) {
|
||||||
|
for (WebElement row : policies().rows()) {
|
||||||
|
PolicyRepresentation actual = policies().toRepresentation(row);
|
||||||
|
if (actual.getName().equalsIgnoreCase(name)) {
|
||||||
|
row.findElements(tagName("a")).get(0).click();
|
||||||
|
WaitUtils.waitForPageToLoad(driver);
|
||||||
|
String type = actual.getType();
|
||||||
|
if ("role".equals(type)) {
|
||||||
|
return (P) rolePolicy;
|
||||||
|
} else if ("user".equals(type)) {
|
||||||
|
return (P) userPolicy;
|
||||||
|
} else if ("aggregate".equals(type)) {
|
||||||
|
return (P) aggregatePolicy;
|
||||||
|
} else if ("js".equals(type)) {
|
||||||
|
return (P) jsPolicy;
|
||||||
|
} else if ("time".equals(type)) {
|
||||||
|
return (P) timePolicy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(String name) {
|
||||||
|
for (WebElement row : policies().rows()) {
|
||||||
|
PolicyRepresentation actual = policies().toRepresentation(row);
|
||||||
|
if (actual.getName().equalsIgnoreCase(name)) {
|
||||||
|
row.findElements(tagName("a")).get(0).click();
|
||||||
|
WaitUtils.waitForPageToLoad(driver);
|
||||||
|
|
||||||
|
String type = actual.getType();
|
||||||
|
|
||||||
|
if ("role".equals(type)) {
|
||||||
|
rolePolicy.form().delete();
|
||||||
|
} else if ("user".equals(type)) {
|
||||||
|
userPolicy.form().delete();
|
||||||
|
} else if ("aggregate".equals(type)) {
|
||||||
|
aggregatePolicy.form().delete();
|
||||||
|
} else if ("js".equals(type)) {
|
||||||
|
jsPolicy.form().delete();
|
||||||
|
} else if ("time".equals(type)) {
|
||||||
|
timePolicy.form().delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public interface PolicyTypeUI {
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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 org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class RolePolicy implements PolicyTypeUI {
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private RolePolicyForm form;
|
||||||
|
|
||||||
|
public RolePolicyForm form() {
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RolePolicyRepresentation toRepresentation() {
|
||||||
|
return form.toRepresentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(RolePolicyRepresentation expected) {
|
||||||
|
form().populate(expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,284 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.fragment.Root;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
|
||||||
|
import org.keycloak.testsuite.page.Form;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.Keys;
|
||||||
|
import org.openqa.selenium.WebDriver;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.interactions.Actions;
|
||||||
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
import org.openqa.selenium.support.ui.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class RolePolicyForm extends Form {
|
||||||
|
|
||||||
|
@FindBy(id = "name")
|
||||||
|
private WebElement name;
|
||||||
|
|
||||||
|
@FindBy(id = "description")
|
||||||
|
private WebElement description;
|
||||||
|
|
||||||
|
@FindBy(id = "logic")
|
||||||
|
private Select logic;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
|
||||||
|
private WebElement deleteButton;
|
||||||
|
|
||||||
|
@FindBy(id = "s2id_roles")
|
||||||
|
private RolesInput realmRolesInput;
|
||||||
|
|
||||||
|
@FindBy(id = "clients")
|
||||||
|
private Select clientsSelect;
|
||||||
|
|
||||||
|
@FindBy(id = "s2id_clientRoles")
|
||||||
|
private ClientRolesInput clientRolesInput;
|
||||||
|
|
||||||
|
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
|
||||||
|
private WebElement confirmDelete;
|
||||||
|
|
||||||
|
public void populate(RolePolicyRepresentation expected) {
|
||||||
|
setInputValue(name, expected.getName());
|
||||||
|
setInputValue(description, expected.getDescription());
|
||||||
|
logic.selectByValue(expected.getLogic().name());
|
||||||
|
|
||||||
|
Set<RolePolicyRepresentation.RoleDefinition> roles = expected.getRoles();
|
||||||
|
|
||||||
|
for (RolePolicyRepresentation.RoleDefinition role : roles) {
|
||||||
|
boolean clientRole = role.getId().indexOf('/') != -1;
|
||||||
|
|
||||||
|
if (clientRole) {
|
||||||
|
String[] parts = role.getId().split("/");
|
||||||
|
clientsSelect.selectByVisibleText(parts[0]);
|
||||||
|
clientRolesInput.select(parts[1], driver);
|
||||||
|
clientRolesInput.setRequired(parts[1], role);
|
||||||
|
} else {
|
||||||
|
realmRolesInput.select(role.getId(), driver);
|
||||||
|
realmRolesInput.setRequired(role.getId(), role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unSelect(roles, realmRolesInput.getSelected());
|
||||||
|
unSelect(roles, clientRolesInput.getSelected());
|
||||||
|
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unSelect(Set<RolePolicyRepresentation.RoleDefinition> roles, Set<RolePolicyRepresentation.RoleDefinition> selection) {
|
||||||
|
for (RolePolicyRepresentation.RoleDefinition selected : selection) {
|
||||||
|
boolean isSelected = false;
|
||||||
|
|
||||||
|
for (RolePolicyRepresentation.RoleDefinition scope : roles) {
|
||||||
|
if (selected.getId().equals(scope.getId())) {
|
||||||
|
isSelected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSelected) {
|
||||||
|
boolean clientRole = selected.getId().indexOf('/') != -1;
|
||||||
|
|
||||||
|
if (clientRole) {
|
||||||
|
clientRolesInput.unSelect(selected.getId().split("/")[1], driver);
|
||||||
|
} else {
|
||||||
|
realmRolesInput.unSelect(selected.getId(), driver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
deleteButton.click();
|
||||||
|
confirmDelete.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
public RolePolicyRepresentation toRepresentation() {
|
||||||
|
RolePolicyRepresentation representation = new RolePolicyRepresentation();
|
||||||
|
|
||||||
|
representation.setName(getInputValue(name));
|
||||||
|
representation.setDescription(getInputValue(description));
|
||||||
|
representation.setLogic(Logic.valueOf(logic.getFirstSelectedOption().getText().toUpperCase()));
|
||||||
|
|
||||||
|
Set<RolePolicyRepresentation.RoleDefinition> roles = realmRolesInput.getSelected();
|
||||||
|
|
||||||
|
roles.addAll(clientRolesInput.getSelected());
|
||||||
|
|
||||||
|
representation.setRoles(roles);
|
||||||
|
|
||||||
|
return representation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RolesInput extends AbstractRolesInput {
|
||||||
|
@Override
|
||||||
|
protected RolePolicyRepresentation.RoleDefinition getSelectedRoles(List<WebElement> tds) {
|
||||||
|
RolePolicyRepresentation.RoleDefinition selectedRole = new RolePolicyRepresentation.RoleDefinition();
|
||||||
|
selectedRole.setId(tds.get(0).getText());
|
||||||
|
selectedRole.setRequired(tds.get(1).findElement(By.tagName("input")).isSelected());
|
||||||
|
return selectedRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WebElement getRemoveButton(List<WebElement> tds) {
|
||||||
|
return tds.get(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<WebElement> getSelectedElements() {
|
||||||
|
return root.findElements(By.xpath("(//table[@id='selected-realm-roles'])/tbody/tr"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WebElement getRequiredColumn(List<WebElement> tds) {
|
||||||
|
return tds.get(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClientRolesInput extends AbstractRolesInput {
|
||||||
|
@Override
|
||||||
|
protected WebElement getRemoveButton(List<WebElement> tds) {
|
||||||
|
return tds.get(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RolePolicyRepresentation.RoleDefinition getSelectedRoles(List<WebElement> tds) {
|
||||||
|
RolePolicyRepresentation.RoleDefinition selectedRole = new RolePolicyRepresentation.RoleDefinition();
|
||||||
|
selectedRole.setId(tds.get(1).getText() + "/" + tds.get(0).getText());
|
||||||
|
selectedRole.setRequired(tds.get(2).findElement(By.tagName("input")).isSelected());
|
||||||
|
return selectedRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<WebElement> getSelectedElements() {
|
||||||
|
return root.findElements(By.xpath("(//table[@id='selected-client-roles'])/tbody/tr"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WebElement getRequiredColumn(List<WebElement> tds) {
|
||||||
|
return tds.get(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class AbstractRolesInput {
|
||||||
|
|
||||||
|
@Root
|
||||||
|
protected WebElement root;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
|
||||||
|
private List<WebElement> result;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
|
||||||
|
private List<WebElement> selection;
|
||||||
|
|
||||||
|
public void select(String roleId, WebDriver driver) {
|
||||||
|
root.click();
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
|
||||||
|
Actions actions = new Actions(driver);
|
||||||
|
|
||||||
|
actions.sendKeys(roleId).perform();
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
|
||||||
|
if (result.isEmpty()) {
|
||||||
|
actions.sendKeys(Keys.ESCAPE).perform();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WebElement result : result) {
|
||||||
|
if (result.getText().equalsIgnoreCase(roleId)) {
|
||||||
|
result.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<RolePolicyRepresentation.RoleDefinition> getSelected() {
|
||||||
|
List<WebElement> realmRoles = getSelectedElements();
|
||||||
|
Set<RolePolicyRepresentation.RoleDefinition> values = new HashSet<>();
|
||||||
|
|
||||||
|
for (WebElement realmRole : realmRoles) {
|
||||||
|
List<WebElement> tds = realmRole.findElements(tagName("td"));
|
||||||
|
if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
|
||||||
|
values.add(getSelectedRoles(tds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract RolePolicyRepresentation.RoleDefinition getSelectedRoles(List<WebElement> tds);
|
||||||
|
|
||||||
|
protected abstract List<WebElement> getSelectedElements();
|
||||||
|
|
||||||
|
public void unSelect(String name, WebDriver driver) {
|
||||||
|
Iterator<WebElement> iterator = getSelectedElements().iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
WebElement realmRole = iterator.next();
|
||||||
|
List<WebElement> tds = realmRole.findElements(tagName("td"));
|
||||||
|
|
||||||
|
if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
|
||||||
|
if (tds.get(0).getText().equals(name)) {
|
||||||
|
getRemoveButton(tds).findElement(By.tagName("button")).click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract WebElement getRemoveButton(List<WebElement> tds);
|
||||||
|
|
||||||
|
public void setRequired(String name, RolePolicyRepresentation.RoleDefinition role) {
|
||||||
|
Iterator<WebElement> iterator = getSelectedElements().iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
WebElement realmRole = iterator.next();
|
||||||
|
List<WebElement> tds = realmRole.findElements(tagName("td"));
|
||||||
|
|
||||||
|
if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
|
||||||
|
if (tds.get(0).getText().equals(name)) {
|
||||||
|
WebElement required = getRequiredColumn(tds).findElement(By.tagName("input"));
|
||||||
|
|
||||||
|
if (required.isSelected() && role.isRequired()) {
|
||||||
|
return;
|
||||||
|
} else if (!required.isSelected() && !role.isRequired()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
required.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract WebElement getRequiredColumn(List<WebElement> tds);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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 org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class TimePolicy implements PolicyTypeUI {
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private TimePolicyForm form;
|
||||||
|
|
||||||
|
public TimePolicyForm form() {
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimePolicyRepresentation toRepresentation() {
|
||||||
|
return form.toRepresentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(TimePolicyRepresentation expected) {
|
||||||
|
form().populate(expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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 org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
import org.keycloak.testsuite.page.Form;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
import org.openqa.selenium.support.ui.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class TimePolicyForm extends Form {
|
||||||
|
|
||||||
|
@FindBy(id = "name")
|
||||||
|
private WebElement name;
|
||||||
|
|
||||||
|
@FindBy(id = "description")
|
||||||
|
private WebElement description;
|
||||||
|
|
||||||
|
@FindBy(id = "logic")
|
||||||
|
private Select logic;
|
||||||
|
|
||||||
|
@FindBy(id = "notBefore")
|
||||||
|
private WebElement notBefore;
|
||||||
|
|
||||||
|
@FindBy(id = "notOnOrAfter")
|
||||||
|
private WebElement notOnOrAfter;
|
||||||
|
|
||||||
|
@FindBy(id = "dayMonth")
|
||||||
|
private WebElement dayMonth;
|
||||||
|
|
||||||
|
@FindBy(id = "month")
|
||||||
|
private WebElement month;
|
||||||
|
|
||||||
|
@FindBy(id = "year")
|
||||||
|
private WebElement year;
|
||||||
|
|
||||||
|
@FindBy(id = "hour")
|
||||||
|
private WebElement hour;
|
||||||
|
|
||||||
|
@FindBy(id = "minute")
|
||||||
|
private WebElement minute;
|
||||||
|
|
||||||
|
@FindBy(id = "dayMonthEnd")
|
||||||
|
private WebElement dayMonthEnd;
|
||||||
|
|
||||||
|
@FindBy(id = "monthEnd")
|
||||||
|
private WebElement monthEnd;
|
||||||
|
|
||||||
|
@FindBy(id = "yearEnd")
|
||||||
|
private WebElement yearEnd;
|
||||||
|
|
||||||
|
@FindBy(id = "hourEnd")
|
||||||
|
private WebElement hourEnd;
|
||||||
|
|
||||||
|
@FindBy(id = "minuteEnd")
|
||||||
|
private WebElement minuteEnd;
|
||||||
|
|
||||||
|
|
||||||
|
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
|
||||||
|
private WebElement deleteButton;
|
||||||
|
|
||||||
|
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
|
||||||
|
private WebElement confirmDelete;
|
||||||
|
|
||||||
|
public void populate(TimePolicyRepresentation expected) {
|
||||||
|
setInputValue(name, expected.getName());
|
||||||
|
setInputValue(description, expected.getDescription());
|
||||||
|
logic.selectByValue(expected.getLogic().name());
|
||||||
|
setInputValue(notBefore, expected.getNotBefore());
|
||||||
|
setInputValue(notOnOrAfter, expected.getNotOnOrAfter());
|
||||||
|
setInputValue(dayMonth, expected.getDayMonth());
|
||||||
|
setInputValue(dayMonthEnd, expected.getDayMonthEnd());
|
||||||
|
setInputValue(month, expected.getMonth());
|
||||||
|
setInputValue(monthEnd, expected.getMonthEnd());
|
||||||
|
setInputValue(year, expected.getYear());
|
||||||
|
setInputValue(yearEnd, expected.getYearEnd());
|
||||||
|
setInputValue(hour, expected.getHour());
|
||||||
|
setInputValue(hourEnd, expected.getHourEnd());
|
||||||
|
setInputValue(minute, expected.getMinute());
|
||||||
|
setInputValue(minuteEnd, expected.getMinuteEnd());
|
||||||
|
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
deleteButton.click();
|
||||||
|
confirmDelete.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimePolicyRepresentation toRepresentation() {
|
||||||
|
TimePolicyRepresentation representation = new TimePolicyRepresentation();
|
||||||
|
|
||||||
|
representation.setName(getInputValue(name));
|
||||||
|
representation.setDescription(getInputValue(description));
|
||||||
|
representation.setLogic(Logic.valueOf(logic.getFirstSelectedOption().getText().toUpperCase()));
|
||||||
|
representation.setDayMonth(getInputValue(dayMonth));
|
||||||
|
representation.setDayMonthEnd(getInputValue(dayMonthEnd));
|
||||||
|
representation.setMonth(getInputValue(month));
|
||||||
|
representation.setMonthEnd(getInputValue(monthEnd));
|
||||||
|
representation.setYear(getInputValue(year));
|
||||||
|
representation.setYearEnd(getInputValue(yearEnd));
|
||||||
|
representation.setHour(getInputValue(hour));
|
||||||
|
representation.setHourEnd(getInputValue(hourEnd));
|
||||||
|
representation.setMinute(getInputValue(minute));
|
||||||
|
representation.setMinuteEnd(getInputValue(minuteEnd));
|
||||||
|
representation.setNotBefore(getInputValue(notBefore));
|
||||||
|
representation.setNotOnOrAfter(getInputValue(notOnOrAfter));
|
||||||
|
|
||||||
|
return representation;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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 org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class UserPolicy implements PolicyTypeUI {
|
||||||
|
|
||||||
|
@Page
|
||||||
|
private UserPolicyForm form;
|
||||||
|
|
||||||
|
public UserPolicyForm form() {
|
||||||
|
return form;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserPolicyRepresentation toRepresentation() {
|
||||||
|
return form.toRepresentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(UserPolicyRepresentation expected) {
|
||||||
|
form().populate(expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.fragment.Root;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
|
||||||
|
import org.keycloak.testsuite.page.Form;
|
||||||
|
import org.keycloak.testsuite.util.WaitUtils;
|
||||||
|
import org.openqa.selenium.By;
|
||||||
|
import org.openqa.selenium.Keys;
|
||||||
|
import org.openqa.selenium.WebDriver;
|
||||||
|
import org.openqa.selenium.WebElement;
|
||||||
|
import org.openqa.selenium.interactions.Actions;
|
||||||
|
import org.openqa.selenium.support.FindBy;
|
||||||
|
import org.openqa.selenium.support.ui.Select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class UserPolicyForm extends Form {
|
||||||
|
|
||||||
|
@FindBy(id = "name")
|
||||||
|
private WebElement name;
|
||||||
|
|
||||||
|
@FindBy(id = "description")
|
||||||
|
private WebElement description;
|
||||||
|
|
||||||
|
@FindBy(id = "logic")
|
||||||
|
private Select logic;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//i[contains(@class,'pficon-delete')]")
|
||||||
|
private WebElement deleteButton;
|
||||||
|
|
||||||
|
@FindBy(id = "s2id_users")
|
||||||
|
private UsersInput usersInput;
|
||||||
|
|
||||||
|
@FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']")
|
||||||
|
private WebElement confirmDelete;
|
||||||
|
|
||||||
|
public void populate(UserPolicyRepresentation expected) {
|
||||||
|
setInputValue(name, expected.getName());
|
||||||
|
setInputValue(description, expected.getDescription());
|
||||||
|
logic.selectByValue(expected.getLogic().name());
|
||||||
|
|
||||||
|
Set<String> users = expected.getUsers();
|
||||||
|
|
||||||
|
for (String user : users) {
|
||||||
|
usersInput.select(user, driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
unSelect(users, usersInput.getSelected());
|
||||||
|
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unSelect(Set<String> users, Set<String> selection) {
|
||||||
|
for (String selected : selection) {
|
||||||
|
boolean isSelected = false;
|
||||||
|
|
||||||
|
for (String user : users) {
|
||||||
|
if (selected.equals(user)) {
|
||||||
|
isSelected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSelected) {
|
||||||
|
usersInput.unSelect(selected, driver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
deleteButton.click();
|
||||||
|
confirmDelete.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserPolicyRepresentation toRepresentation() {
|
||||||
|
UserPolicyRepresentation representation = new UserPolicyRepresentation();
|
||||||
|
|
||||||
|
representation.setName(getInputValue(name));
|
||||||
|
representation.setDescription(getInputValue(description));
|
||||||
|
representation.setLogic(Logic.valueOf(logic.getFirstSelectedOption().getText().toUpperCase()));
|
||||||
|
representation.setUsers(usersInput.getSelected());
|
||||||
|
|
||||||
|
return representation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UsersInput extends AbstractUserInput {
|
||||||
|
@Override
|
||||||
|
protected WebElement getRemoveButton(List<WebElement> tds) {
|
||||||
|
return tds.get(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<WebElement> getSelectedElements() {
|
||||||
|
return root.findElements(By.xpath("(//table[@id='selected-users'])/tbody/tr"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class AbstractUserInput {
|
||||||
|
|
||||||
|
@Root
|
||||||
|
protected WebElement root;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//div[contains(@class,'select2-result-label')]")
|
||||||
|
private List<WebElement> result;
|
||||||
|
|
||||||
|
@FindBy(xpath = "//li[contains(@class,'select2-search-choice')]")
|
||||||
|
private List<WebElement> selection;
|
||||||
|
|
||||||
|
public void select(String roleId, WebDriver driver) {
|
||||||
|
root.click();
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
|
||||||
|
Actions actions = new Actions(driver);
|
||||||
|
|
||||||
|
actions.sendKeys(roleId).perform();
|
||||||
|
WaitUtils.pause(1000);
|
||||||
|
|
||||||
|
if (result.isEmpty()) {
|
||||||
|
actions.sendKeys(Keys.ESCAPE).perform();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WebElement result : result) {
|
||||||
|
if (result.getText().equalsIgnoreCase(roleId)) {
|
||||||
|
result.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getSelected() {
|
||||||
|
List<WebElement> users = getSelectedElements();
|
||||||
|
Set<String> values = new HashSet<>();
|
||||||
|
|
||||||
|
for (WebElement user : users) {
|
||||||
|
List<WebElement> tds = user.findElements(tagName("td"));
|
||||||
|
if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
|
||||||
|
values.add(tds.get(0).getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract List<WebElement> getSelectedElements();
|
||||||
|
|
||||||
|
public void unSelect(String name, WebDriver driver) {
|
||||||
|
Iterator<WebElement> iterator = getSelectedElements().iterator();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
WebElement realmRole = iterator.next();
|
||||||
|
List<WebElement> tds = realmRole.findElements(tagName("td"));
|
||||||
|
|
||||||
|
if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) {
|
||||||
|
if (tds.get(0).getText().equals(name)) {
|
||||||
|
getRemoveButton(tds).findElement(By.tagName("button")).click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract WebElement getRemoveButton(List<WebElement> tds);
|
||||||
|
}
|
||||||
|
}
|
|
@ -75,6 +75,8 @@ public abstract class AbstractAuthorizationSettingsTest extends AbstractClientTe
|
||||||
clientSettingsPage.tabs().authorization();
|
clientSettingsPage.tabs().authorization();
|
||||||
assertTrue(authorizationPage.isCurrent());
|
assertTrue(authorizationPage.isCurrent());
|
||||||
|
|
||||||
|
newClient.setId(found.getId());
|
||||||
|
|
||||||
return newClient;
|
return newClient;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.authorization;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.admin.client.resource.AuthorizationResource;
|
||||||
|
import org.keycloak.admin.client.resource.PoliciesResource;
|
||||||
|
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.Logic;
|
||||||
|
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
|
||||||
|
import org.keycloak.testsuite.console.page.clients.authorization.policy.AggregatePolicy;
|
||||||
|
import org.keycloak.testsuite.console.page.clients.authorization.policy.UserPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class AggregatePolicyManagementTest extends AbstractAuthorizationSettingsTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void configureTest() {
|
||||||
|
super.configureTest();
|
||||||
|
RolesResource realmRoles = testRealmResource().roles();
|
||||||
|
realmRoles.create(new RoleRepresentation("Role A", "", false));
|
||||||
|
realmRoles.create(new RoleRepresentation("Role B", "", false));
|
||||||
|
|
||||||
|
RolePolicyRepresentation policyA = new RolePolicyRepresentation();
|
||||||
|
|
||||||
|
policyA.setName("Policy A");
|
||||||
|
policyA.addRole("Role A");
|
||||||
|
|
||||||
|
AuthorizationResource authorization = testRealmResource().clients().get(newClient.getId()).authorization();
|
||||||
|
PoliciesResource policies = authorization.policies();
|
||||||
|
RolePoliciesResource roles = policies.roles();
|
||||||
|
|
||||||
|
roles.create(policyA);
|
||||||
|
|
||||||
|
RolePolicyRepresentation policyB = new RolePolicyRepresentation();
|
||||||
|
|
||||||
|
policyB.setName("Policy B");
|
||||||
|
policyB.addRole("Role B");
|
||||||
|
|
||||||
|
roles.create(policyB);
|
||||||
|
|
||||||
|
UserPolicyRepresentation policyC = new UserPolicyRepresentation();
|
||||||
|
|
||||||
|
policyC.setName("Policy C");
|
||||||
|
policyC.addUser("test");
|
||||||
|
|
||||||
|
policies.users().create(policyC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
AggregatePolicyRepresentation expected = new AggregatePolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Aggregate Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.addPolicy("Policy A");
|
||||||
|
expected.addPolicy("Policy B");
|
||||||
|
expected.addPolicy("Policy C");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
|
||||||
|
String previousName = expected.getName();
|
||||||
|
|
||||||
|
expected.setName("Changed Test Aggregate Policy");
|
||||||
|
expected.setDescription("Changed description");
|
||||||
|
expected.setLogic(Logic.NEGATIVE);
|
||||||
|
|
||||||
|
expected.setPolicies(expected.getPolicies().stream().filter(policy -> !policy.equals("Policy B")).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(previousName, expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
AggregatePolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
|
||||||
|
|
||||||
|
assertPolicy(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeletePolicy() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
AggregatePolicyRepresentation expected = new AggregatePolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Aggregate Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.addPolicy("Policy C");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().delete(expected.getName());
|
||||||
|
assertAlertSuccess();
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private AggregatePolicyRepresentation createPolicy(AggregatePolicyRepresentation expected) {
|
||||||
|
AggregatePolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
return assertPolicy(expected, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AggregatePolicyRepresentation assertPolicy(AggregatePolicyRepresentation expected, AggregatePolicy policy) {
|
||||||
|
AggregatePolicyRepresentation actual = policy.toRepresentation();
|
||||||
|
|
||||||
|
assertEquals(expected.getName(), actual.getName());
|
||||||
|
assertEquals(expected.getDescription(), actual.getDescription());
|
||||||
|
assertEquals(expected.getLogic(), actual.getLogic());
|
||||||
|
|
||||||
|
assertNotNull(actual.getPolicies());
|
||||||
|
assertEquals(expected.getPolicies().size(), actual.getPolicies().size());
|
||||||
|
assertEquals(0, actual.getPolicies().stream().filter(actualPolicy -> !expected.getPolicies().stream()
|
||||||
|
.filter(expectedPolicy -> actualPolicy.equals(expectedPolicy))
|
||||||
|
.findFirst().isPresent())
|
||||||
|
.count());
|
||||||
|
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.authorization;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
import org.keycloak.testsuite.console.page.clients.authorization.policy.JSPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class JSPolicyManagementTest extends AbstractAuthorizationSettingsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
JSPolicyRepresentation expected = new JSPolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test JS Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.setCode("$evaluation.grant();");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
|
||||||
|
String previousName = expected.getName();
|
||||||
|
|
||||||
|
expected.setName("Changed Test JS Policy");
|
||||||
|
expected.setDescription("Changed description");
|
||||||
|
expected.setLogic(Logic.NEGATIVE);
|
||||||
|
expected.setCode("$evaluation.deny();");
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(previousName, expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
JSPolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
|
||||||
|
|
||||||
|
assertPolicy(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeletePolicy() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
JSPolicyRepresentation expected = new JSPolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test JS Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.setCode("$evaluation.deny();");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().delete(expected.getName());
|
||||||
|
assertAlertSuccess();
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSPolicyRepresentation createPolicy(JSPolicyRepresentation expected) {
|
||||||
|
JSPolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
return assertPolicy(expected, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSPolicyRepresentation assertPolicy(JSPolicyRepresentation expected, JSPolicy policy) {
|
||||||
|
JSPolicyRepresentation actual = policy.toRepresentation();
|
||||||
|
|
||||||
|
assertEquals(expected.getName(), actual.getName());
|
||||||
|
assertEquals(expected.getDescription(), actual.getDescription());
|
||||||
|
assertEquals(expected.getLogic(), actual.getLogic());
|
||||||
|
assertEquals(expected.getCode(), actual.getCode());
|
||||||
|
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.authorization;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.admin.client.resource.AuthorizationResource;
|
||||||
|
import org.keycloak.admin.client.resource.PoliciesResource;
|
||||||
|
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.DecisionStrategy;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class ResourcePermissionManagementTest extends AbstractAuthorizationSettingsTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void configureTest() {
|
||||||
|
super.configureTest();
|
||||||
|
RolesResource realmRoles = testRealmResource().roles();
|
||||||
|
realmRoles.create(new RoleRepresentation("Role A", "", false));
|
||||||
|
realmRoles.create(new RoleRepresentation("Role B", "", false));
|
||||||
|
|
||||||
|
RolePolicyRepresentation policyA = new RolePolicyRepresentation();
|
||||||
|
|
||||||
|
policyA.setName("Policy A");
|
||||||
|
policyA.addRole("Role A");
|
||||||
|
|
||||||
|
AuthorizationResource authorization = testRealmResource().clients().get(newClient.getId()).authorization();
|
||||||
|
PoliciesResource policies = authorization.policies();
|
||||||
|
RolePoliciesResource roles = policies.roles();
|
||||||
|
|
||||||
|
roles.create(policyA);
|
||||||
|
|
||||||
|
RolePolicyRepresentation policyB = new RolePolicyRepresentation();
|
||||||
|
|
||||||
|
policyB.setName("Policy B");
|
||||||
|
policyB.addRole("Role B");
|
||||||
|
|
||||||
|
roles.create(policyB);
|
||||||
|
|
||||||
|
UserPolicyRepresentation policyC = new UserPolicyRepresentation();
|
||||||
|
|
||||||
|
policyC.setName("Policy C");
|
||||||
|
policyC.addUser("test");
|
||||||
|
|
||||||
|
policies.users().create(policyC);
|
||||||
|
|
||||||
|
ResourcesResource resources = authorization.resources();
|
||||||
|
|
||||||
|
resources.create(new ResourceRepresentation("Resource A"));
|
||||||
|
resources.create(new ResourceRepresentation("Resource B"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateResource() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
ResourcePermissionRepresentation expected = new ResourcePermissionRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Resource A Permission");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.addResource("Resource A");
|
||||||
|
expected.addPolicy("Policy A");
|
||||||
|
expected.addPolicy("Policy B");
|
||||||
|
expected.addPolicy("Policy C");
|
||||||
|
|
||||||
|
expected = createPermission(expected);
|
||||||
|
|
||||||
|
String previousName = expected.getName();
|
||||||
|
|
||||||
|
expected.setName("Changed Test Resource A Permission");
|
||||||
|
expected.setDescription("Changed description");
|
||||||
|
expected.setDecisionStrategy(DecisionStrategy.CONSENSUS);
|
||||||
|
expected.getResources().clear();
|
||||||
|
expected.addResource("Resource B");
|
||||||
|
expected.setPolicies(expected.getPolicies().stream().filter(policy -> !policy.equals("Policy B")).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().permissions().update(previousName, expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
ResourcePermission actual = authorizationPage.authorizationTabs().permissions().name(expected.getName());
|
||||||
|
|
||||||
|
assertPolicy(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateResourceType() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
ResourcePermissionRepresentation expected = new ResourcePermissionRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Resource B Permission");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.setResourceType("test-resource-type");
|
||||||
|
expected.addPolicy("Policy A");
|
||||||
|
expected.addPolicy("Policy B");
|
||||||
|
expected.addPolicy("Policy C");
|
||||||
|
|
||||||
|
expected = createPermission(expected);
|
||||||
|
|
||||||
|
String previousName = expected.getName();
|
||||||
|
|
||||||
|
expected.setName("Changed Test Resource B Permission");
|
||||||
|
expected.setDescription("Changed description");
|
||||||
|
expected.setDecisionStrategy(DecisionStrategy.CONSENSUS);
|
||||||
|
|
||||||
|
expected.setResourceType("changed-resource-type");
|
||||||
|
expected.setPolicies(expected.getPolicies().stream().filter(policy -> !policy.equals("Policy B")).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().permissions().update(previousName, expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
ResourcePermission actual = authorizationPage.authorizationTabs().permissions().name(expected.getName());
|
||||||
|
|
||||||
|
assertPolicy(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeletePolicy() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
ResourcePermissionRepresentation expected = new ResourcePermissionRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Delete Resource Permission");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.addResource("Resource B");
|
||||||
|
expected.addPolicy("Policy C");
|
||||||
|
|
||||||
|
expected = createPermission(expected);
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().permissions().delete(expected.getName());
|
||||||
|
assertAlertSuccess();
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
assertNull(authorizationPage.authorizationTabs().permissions().permissions().findByName(expected.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourcePermissionRepresentation createPermission(ResourcePermissionRepresentation expected) {
|
||||||
|
ResourcePermission policy = authorizationPage.authorizationTabs().permissions().create(expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
return assertPolicy(expected, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourcePermissionRepresentation assertPolicy(ResourcePermissionRepresentation expected, ResourcePermission policy) {
|
||||||
|
ResourcePermissionRepresentation actual = policy.toRepresentation();
|
||||||
|
|
||||||
|
assertEquals(expected.getName(), actual.getName());
|
||||||
|
assertEquals(expected.getDescription(), actual.getDescription());
|
||||||
|
assertEquals(expected.getLogic(), actual.getLogic());
|
||||||
|
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,232 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.authorization;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.admin.client.resource.RolesResource;
|
||||||
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.RolePolicyRepresentation;
|
||||||
|
import org.keycloak.testsuite.console.page.clients.authorization.policy.RolePolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class RolePolicyManagementTest extends AbstractAuthorizationSettingsTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void configureTest() {
|
||||||
|
super.configureTest();
|
||||||
|
RolesResource realmRoles = testRealmResource().roles();
|
||||||
|
realmRoles.create(new RoleRepresentation("Realm Role A", "", false));
|
||||||
|
realmRoles.create(new RoleRepresentation("Realm Role B", "", false));
|
||||||
|
realmRoles.create(new RoleRepresentation("Realm Role C", "", false));
|
||||||
|
RolesResource clientRoles = testRealmResource().clients().get(newClient.getId()).roles();
|
||||||
|
clientRoles.create(new RoleRepresentation("Client Role A", "", false));
|
||||||
|
clientRoles.create(new RoleRepresentation("Client Role B", "", false));
|
||||||
|
clientRoles.create(new RoleRepresentation("Client Role C", "", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateRealmRoles() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
RolePolicyRepresentation expected = new RolePolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Realm Role Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.addRole("Realm Role A");
|
||||||
|
expected.addRole("Realm Role B");
|
||||||
|
expected.addRole("Realm Role C");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
|
||||||
|
String previousName = expected.getName();
|
||||||
|
|
||||||
|
expected.setName("Changed Test Realm Role Policy");
|
||||||
|
expected.setDescription("Changed description");
|
||||||
|
expected.setLogic(Logic.NEGATIVE);
|
||||||
|
|
||||||
|
expected.setRoles(expected.getRoles().stream().filter(roleDefinition -> !roleDefinition.getId().equals("Realm Role B")).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(previousName, expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
RolePolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
|
||||||
|
expected = assertPolicy(expected, actual);
|
||||||
|
|
||||||
|
expected.getRoles().iterator().next().setRequired(true);
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(expected.getName(), expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
expected = assertPolicy(expected, actual);
|
||||||
|
|
||||||
|
expected.getRoles().clear();
|
||||||
|
expected.addRole("Realm Role B", true);
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(expected.getName(), expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
assertPolicy(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateClientRoles() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
RolePolicyRepresentation expected = new RolePolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Client Role Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
|
||||||
|
String clientId = newClient.getClientId();
|
||||||
|
|
||||||
|
expected.addClientRole(clientId, "Client Role A");
|
||||||
|
expected.addClientRole(clientId, "Client Role B");
|
||||||
|
expected.addClientRole(clientId, "Client Role C");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
|
||||||
|
String previousName = expected.getName();
|
||||||
|
|
||||||
|
expected.setName("Changed Test Client Role Policy");
|
||||||
|
expected.setDescription("Changed description");
|
||||||
|
|
||||||
|
expected.setRoles(expected.getRoles().stream().filter(roleDefinition -> !roleDefinition.getId().contains("Client Role B")).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(previousName, expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
RolePolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
|
||||||
|
expected = assertPolicy(expected, actual);
|
||||||
|
|
||||||
|
expected.getRoles().iterator().next().setRequired(true);
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(expected.getName(), expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
expected = assertPolicy(expected, actual);
|
||||||
|
|
||||||
|
expected.getRoles().clear();
|
||||||
|
expected.addClientRole(clientId, "Client Role B", true);
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(expected.getName(), expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
assertPolicy(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRealmAndClientRoles() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
RolePolicyRepresentation expected = new RolePolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Realm And Client Role Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
|
||||||
|
String clientId = newClient.getClientId();
|
||||||
|
|
||||||
|
expected.addRole("Realm Role A");
|
||||||
|
expected.addRole("Realm Role C");
|
||||||
|
expected.addClientRole(clientId, "Client Role A");
|
||||||
|
expected.addClientRole(clientId, "Client Role B");
|
||||||
|
expected.addClientRole(clientId, "Client Role C");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
expected.setRoles(expected.getRoles().stream().filter(roleDefinition -> !roleDefinition.getId().contains("Client Role B") && !roleDefinition.getId().contains("Realm Role A")).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(expected.getName(), expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
RolePolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
|
||||||
|
expected = assertPolicy(expected, actual);
|
||||||
|
|
||||||
|
expected.getRoles().forEach(roleDefinition -> {
|
||||||
|
if (roleDefinition.getId().equals("Realm Role C")) {
|
||||||
|
roleDefinition.setRequired(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(expected.getName(), expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
expected = assertPolicy(expected, actual);
|
||||||
|
|
||||||
|
expected.getRoles().clear();
|
||||||
|
expected.addClientRole(clientId, "Client Role B", true);
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(expected.getName(), expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
assertPolicy(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeletePolicy() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
RolePolicyRepresentation expected = new RolePolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Realm Role Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.addRole("Realm Role A");
|
||||||
|
expected.addRole("Realm Role B");
|
||||||
|
expected.addRole("Realm Role C");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().delete(expected.getName());
|
||||||
|
assertAlertSuccess();
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private RolePolicyRepresentation createPolicy(RolePolicyRepresentation expected) {
|
||||||
|
RolePolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
return assertPolicy(expected, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RolePolicyRepresentation assertPolicy(RolePolicyRepresentation expected, RolePolicy policy) {
|
||||||
|
RolePolicyRepresentation actual = policy.toRepresentation();
|
||||||
|
|
||||||
|
assertEquals(expected.getName(), actual.getName());
|
||||||
|
assertEquals(expected.getDescription(), actual.getDescription());
|
||||||
|
assertEquals(expected.getLogic(), actual.getLogic());
|
||||||
|
|
||||||
|
assertNotNull(actual.getRoles());
|
||||||
|
assertEquals(expected.getRoles().size(), actual.getRoles().size());
|
||||||
|
assertEquals(0, actual.getRoles().stream().filter(actualDefinition -> !expected.getRoles().stream()
|
||||||
|
.filter(roleDefinition -> actualDefinition.getId().contains(roleDefinition.getId()) && actualDefinition.isRequired() == roleDefinition.isRequired())
|
||||||
|
.findFirst().isPresent())
|
||||||
|
.count());
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.authorization;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.representations.idm.authorization.JSPolicyRepresentation;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
import org.keycloak.representations.idm.authorization.TimePolicyRepresentation;
|
||||||
|
import org.keycloak.testsuite.console.page.clients.authorization.policy.JSPolicy;
|
||||||
|
import org.keycloak.testsuite.console.page.clients.authorization.policy.TimePolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class TimePolicyManagementTest extends AbstractAuthorizationSettingsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
TimePolicyRepresentation expected = new TimePolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Time Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.setNotBefore("2017-01-01 00:00:00");
|
||||||
|
expected.setNotBefore("2018-01-01 00:00:00");
|
||||||
|
expected.setDayMonth("1");
|
||||||
|
expected.setDayMonthEnd("2");
|
||||||
|
expected.setMonth("3");
|
||||||
|
expected.setMonthEnd("4");
|
||||||
|
expected.setYear("5");
|
||||||
|
expected.setYearEnd("6");
|
||||||
|
expected.setHour("7");
|
||||||
|
expected.setHourEnd("8");
|
||||||
|
expected.setMinute("9");
|
||||||
|
expected.setMinuteEnd("10");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
|
||||||
|
String previousName = expected.getName();
|
||||||
|
|
||||||
|
expected.setName("Changed Test Time Policy");
|
||||||
|
expected.setDescription("Changed description");
|
||||||
|
expected.setLogic(Logic.NEGATIVE);
|
||||||
|
expected.setNotBefore("2018-01-01 00:00:00");
|
||||||
|
expected.setNotBefore("2019-01-01 00:00:00");
|
||||||
|
expected.setDayMonth("23");
|
||||||
|
expected.setDayMonthEnd("25");
|
||||||
|
expected.setMonth("11");
|
||||||
|
expected.setMonthEnd("12");
|
||||||
|
expected.setYear("2020");
|
||||||
|
expected.setYearEnd("2021");
|
||||||
|
expected.setHour("17");
|
||||||
|
expected.setHourEnd("18");
|
||||||
|
expected.setMinute("19");
|
||||||
|
expected.setMinuteEnd("20");
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(previousName, expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
TimePolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
|
||||||
|
|
||||||
|
assertPolicy(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeletePolicy() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
TimePolicyRepresentation expected = new TimePolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test Time Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.setNotBefore("2017-01-01 00:00:00");
|
||||||
|
expected.setNotBefore("2018-01-01 00:00:00");
|
||||||
|
expected.setDayMonth("1");
|
||||||
|
expected.setDayMonthEnd("2");
|
||||||
|
expected.setMonth("3");
|
||||||
|
expected.setMonthEnd("4");
|
||||||
|
expected.setYear("5");
|
||||||
|
expected.setYearEnd("6");
|
||||||
|
expected.setHour("7");
|
||||||
|
expected.setHourEnd("8");
|
||||||
|
expected.setMinute("9");
|
||||||
|
expected.setMinuteEnd("10");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().delete(expected.getName());
|
||||||
|
assertAlertSuccess();
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimePolicyRepresentation createPolicy(TimePolicyRepresentation expected) {
|
||||||
|
TimePolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
return assertPolicy(expected, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimePolicyRepresentation assertPolicy(TimePolicyRepresentation expected, TimePolicy policy) {
|
||||||
|
TimePolicyRepresentation actual = policy.toRepresentation();
|
||||||
|
|
||||||
|
assertEquals(expected.getName(), actual.getName());
|
||||||
|
assertEquals(expected.getDescription(), actual.getDescription());
|
||||||
|
assertEquals(expected.getLogic(), actual.getLogic());
|
||||||
|
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 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.authorization;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.admin.client.resource.UsersResource;
|
||||||
|
import org.keycloak.representations.idm.authorization.Logic;
|
||||||
|
import org.keycloak.representations.idm.authorization.UserPolicyRepresentation;
|
||||||
|
import org.keycloak.testsuite.console.page.clients.authorization.policy.UserPolicy;
|
||||||
|
import org.keycloak.testsuite.util.UserBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
|
||||||
|
*/
|
||||||
|
public class UserPolicyManagementTest extends AbstractAuthorizationSettingsTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void configureTest() {
|
||||||
|
super.configureTest();
|
||||||
|
UsersResource users = testRealmResource().users();
|
||||||
|
users.create(UserBuilder.create().username("user a").build());
|
||||||
|
users.create(UserBuilder.create().username("user b").build());
|
||||||
|
users.create(UserBuilder.create().username("user c").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdate() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
UserPolicyRepresentation expected = new UserPolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test User Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.addUser("user a");
|
||||||
|
expected.addUser("user b");
|
||||||
|
expected.addUser("user c");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
|
||||||
|
String previousName = expected.getName();
|
||||||
|
|
||||||
|
expected.setName("Changed Test User Policy");
|
||||||
|
expected.setDescription("Changed description");
|
||||||
|
expected.setLogic(Logic.NEGATIVE);
|
||||||
|
|
||||||
|
expected.setUsers(expected.getUsers().stream().filter(user -> !user.equals("user b")).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().update(previousName, expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
UserPolicy actual = authorizationPage.authorizationTabs().policies().name(expected.getName());
|
||||||
|
|
||||||
|
assertPolicy(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeletePolicy() throws InterruptedException {
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
UserPolicyRepresentation expected = new UserPolicyRepresentation();
|
||||||
|
|
||||||
|
expected.setName("Test User Policy");
|
||||||
|
expected.setDescription("description");
|
||||||
|
expected.addUser("user c");
|
||||||
|
|
||||||
|
expected = createPolicy(expected);
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
authorizationPage.authorizationTabs().policies().delete(expected.getName());
|
||||||
|
assertAlertSuccess();
|
||||||
|
authorizationPage.navigateTo();
|
||||||
|
assertNull(authorizationPage.authorizationTabs().policies().policies().findByName(expected.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserPolicyRepresentation createPolicy(UserPolicyRepresentation expected) {
|
||||||
|
UserPolicy policy = authorizationPage.authorizationTabs().policies().create(expected);
|
||||||
|
assertAlertSuccess();
|
||||||
|
return assertPolicy(expected, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserPolicyRepresentation assertPolicy(UserPolicyRepresentation expected, UserPolicy policy) {
|
||||||
|
UserPolicyRepresentation actual = policy.toRepresentation();
|
||||||
|
|
||||||
|
assertEquals(expected.getName(), actual.getName());
|
||||||
|
assertEquals(expected.getDescription(), actual.getDescription());
|
||||||
|
assertEquals(expected.getLogic(), actual.getLogic());
|
||||||
|
|
||||||
|
assertNotNull(actual.getUsers());
|
||||||
|
assertEquals(expected.getUsers().size(), actual.getUsers().size());
|
||||||
|
assertEquals(0, actual.getUsers().stream().filter(actualUser -> !expected.getUsers().stream()
|
||||||
|
.filter(expectedUser -> actualUser.equals(expectedUser))
|
||||||
|
.findFirst().isPresent())
|
||||||
|
.count());
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1789,7 +1789,6 @@ module.controller('ResourceServerPolicyAggregateDetailCtrl', function($scope, $r
|
||||||
},
|
},
|
||||||
|
|
||||||
onInitUpdate : function(policy) {
|
onInitUpdate : function(policy) {
|
||||||
policy.config.applyPolicies = [];
|
|
||||||
ResourceServerPolicy.associatedPolicies({
|
ResourceServerPolicy.associatedPolicies({
|
||||||
realm : $route.current.params.realm,
|
realm : $route.current.params.realm,
|
||||||
client : client.id,
|
client : client.id,
|
||||||
|
@ -1816,11 +1815,11 @@ module.controller('ResourceServerPolicyAggregateDetailCtrl', function($scope, $r
|
||||||
policies.push($scope.selectedPolicies[i].id);
|
policies.push($scope.selectedPolicies[i].id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.policy.config.applyPolicies = JSON.stringify(policies);
|
$scope.policy.policies = policies;
|
||||||
|
delete $scope.policy.config;
|
||||||
},
|
},
|
||||||
|
|
||||||
onInitCreate : function(newPolicy) {
|
onInitCreate : function(newPolicy) {
|
||||||
newPolicy.config = {};
|
|
||||||
newPolicy.decisionStrategy = 'UNANIMOUS';
|
newPolicy.decisionStrategy = 'UNANIMOUS';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1831,7 +1830,8 @@ module.controller('ResourceServerPolicyAggregateDetailCtrl', function($scope, $r
|
||||||
policies.push($scope.selectedPolicies[i].id);
|
policies.push($scope.selectedPolicies[i].id);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.policy.config.applyPolicies = JSON.stringify(policies);
|
$scope.policy.policies = policies;
|
||||||
|
delete $scope.policy.config;
|
||||||
}
|
}
|
||||||
}, realm, client, $scope);
|
}, realm, client, $scope);
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,36 +36,36 @@
|
||||||
<kc-tooltip>{{:: 'authz-permission-resource-apply-to-resource-type.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-permission-resource-apply-to-resource-type.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix" data-ng-hide="applyToResourceTypeFlag">
|
<div class="form-group clearfix" data-ng-hide="applyToResourceTypeFlag">
|
||||||
<label class="col-md-2 control-label" for="reqActions">{{:: 'authz-resources' | translate}} <span class="required">*</span></label>
|
<label class="col-md-2 control-label" for="resources">{{:: 'authz-resources' | translate}} <span class="required">*</span></label>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input type="hidden" ui-select2="resourcesUiSelect" id="reqActions" data-ng-model="selectedResource" data-placeholder="{{:: 'authz-select-resource' | translate}}..." data-ng-required="!applyToResourceTypeFlag"/>
|
<input type="hidden" ui-select2="resourcesUiSelect" id="resources" data-ng-model="selectedResource" data-placeholder="{{:: 'authz-select-resource' | translate}}..." data-ng-required="!applyToResourceTypeFlag"/>
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-permission-resource-resource.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-permission-resource-resource.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix" data-ng-show="applyToResourceTypeFlag">
|
<div class="form-group clearfix" data-ng-show="applyToResourceTypeFlag">
|
||||||
<label class="col-md-2 control-label" for="policy.resourceType">{{:: 'authz-resource-type' | translate}} <span class="required">*</span></label>
|
<label class="col-md-2 control-label" for="resourceType">{{:: 'authz-resource-type' | translate}} <span class="required">*</span></label>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input class="form-control" type="text" id="policy.resourceType" name="policy.resourceType" data-ng-model="policy.resourceType" data-ng-required="applyToResourceTypeFlag">
|
<input class="form-control" type="text" id="resourceType" name="policy.resourceType" data-ng-model="policy.resourceType" data-ng-required="applyToResourceTypeFlag">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<kc-tooltip>{{:: 'authz-permission-resource-type.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-permission-resource-type.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<label class="col-md-2 control-label" for="reqActions">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
|
<label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input type="hidden" ui-select2="policiesUiSelect" id="reqActions" data-ng-model="selectedPolicies" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." multiple required />
|
<input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-model="selectedPolicies" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." multiple required />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<label class="col-md-2 control-label" for="policy.decisionStrategy">{{:: 'authz-policy-decision-strategy' | translate}}</label>
|
<label class="col-md-2 control-label" for="decisionStrategy">{{:: 'authz-policy-decision-strategy' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<select class="form-control" id="policy.decisionStrategy"
|
<select class="form-control" id="decisionStrategy"
|
||||||
data-ng-model="policy.decisionStrategy"
|
data-ng-model="policy.decisionStrategy"
|
||||||
ng-change="selectDecisionStrategy()">
|
ng-change="selectDecisionStrategy()">
|
||||||
<option value="UNANIMOUS">{{:: 'authz-policy-decision-strategy-unanimous' | translate}}</option>
|
<option value="UNANIMOUS">{{:: 'authz-policy-decision-strategy-unanimous' | translate}}</option>
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<select class="form-control" ng-model="policyType"
|
<select class="form-control" ng-model="policyType"
|
||||||
ng-options="p.name for p in policyProviders track by p.type"
|
ng-options="p.name for p in policyProviders track by p.type"
|
||||||
|
id="create-permission"
|
||||||
data-ng-change="addPolicy(policyType);">
|
data-ng-change="addPolicy(policyType);">
|
||||||
<option value="" disabled selected>{{:: 'authz-create-permission' | translate}}...</option>
|
<option value="" disabled selected>{{:: 'authz-create-permission' | translate}}...</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -31,10 +31,10 @@
|
||||||
<kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<label class="col-md-2 control-label" for="reqActions">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
|
<label class="col-md-2 control-label" for="policies">{{:: 'authz-policy-apply-policy' | translate}} <span class="required">*</span></label>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input type="hidden" ui-select2="policiesUiSelect" id="reqActions" data-ng-model="selectedPolicies" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." multiple required />
|
<input type="hidden" ui-select2="policiesUiSelect" id="policies" data-ng-model="selectedPolicies" data-placeholder="{{:: 'authz-select-a-policy' | translate}}..." multiple required />
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-apply-policy.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
@ -54,10 +54,10 @@
|
||||||
<kc-tooltip>{{:: 'authz-policy-decision-strategy.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-decision-strategy.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<label class="col-md-2 control-label" for="policy.logic">{{:: 'authz-policy-logic' | translate}}</label>
|
<label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-sm-1">
|
<div class="col-sm-1">
|
||||||
<select class="form-control" id="policy.logic"
|
<select class="form-control" id="logic" name="logic"
|
||||||
data-ng-model="policy.logic">
|
data-ng-model="policy.logic">
|
||||||
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
||||||
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
||||||
|
|
|
@ -33,17 +33,17 @@
|
||||||
<kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="description">{{:: 'authz-policy-js-code' | translate}} </label>
|
<label class="col-md-2 control-label" for="code">{{:: 'authz-policy-js-code' | translate}} </label>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div ui-ace="{ onLoad : initEditor }" data-ng-model="policy.code"></div>
|
<div ui-ace="{ onLoad : initEditor }" id="code" data-ng-model="policy.code"></div>
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-js-code.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-js-code.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<label class="col-md-2 control-label" for="policy.logic">{{:: 'authz-policy-logic' | translate}}</label>
|
<label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-sm-1">
|
<div class="col-sm-1">
|
||||||
<select class="form-control" id="policy.logic"
|
<select class="form-control" id="logic"
|
||||||
data-ng-model="policy.logic">
|
data-ng-model="policy.logic">
|
||||||
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
||||||
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
<div class="form-group clearfix" style="margin-top: -15px;">
|
<div class="form-group clearfix" style="margin-top: -15px;">
|
||||||
<label class="col-md-2 control-label"></label>
|
<label class="col-md-2 control-label"></label>
|
||||||
<div class="col-sm-4" data-ng-show="hasRealmRole()">
|
<div class="col-sm-4" data-ng-show="hasRealmRole()">
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered" id="selected-realm-roles">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="col-sm-5">{{:: 'name' | translate}}</th>
|
<th class="col-sm-5">{{:: 'name' | translate}}</th>
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
<div class="form-group clearfix" style="margin-top: -15px;">
|
<div class="form-group clearfix" style="margin-top: -15px;">
|
||||||
<label class="col-md-2 control-label"></label>
|
<label class="col-md-2 control-label"></label>
|
||||||
<div class="col-sm-4" data-ng-show="hasClientRole()">
|
<div class="col-sm-4" data-ng-show="hasClientRole()">
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered" id="selected-client-roles">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="col-sm-5">{{:: 'name' | translate}}</th>
|
<th class="col-sm-5">{{:: 'name' | translate}}</th>
|
||||||
|
@ -140,10 +140,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<label class="col-md-2 control-label" for="policy.logic">{{:: 'authz-policy-logic' | translate}}</label>
|
<label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-sm-1">
|
<div class="col-sm-1">
|
||||||
<select class="form-control" id="policy.logic"
|
<select class="form-control" id="logic"
|
||||||
data-ng-model="policy.logic">
|
data-ng-model="policy.logic">
|
||||||
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
||||||
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
||||||
|
|
|
@ -34,18 +34,18 @@
|
||||||
<kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-description.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="policy.notBefore">{{:: 'not-before' | translate}}</label>
|
<label class="col-md-2 control-label" for="notBefore">{{:: 'not-before' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6 time-selector">
|
<div class="col-md-6 time-selector">
|
||||||
<input class="form-control" style="width: 150px" type="text" id="policy.notBefore" name="notBefore" data-ng-model="policy.notBefore" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()">
|
<input class="form-control" style="width: 150px" type="text" id="notBefore" name="notBefore" data-ng-model="policy.notBefore" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()">
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-not-before.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-not-before.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="policy.notOnOrAfter">{{:: 'authz-policy-time-not-on-after' | translate}}</label>
|
<label class="col-md-2 control-label" for="notOnOrAfter">{{:: 'authz-policy-time-not-on-after' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-md-6 time-selector">
|
<div class="col-md-6 time-selector">
|
||||||
<input class="form-control" style="width: 150px" type="text" id="policy.notOnOrAfter" name="policy.notOnOrAfter" data-ng-model="policy.notOnOrAfter" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()">
|
<input class="form-control" style="width: 150px" type="text" id="notOnOrAfter" name="notOnOrAfter" data-ng-model="policy.notOnOrAfter" placeholder="yyyy-MM-dd hh:mm:ss" data-ng-required="isRequired()">
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-not-on-after.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-not-on-after.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,10 +90,10 @@
|
||||||
<kc-tooltip>{{:: 'authz-policy-time-minute.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'authz-policy-time-minute.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<label class="col-md-2 control-label" for="policy.logic">{{:: 'authz-policy-logic' | translate}}</label>
|
<label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-sm-1">
|
<div class="col-sm-1">
|
||||||
<select class="form-control" id="policy.logic"
|
<select class="form-control" id="logic"
|
||||||
data-ng-model="policy.logic">
|
data-ng-model="policy.logic">
|
||||||
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
||||||
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<div class="form-group clearfix" style="margin-top: -15px;">
|
<div class="form-group clearfix" style="margin-top: -15px;">
|
||||||
<label class="col-md-2 control-label"></label>
|
<label class="col-md-2 control-label"></label>
|
||||||
<div class="col-sm-3">
|
<div class="col-sm-3">
|
||||||
<table class="table table-striped table-bordered">
|
<table class="table table-striped table-bordered" id="selected-users">
|
||||||
<thead>
|
<thead>
|
||||||
<tr data-ng-hide="!selectedUsers.length">
|
<tr data-ng-hide="!selectedUsers.length">
|
||||||
<th>{{:: 'username' | translate}}</th>
|
<th>{{:: 'username' | translate}}</th>
|
||||||
|
@ -64,10 +64,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group clearfix">
|
<div class="form-group clearfix">
|
||||||
<label class="col-md-2 control-label" for="policy.logic">{{:: 'authz-policy-logic' | translate}}</label>
|
<label class="col-md-2 control-label" for="logic">{{:: 'authz-policy-logic' | translate}}</label>
|
||||||
|
|
||||||
<div class="col-sm-1">
|
<div class="col-sm-1">
|
||||||
<select class="form-control" id="policy.logic"
|
<select class="form-control" id="logic"
|
||||||
data-ng-model="policy.logic">
|
data-ng-model="policy.logic">
|
||||||
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
<option value="POSITIVE">{{:: 'authz-policy-logic-positive' | translate}}</option>
|
||||||
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
<option value="NEGATIVE">{{:: 'authz-policy-logic-negative' | translate}}</option>
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<a id="hideDetails" data-ng-show="showDetailsFlag" class="btn btn-default" data-ng-click="showDetailsFlag = !showDetailsFlag;showDetails();" href="">{{:: 'authz-hide-details' | translate}}</a>
|
<a id="hideDetails" data-ng-show="showDetailsFlag" class="btn btn-default" data-ng-click="showDetailsFlag = !showDetailsFlag;showDetails();" href="">{{:: 'authz-hide-details' | translate}}</a>
|
||||||
<a id="showDetails" data-ng-hide="showDetailsFlag" class="btn btn-default" data-ng-click="showDetailsFlag = !showDetailsFlag;showDetails();" href="">{{:: 'authz-show-details' | translate}}</a>
|
<a id="showDetails" data-ng-hide="showDetailsFlag" class="btn btn-default" data-ng-click="showDetailsFlag = !showDetailsFlag;showDetails();" href="">{{:: 'authz-show-details' | translate}}</a>
|
||||||
<select class="form-control" ng-model="policyType"
|
<select id="create-policy" class="form-control" ng-model="policyType"
|
||||||
ng-options="p.name for p in policyProviders track by p.type"
|
ng-options="p.name for p in policyProviders track by p.type"
|
||||||
data-ng-change="addPolicy(policyType);">
|
data-ng-change="addPolicy(policyType);">
|
||||||
<option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
|
<option value="" disabled selected>{{:: 'authz-create-policy' | translate}}...</option>
|
||||||
|
|
Loading…
Reference in a new issue