diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java index a6ce3e5bcb..39999ba104 100644 --- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java @@ -76,6 +76,8 @@ public class Client extends Clients { private WebElement installationLink; @FindBy(linkText = "Service Account Roles") private WebElement serviceAccountRoles; + @FindBy(linkText = "Authorization") + private WebElement authorizationLink; public void settings() { settingsLink.click(); @@ -104,6 +106,10 @@ public class Client extends Clients { public void installation() { installationLink.click(); } + + public void authorization() { + authorizationLink.click(); + } public boolean isServiceAccountRolesDisplayed() { try { diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/Authorization.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/Authorization.java new file mode 100644 index 0000000000..d881354cf8 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/Authorization.java @@ -0,0 +1,135 @@ +/* + * 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; + +import org.jboss.arquillian.graphene.fragment.Root; +import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.testsuite.console.page.clients.Client; +import org.keycloak.testsuite.console.page.clients.authorization.permission.Permissions; +import org.keycloak.testsuite.console.page.clients.authorization.policy.Policies; +import org.keycloak.testsuite.console.page.clients.authorization.resource.Resources; +import org.keycloak.testsuite.console.page.clients.authorization.scope.Scopes; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +/** + * + * @author tkyjovsk + */ +public class Authorization extends Client { + + @FindBy(id = "authz-tabs") + protected AuthorizationTabLinks authorizationTabLinks; + + @Page + private AuthorizationSettingsForm authorizationSettingsForm; + + @Page + private Resources resources; + + @Page + private Scopes scopes; + + @Page + private Permissions permissions; + + @Page + private Policies policies; + + public AuthorizationSettingsForm settings() { + return authorizationSettingsForm; + } + + public AuthorizationTab authorizationTabs() { + return new AuthorizationTab(authorizationTabLinks); + } + + @Override + public String getUriFragment() { + return super.getUriFragment() + "/authz/resource-server"; + } + + public class AuthorizationTab { + + private final AuthorizationTabLinks links; + + public AuthorizationTab(AuthorizationTabLinks links) { + this.links = links; + } + + public Resources resources() { + links.resources(); + return resources; + } + + public Scopes scopes() { + links.scopes(); + return scopes; + } + + public Permissions permissions() { + links.permissions(); + return permissions; + } + + public Policies policies() { + links.policies(); + return policies; + } + } + + public class AuthorizationTabLinks { + + @Root + private WebElement root; + + @FindBy(linkText = "Settings") + private WebElement settingsLink; + + @FindBy(linkText = "Resources") + private WebElement resourcesLink; + + @FindBy(linkText = "Authorization Scopes") + private WebElement scopesLink; + + @FindBy(linkText = "Permissions") + private WebElement permissionsLink; + + @FindBy(linkText = "Policies") + private WebElement policiesLink; + + public void settings() { + settingsLink.click(); + } + + public void resources() { + resourcesLink.click(); + } + + private void scopes() { + scopesLink.click(); + } + + private void permissions() { + permissionsLink.click(); + } + + private void policies() { + policiesLink.click(); + } + } +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/AuthorizationSettingsForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/AuthorizationSettingsForm.java new file mode 100644 index 0000000000..d8b38e9b22 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/AuthorizationSettingsForm.java @@ -0,0 +1,62 @@ +/* + * 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; + +import static org.keycloak.testsuite.util.WaitUtils.pause; +import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.testsuite.console.page.clients.CreateClientForm; +import org.keycloak.testsuite.console.page.fragment.OnOffSwitch; +import org.keycloak.testsuite.page.Form; +import org.keycloak.testsuite.util.Timer; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; +import org.openqa.selenium.support.ui.Select; + +/** + * @author tkyjovsk + */ +public class AuthorizationSettingsForm extends Form { + + @FindBy(id = "server.policyEnforcementMode") + private Select enforcementMode; + + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='server.allowRemoteResourceManagement']]") + private OnOffSwitch allowRemoteResourceManagement; + + public void setEnforcementMode(PolicyEnforcerConfig.EnforcementMode mode) { + enforcementMode.selectByValue(mode.name()); + } + + public PolicyEnforcerConfig.EnforcementMode getEnforcementMode() { + return PolicyEnforcerConfig.EnforcementMode.valueOf(enforcementMode.getFirstSelectedOption().getAttribute("value")); + } + + public void setAllowRemoteResourceManagement(boolean enable) { + allowRemoteResourceManagement.setOn(enable); + } + + public boolean isAllowRemoteResourceManagement() { + return allowRemoteResourceManagement.isOn(); + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java new file mode 100644 index 0000000000..1522504b85 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/Permissions.java @@ -0,0 +1,33 @@ +/* + * 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.keycloak.testsuite.page.Form; +import org.openqa.selenium.support.FindBy; + +/** + * @author tkyjovsk + */ +public class Permissions extends Form { + + @FindBy(css = "table[class*='table']") + private PermissionsTable table; + + public PermissionsTable permissions() { + return table; + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/PermissionsTable.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/PermissionsTable.java new file mode 100644 index 0000000000..5329ff1b3b --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/permission/PermissionsTable.java @@ -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.permission; + +import static org.openqa.selenium.By.tagName; + +import java.util.ArrayList; +import java.util.List; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.testsuite.console.page.fragment.DataTable; +import org.openqa.selenium.WebElement; + +/** + * + * @author tkyjovsk + */ +public class PermissionsTable extends DataTable { + + public PolicyRepresentation findByName(String name) { + search(name); + List result = getTableRows(); + if (result.isEmpty()) { + return null; + } else { + assert 1 == result.size(); + return result.get(0); + } + } + + public boolean contains(String name) { + for (PolicyRepresentation representation : getTableRows()) { + if (name.equals(representation.getName())) { + return true; + } + } + return false; + } + + public List getTableRows() { + List rows = new ArrayList<>(); + for (WebElement row : rows()) { + PolicyRepresentation representation = toRepresentation(row); + if (representation != null) { + rows.add(representation); + } + } + return rows; + } + + public PolicyRepresentation toRepresentation(WebElement row) { + PolicyRepresentation representation = null; + List tds = row.findElements(tagName("td")); + if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) { + representation = new PolicyRepresentation(); + representation.setName(tds.get(0).getText()); + representation.setDescription(tds.get(1).getText()); + representation.setType(tds.get(2).getText()); + } + return representation; + } + +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java new file mode 100644 index 0000000000..f0364e1f7c --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/Policies.java @@ -0,0 +1,34 @@ +/* + * 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.testsuite.console.page.clients.authorization.permission.PermissionsTable; +import org.keycloak.testsuite.page.Form; +import org.openqa.selenium.support.FindBy; + +/** + * @author tkyjovsk + */ +public class Policies extends Form { + + @FindBy(css = "table[class*='table']") + private PermissionsTable table; + + public PermissionsTable policies() { + return table; + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/PoliciesTable.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/PoliciesTable.java new file mode 100644 index 0000000000..d6e91dfaed --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/policy/PoliciesTable.java @@ -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 static org.openqa.selenium.By.tagName; + +import java.util.ArrayList; +import java.util.List; + +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.testsuite.console.page.fragment.DataTable; +import org.openqa.selenium.WebElement; + +/** + * + * @author tkyjovsk + */ +public class PoliciesTable extends DataTable { + + public PolicyRepresentation findByName(String name) { + search(name); + List result = getTableRows(); + if (result.isEmpty()) { + return null; + } else { + assert 1 == result.size(); + return result.get(0); + } + } + + public boolean contains(String name) { + for (PolicyRepresentation representation : getTableRows()) { + if (name.equals(representation.getName())) { + return true; + } + } + return false; + } + + public List getTableRows() { + List rows = new ArrayList<>(); + for (WebElement row : rows()) { + PolicyRepresentation representation = toRepresentation(row); + if (representation != null) { + rows.add(representation); + } + } + return rows; + } + + public PolicyRepresentation toRepresentation(WebElement row) { + PolicyRepresentation representation = null; + List tds = row.findElements(tagName("td")); + if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) { + representation = new PolicyRepresentation(); + representation.setName(tds.get(0).getText()); + representation.setDescription(tds.get(1).getText()); + representation.setType(tds.get(2).getText()); + } + return representation; + } + +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resource.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resource.java new file mode 100644 index 0000000000..4fd6d4a096 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resource.java @@ -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.resource; + +import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; + +/** + * @author Pedro Igor + */ +public class Resource { + + @Page + private ResourceForm form; + + public ResourceForm form() { + return form; + } + + public ResourceRepresentation toRepresentation() { + return form.toRepresentation(); + } + + public void update(ResourceRepresentation expected) { + form().populate(expected); + } +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/ResourceForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/ResourceForm.java new file mode 100644 index 0000000000..959dffb653 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/ResourceForm.java @@ -0,0 +1,163 @@ +/* + * 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.resource; + +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.ResourceRepresentation; +import org.keycloak.representations.idm.authorization.ScopeRepresentation; +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.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +/** + * @author tkyjovsk + */ +public class ResourceForm extends Form { + + @FindBy(id = "name") + private WebElement name; + + @FindBy(id = "type") + private WebElement type; + + @FindBy(id = "uri") + private WebElement uri; + + @FindBy(id = "iconUri") + private WebElement iconUri; + + @FindBy(id = "resource.owner.name") + private WebElement owner; + + @FindBy(xpath = "//i[contains(@class,'pficon-delete')]") + private WebElement deleteButton; + + @FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']") + private WebElement confirmDelete; + + @FindBy(id = "s2id_scopes") + private ScopesInput scopesInput; + + public void populate(ResourceRepresentation expected) { + setInputValue(name, expected.getName()); + setInputValue(type, expected.getType()); + setInputValue(uri, expected.getUri()); + setInputValue(iconUri, expected.getIconUri()); + + Set scopes = expected.getScopes(); + + for (ScopeRepresentation scope : scopes) { + scopesInput.select(scope.getName()); + } + + Set selection = scopesInput.getSelected(); + + for (ScopeRepresentation selected : selection) { + boolean isSelected = false; + + for (ScopeRepresentation scope : scopes) { + if (selected.getName().equals(scope.getName())) { + isSelected = true; + break; + } + } + + if (!isSelected) { + scopesInput.unSelect(selected.getName(), driver); + } + } + + save(); + } + + public void delete() { + deleteButton.click(); + confirmDelete.click(); + } + + public ResourceRepresentation toRepresentation() { + ResourceRepresentation representation = new ResourceRepresentation(); + + representation.setName(getInputValue(name)); + representation.setType(getInputValue(type)); + representation.setUri(getInputValue(uri)); + representation.setIconUri(getInputValue(iconUri)); + representation.setScopes(scopesInput.getSelected()); + + return representation; + } + + public class ScopesInput { + + @Root + private WebElement root; + + @FindBy(xpath = "//input[contains(@class,'select2-input')]") + private WebElement search; + + @FindBy(xpath = "//div[contains(@class,'select2-result-label')]") + private List result; + + @FindBy(xpath = "//li[contains(@class,'select2-search-choice')]") + private List selection; + + public void select(String name) { + setInputValue(search, name); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + for (WebElement result : result) { + if (result.getText().equalsIgnoreCase(name)) { + result.click(); + return; + } + } + } + + public Set getSelected() { + HashSet values = new HashSet<>(); + + for (WebElement selected : selection) { + values.add(new ScopeRepresentation(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; + } + } + } + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java new file mode 100644 index 0000000000..54ad2fad45 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/Resources.java @@ -0,0 +1,86 @@ +/* + * 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.resource; + +import static org.openqa.selenium.By.tagName; + +import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; +import org.keycloak.testsuite.page.Form; +import org.keycloak.testsuite.util.WaitUtils; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +/** + * @author tkyjovsk + */ +public class Resources extends Form { + + @FindBy(css = "table[class*='table']") + private ResourcesTable table; + + @FindBy(linkText = "Create") + private WebElement create; + + @Page + private Resource resource; + + public ResourcesTable resources() { + return table; + } + + public void create(ResourceRepresentation representation) { + create.click(); + resource.form().populate(representation); + } + + public void update(String name, ResourceRepresentation representation) { + for (WebElement row : resources().rows()) { + ResourceRepresentation actual = resources().toRepresentation(row); + if (actual.getName().equalsIgnoreCase(name)) { + row.findElements(tagName("a")).get(0).click(); + WaitUtils.waitForPageToLoad(driver); + resource.form().populate(representation); + return; + } + } + } + + public void delete(String name) { + for (WebElement row : resources().rows()) { + ResourceRepresentation actual = resources().toRepresentation(row); + if (actual.getName().equalsIgnoreCase(name)) { + row.findElements(tagName("a")).get(0).click(); + WaitUtils.waitForPageToLoad(driver); + resource.form().delete(); + return; + } + } + } + + public Resource name(String name) { + for (WebElement row : resources().rows()) { + ResourceRepresentation actual = resources().toRepresentation(row); + if (actual.getName().equalsIgnoreCase(name)) { + row.findElements(tagName("a")).get(0).click(); + WaitUtils.waitForPageToLoad(driver); + return resource; + } + } + return null; + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/ResourcesTable.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/ResourcesTable.java new file mode 100644 index 0000000000..4f51cc92bb --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/resource/ResourcesTable.java @@ -0,0 +1,80 @@ +/* + * 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.resource; + +import static org.openqa.selenium.By.tagName; + +import java.util.ArrayList; +import java.util.List; + +import org.keycloak.representations.idm.authorization.ResourceOwnerRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; +import org.keycloak.testsuite.console.page.fragment.DataTable; +import org.openqa.selenium.WebElement; + +/** + * + * @author tkyjovsk + */ +public class ResourcesTable extends DataTable { + + public ResourceRepresentation findByName(String name) { + search(name); + List result = getTableRows(); + if (result.isEmpty()) { + return null; + } else { + assert 1 == result.size(); + return result.get(0); + } + } + + public boolean contains(String name) { + for (ResourceRepresentation representation : getTableRows()) { + if (name.equals(representation.getName())) { + return true; + } + } + return false; + } + + public List getTableRows() { + List rows = new ArrayList<>(); + for (WebElement row : rows()) { + ResourceRepresentation representation = toRepresentation(row); + if (representation != null) { + rows.add(representation); + } + } + return rows; + } + + public ResourceRepresentation toRepresentation(WebElement row) { + ResourceRepresentation representation = null; + List tds = row.findElements(tagName("td")); + if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) { + representation = new ResourceRepresentation(); + representation.setName(tds.get(0).getText()); + representation.setType(tds.get(1).getText()); + representation.setUri(tds.get(2).getText()); + ResourceOwnerRepresentation owner = new ResourceOwnerRepresentation(); + owner.setName(tds.get(3).getText()); + representation.setOwner(owner); + } + return representation; + } +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scope.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scope.java new file mode 100644 index 0000000000..6aef307843 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scope.java @@ -0,0 +1,32 @@ +/* + * 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.scope; + +import org.jboss.arquillian.graphene.page.Page; + +/** + * @author Pedro Igor + */ +public class Scope { + + @Page + private ScopeForm form; + + public ScopeForm form() { + return form; + } +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/ScopeForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/ScopeForm.java new file mode 100644 index 0000000000..e73c6cb4b1 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/ScopeForm.java @@ -0,0 +1,51 @@ +/* + * 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.scope; + +import org.keycloak.representations.idm.authorization.ScopeRepresentation; +import org.keycloak.testsuite.page.Form; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +/** + * @author tkyjovsk + */ +public class ScopeForm extends Form { + + @FindBy(id = "name") + private WebElement name; + + @FindBy(id = "iconUri") + private WebElement iconUri; + + @FindBy(xpath = "//i[contains(@class,'pficon-delete')]") + private WebElement deleteButton; + + @FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Delete']") + private WebElement confirmDelete; + + public void populate(ScopeRepresentation expected) { + setInputValue(name, expected.getName()); + setInputValue(iconUri, expected.getIconUri()); + save(); + } + + public void delete() { + deleteButton.click(); + confirmDelete.click(); + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java new file mode 100644 index 0000000000..b32f76a6db --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/Scopes.java @@ -0,0 +1,69 @@ +/* + * 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.scope; + +import static org.openqa.selenium.By.tagName; + +import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.representations.idm.authorization.ScopeRepresentation; +import org.keycloak.testsuite.page.Form; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +/** + * @author tkyjovsk + */ +public class Scopes extends Form { + + @FindBy(css = "table[class*='table']") + private ScopesTable table; + + @FindBy(linkText = "Create") + private WebElement create; + + @Page + private Scope scope; + + public ScopesTable scopes() { + return table; + } + + public void create(ScopeRepresentation representation) { + create.click(); + scope.form().populate(representation); + } + + public void update(String name, ScopeRepresentation representation) { + for (WebElement row : scopes().rows()) { + ScopeRepresentation actual = scopes().toRepresentation(row); + if (actual.getName().equalsIgnoreCase(name)) { + row.findElements(tagName("a")).get(0).click(); + scope.form().populate(representation); + } + } + } + + public void delete(String name) { + for (WebElement row : scopes().rows()) { + ScopeRepresentation actual = scopes().toRepresentation(row); + if (actual.getName().equalsIgnoreCase(name)) { + row.findElements(tagName("a")).get(0).click(); + scope.form().delete(); + } + } + } +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/ScopesTable.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/ScopesTable.java new file mode 100644 index 0000000000..ed90fe535d --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/authorization/scope/ScopesTable.java @@ -0,0 +1,74 @@ +/* + * 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.scope; + +import static org.openqa.selenium.By.tagName; + +import java.util.ArrayList; +import java.util.List; + +import org.keycloak.representations.idm.authorization.ScopeRepresentation; +import org.keycloak.testsuite.console.page.fragment.DataTable; +import org.openqa.selenium.WebElement; + +/** + * + * @author tkyjovsk + */ +public class ScopesTable extends DataTable { + + public ScopeRepresentation findByName(String name) { + search(name); + List result = getTableRows(); + if (result.isEmpty()) { + return null; + } else { + assert 1 == result.size(); + return result.get(0); + } + } + + public boolean contains(String name) { + for (ScopeRepresentation representation : getTableRows()) { + if (name.equals(representation.getName())) { + return true; + } + } + return false; + } + + public List getTableRows() { + List rows = new ArrayList<>(); + for (WebElement row : rows()) { + ScopeRepresentation representation = toRepresentation(row); + if (representation != null) { + rows.add(representation); + } + } + return rows; + } + + public ScopeRepresentation toRepresentation(WebElement row) { + ScopeRepresentation representation = null; + List tds = row.findElements(tagName("td")); + if (!(tds.isEmpty() || tds.get(0).getText().isEmpty())) { + representation = new ScopeRepresentation(); + representation.setName(tds.get(0).getText()); + } + return representation; + } +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java index a1d225a960..57f789e35c 100644 --- a/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java +++ b/testsuite/integration-arquillian/tests/other/console/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java @@ -67,6 +67,12 @@ public class ClientSettingsForm extends CreateClientForm { @FindBy(xpath = ".//button[contains(@data-ng-click, 'deleteWebOrigin')]") private List deleteWebOriginIcons; + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='authorizationServicesEnabled']]") + private OnOffSwitch authorizationSettingsEnabledSwitch; + + @FindBy(xpath = ACTIVE_DIV_XPATH + "/button[text()='Disable Authorization Settings']") + private WebElement confirmDisableAuthorizationSettingsButton; + public enum OidcAccessType { BEARER_ONLY("bearer-only"), PUBLIC("public"), CONFIDENTIAL("confidential"); @@ -212,6 +218,18 @@ public class ClientSettingsForm extends CreateClientForm { serviceAccountsEnabledSwitch.setOn(serviceAccountsEnabled); } + public void setAuthorizationSettingsEnabled(boolean enabled) { + authorizationSettingsEnabledSwitch.setOn(enabled); + } + + public boolean isAuthorizationSettingsEnabled() { + return authorizationSettingsEnabledSwitch.isOn(); + } + + public void confirmDisableAuthorizationSettings() { + confirmDisableAuthorizationSettingsButton.click(); + } + public class SAMLClientSettingsForm extends Form { public static final String SAML_ASSERTION_SIGNATURE = "saml.assertion.signature"; diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AbstractAuthorizationSettingsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AbstractAuthorizationSettingsTest.java new file mode 100644 index 0000000000..5bb5449c4c --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/AbstractAuthorizationSettingsTest.java @@ -0,0 +1,80 @@ +/* + * 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.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.keycloak.testsuite.auth.page.login.Login.OIDC; + +import org.jboss.arquillian.graphene.page.Page; +import org.junit.Before; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.testsuite.console.clients.AbstractClientTest; +import org.keycloak.testsuite.console.page.clients.authorization.Authorization; +import org.keycloak.testsuite.console.page.clients.settings.ClientSettings; +import org.openqa.selenium.By; + +/** + * @author Pedro Igor + */ +public abstract class AbstractAuthorizationSettingsTest extends AbstractClientTest { + + @Page + protected ClientSettings clientSettingsPage; + + @Page + protected Authorization authorizationPage; + + protected ClientRepresentation newClient; + + @Before + public void configureTest() { + this.newClient = createResourceServer(); + } + + private ClientRepresentation createResourceServer() { + ClientRepresentation newClient = createClientRep("oidc-confidetial", OIDC); + + createClient(newClient); + + newClient.setRedirectUris(TEST_REDIRECT_URIs); + newClient.setAuthorizationServicesEnabled(true); + + clientSettingsPage.form().setRedirectUris(TEST_REDIRECT_URIs); + clientSettingsPage.form().setAuthorizationSettingsEnabled(true); + clientSettingsPage.form().save(); + assertAlertSuccess(); + + ClientRepresentation found = findClientByClientId(newClient.getClientId()); + assertNotNull("Client " + newClient.getClientId() + " was not found.", found); + + newClient.setPublicClient(false); + newClient.setServiceAccountsEnabled(true); + + assertClientSettingsEqual(newClient, found); + assertTrue(clientSettingsPage.tabs().getTabs().findElement(By.linkText("Authorization")).isDisplayed()); + + clientSettingsPage.setId(found.getId()); + clientSettingsPage.navigateTo(); + authorizationPage.setId(found.getId()); + + clientSettingsPage.tabs().authorization(); + assertTrue(authorizationPage.isCurrent()); + + return newClient; + } +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DefaultAuthorizationSettingsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DefaultAuthorizationSettingsTest.java new file mode 100644 index 0000000000..f4b5b68595 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DefaultAuthorizationSettingsTest.java @@ -0,0 +1,69 @@ +/* + * 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.assertTrue; + +import org.junit.Test; +import org.keycloak.representations.adapters.config.PolicyEnforcerConfig; +import org.keycloak.representations.idm.authorization.PolicyRepresentation; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; +import org.keycloak.testsuite.console.page.clients.authorization.AuthorizationSettingsForm; +import org.keycloak.testsuite.console.page.clients.authorization.permission.Permissions; +import org.keycloak.testsuite.console.page.clients.authorization.policy.Policies; +import org.keycloak.testsuite.console.page.clients.authorization.resource.Resources; +import org.keycloak.testsuite.console.page.clients.authorization.scope.Scopes; + +/** + * @author Pedro Igor + */ +public class DefaultAuthorizationSettingsTest extends AbstractAuthorizationSettingsTest { + + @Test + public void testDefaultSettings() { + AuthorizationSettingsForm settings = authorizationPage.settings(); + + assertEquals(PolicyEnforcerConfig.EnforcementMode.ENFORCING, settings.getEnforcementMode()); + assertEquals(false, settings.isAllowRemoteResourceManagement()); + + Resources resources = authorizationPage.authorizationTabs().resources(); + ResourceRepresentation resource = resources.resources().findByName("Default Resource"); + + assertNotNull(resource); + assertEquals("urn:oidc-confidetial:resources:default", resource.getType()); + assertEquals("/*", resource.getUri()); + assertEquals(newClient.getClientId(), resource.getOwner().getName()); + + Scopes scopes = authorizationPage.authorizationTabs().scopes(); + + assertTrue(scopes.scopes().getTableRows().isEmpty()); + + Permissions permissions = authorizationPage.authorizationTabs().permissions(); + PolicyRepresentation permission = permissions.permissions().findByName("Default Permission"); + + assertNotNull(permission); + assertEquals("resource", permission.getType()); + + Policies policies = authorizationPage.authorizationTabs().policies(); + PolicyRepresentation policy = policies.policies().findByName("Default Policy"); + + assertNotNull(policy); + assertEquals("js", policy.getType()); + } +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DisableAuthorizationSettingsTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DisableAuthorizationSettingsTest.java new file mode 100644 index 0000000000..3e3359e6db --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/DisableAuthorizationSettingsTest.java @@ -0,0 +1,40 @@ +/* + * 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.assertFalse; + +import org.junit.Test; + +/** + * @author Pedro Igor + */ +public class DisableAuthorizationSettingsTest extends AbstractAuthorizationSettingsTest { + + @Test + public void testDisableAuthorization() throws InterruptedException { + clientSettingsPage.navigateTo(); + clientSettingsPage.form().setAuthorizationSettingsEnabled(false); + clientSettingsPage.form().confirmDisableAuthorizationSettings(); + Thread.sleep(1000); + clientSettingsPage.form().save(); + assertAlertSuccess(); + + clientSettingsPage.navigateTo(); + assertFalse(clientSettingsPage.form().isAuthorizationSettingsEnabled()); + } +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourceManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourceManagementTest.java new file mode 100644 index 0000000000..75a479ad7b --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ResourceManagementTest.java @@ -0,0 +1,120 @@ +/* + * 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 static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +import org.junit.Before; +import org.junit.Test; +import org.keycloak.representations.idm.authorization.ResourceRepresentation; +import org.keycloak.representations.idm.authorization.ScopeRepresentation; +import org.keycloak.testsuite.console.page.clients.authorization.resource.Resource; + +/** + * @author Pedro Igor + */ +public class ResourceManagementTest extends AbstractAuthorizationSettingsTest { + + @Before + @Override + public void configureTest() { + super.configureTest(); + for (String scopeName : Arrays.asList("Scope A", "Scope B", "Scope C")) { + authorizationPage.navigateTo(); + authorizationPage.authorizationTabs().scopes().create(new ScopeRepresentation(scopeName)); + } + authorizationPage.navigateTo(); + } + + @Test + public void testUpdate() { + ResourceRepresentation expected = createResource(); + String previousName = expected.getName(); + + expected.setName("changed"); + expected.setType("changed"); + expected.setUri("changed"); + expected.setScopes(Arrays.asList("Scope A", "Scope B", "Scope C").stream().map(name -> new ScopeRepresentation(name)).collect(Collectors.toSet())); + + authorizationPage.navigateTo(); + Resource resource = authorizationPage.authorizationTabs().resources().name(previousName); + resource.update(expected); + assertAlertSuccess(); + assertResource(expected); + + expected.setScopes(expected.getScopes().stream().filter(scope -> scope.getName().equals("Scope C")).collect(Collectors.toSet())); + + authorizationPage.navigateTo(); + authorizationPage.authorizationTabs().resources().update(expected.getName(), expected); + assertAlertSuccess(); + assertResource(expected); + } + + @Test + public void testDelete() { + ResourceRepresentation expected = createResource(); + authorizationPage.navigateTo(); + authorizationPage.authorizationTabs().resources().delete(expected.getName()); + authorizationPage.navigateTo(); + assertNull(authorizationPage.authorizationTabs().resources().resources().findByName(expected.getName())); + } + + private ResourceRepresentation createResource() { + ResourceRepresentation expected = new ResourceRepresentation(); + + expected.setName("Test Resource"); + expected.setType("Test Type"); + expected.setUri("/test/resource"); + + authorizationPage.authorizationTabs().resources().create(expected); + assertAlertSuccess(); + + return expected; + } + + private void assertResource(ResourceRepresentation expected) { + authorizationPage.navigateTo(); + ResourceRepresentation actual = authorizationPage.authorizationTabs().resources().resources().findByName(expected.getName()); + + assertEquals(expected.getName(), actual.getName()); + assertEquals(expected.getType(), actual.getType()); + assertEquals(expected.getUri(), actual.getUri()); + assertEquals(expected.getIconUri(), actual.getIconUri()); + + ResourceRepresentation resource = authorizationPage.authorizationTabs().resources().name(expected.getName()).toRepresentation(); + Set associatedScopes = resource.getScopes(); + + if (expected.getScopes() != null) { + assertNotNull(associatedScopes); + assertEquals(expected.getScopes().size(), associatedScopes.size()); + assertEquals(0, resource.getScopes().stream().filter(actualScope -> !expected.getScopes().stream() + .filter(expectedScope -> actualScope.getName().equals(expectedScope.getName())) + .findFirst().isPresent()) + .count()); + } else { + assertTrue(associatedScopes.isEmpty()); + } + + } +} diff --git a/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopeManagementTest.java b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopeManagementTest.java new file mode 100644 index 0000000000..84a5c42766 --- /dev/null +++ b/testsuite/integration-arquillian/tests/other/console/src/test/java/org/keycloak/testsuite/console/authorization/ScopeManagementTest.java @@ -0,0 +1,70 @@ +/* + * 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.ScopeRepresentation; + +/** + * @author Pedro Igor + */ +public class ScopeManagementTest extends AbstractAuthorizationSettingsTest { + + @Test + public void testUpdate() { + ScopeRepresentation expected = createScope(); + String previousName = expected.getName(); + + expected.setName("changed"); + + authorizationPage.navigateTo(); + authorizationPage.authorizationTabs().scopes().update(previousName, expected); + assertAlertSuccess(); + assertScope(expected); + } + + @Test + public void testDelete() { + ScopeRepresentation expected = createScope(); + authorizationPage.navigateTo(); + authorizationPage.authorizationTabs().scopes().delete(expected.getName()); + authorizationPage.navigateTo(); + assertNull(authorizationPage.authorizationTabs().scopes().scopes().findByName(expected.getName())); + } + + private ScopeRepresentation createScope() { + ScopeRepresentation expected = new ScopeRepresentation(); + + expected.setName("Test Scope"); + + authorizationPage.authorizationTabs().scopes().create(expected); + assertAlertSuccess(); + + return expected; + } + + private void assertScope(ScopeRepresentation expected) { + authorizationPage.navigateTo(); + ScopeRepresentation actual = authorizationPage.authorizationTabs().scopes().scopes().findByName(expected.getName()); + + assertEquals(expected.getName(), actual.getName()); + assertEquals(expected.getIconUri(), actual.getIconUri()); + } +} diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-resource-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-resource-detail.html index 7187c22945..e3bda1e507 100644 --- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-resource-detail.html +++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-resource-detail.html @@ -44,10 +44,10 @@ {{:: 'authz-resource-uri.tooltip' | translate}}
- +
- +
{{:: 'authz-resource-scopes.tooltip' | translate}} diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-scope-detail.html b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-scope-detail.html index 6bfadfe86f..a505bbcd23 100644 --- a/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-scope-detail.html +++ b/themes/src/main/resources/theme/base/admin/resources/partials/authz/resource-server-scope-detail.html @@ -25,7 +25,7 @@
- +
{{:: 'authz-icon-uri.tooltip' | translate}}
diff --git a/themes/src/main/resources/theme/base/admin/resources/templates/authz/kc-tabs-resource-server.html b/themes/src/main/resources/theme/base/admin/resources/templates/authz/kc-tabs-resource-server.html index 4b24d3fd85..0491364b81 100755 --- a/themes/src/main/resources/theme/base/admin/resources/templates/authz/kc-tabs-resource-server.html +++ b/themes/src/main/resources/theme/base/admin/resources/templates/authz/kc-tabs-resource-server.html @@ -2,7 +2,7 @@ -