diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html index 91f909f2c8..e3ae1aa839 100644 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-clustering-node.html @@ -17,7 +17,7 @@
- +
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html index 6c4801652c..cd63f49afe 100755 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-scope-mappings.html @@ -76,9 +76,9 @@
- + {{:: 'assign.available-roles.tooltip' | translate}} - diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-service-account-roles.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-service-account-roles.html index bb38c6a62a..bc552daf86 100644 --- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-service-account-roles.html +++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/client-service-account-roles.html @@ -65,9 +65,9 @@
- + {{:: 'assign.available-roles.tooltip' | translate}} - diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java index 783cd0bc06..bb70843df8 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Client.java @@ -1,5 +1,6 @@ package org.keycloak.testsuite.console.page.clients; +import org.jboss.arquillian.graphene.fragment.Root; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.testsuite.console.page.fragment.Breadcrumb; import static org.keycloak.testsuite.console.page.fragment.Breadcrumb.BREADCRUMB_XPATH; @@ -55,6 +56,9 @@ public class Client extends Clients { public class ClientTabs { + @Root + private WebElement tabs; + @FindBy(linkText = "Settings") private WebElement settingsLink; @FindBy(linkText = "Roles") @@ -97,6 +101,10 @@ public class Client extends Clients { public void installation() { installationLink.click(); } + + public WebElement getTabs() { + return tabs; + } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientClustering.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientClustering.java deleted file mode 100644 index cdc8d6b0c4..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientClustering.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.keycloak.testsuite.console.page.clients; - -/** - * - * @author tkyjovsk - */ -public class ClientClustering extends Client { - - @Override - public String getUriFragment() { - return super.getUriFragment() + "/clustering"; - } - -} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientCredentials.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientCredentials.java deleted file mode 100644 index 08a3523159..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientCredentials.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.keycloak.testsuite.console.page.clients; - -/** - * - * @author tkyjovsk - */ -public class ClientCredentials extends Client { - - @Override - public String getUriFragment() { - return super.getUriFragment() + "/credentials"; - } - -} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientInstallation.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientInstallation.java deleted file mode 100644 index 65c1c6c758..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientInstallation.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.keycloak.testsuite.console.page.clients; - -/** - * - * @author tkyjovsk - */ -public class ClientInstallation extends Client { - - @Override - public String getUriFragment() { - return super.getUriFragment() + "/installation"; - } - -} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientRevocation.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientRevocation.java deleted file mode 100644 index fb161a89a4..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientRevocation.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.keycloak.testsuite.console.page.clients; - -/** - * - * @author tkyjovsk - */ -public class ClientRevocation extends Client { - - @Override - public String getUriFragment() { - return super.getUriFragment() + "/revocation"; - } - -} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientScopeMappings.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientScopeMappings.java deleted file mode 100644 index 32107fd229..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientScopeMappings.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.keycloak.testsuite.console.page.clients; - -/** - * - * @author tkyjovsk - */ -public class ClientScopeMappings extends Client { - - @Override - public String getUriFragment() { - return super.getUriFragment() + "/scope-mappings"; - } - -} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSessions.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSessions.java deleted file mode 100644 index eae5013200..0000000000 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSessions.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.keycloak.testsuite.console.page.clients; - -/** - * - * @author tkyjovsk - */ -public class ClientSessions extends Client { - - @Override - public String getUriFragment() { - return super.getUriFragment() + "/sessions"; - } - -} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java index 494b3fe748..58fac4dfbc 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/Clients.java @@ -126,11 +126,6 @@ public class Clients extends AdminConsoleRealm { } } - public void deleteClient(String clientId) { - clientsTable.searchClients(clientId); - clientsTable.deleteClient(clientId); - } - public ClientsResource clientsResource() { return realmResource().clients(); } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientForm.java index 88e6ed5482..8182638316 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientForm.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientForm.java @@ -2,13 +2,15 @@ package org.keycloak.testsuite.console.page.clients; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import org.jboss.arquillian.graphene.page.Page; import org.keycloak.representations.idm.ClientRepresentation; import static org.keycloak.testsuite.auth.page.login.OIDCLogin.OIDC; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.*; import org.keycloak.testsuite.console.page.fragment.OnOffSwitch; import org.keycloak.testsuite.page.Form; import static org.keycloak.testsuite.page.Form.getInputValue; -import static org.keycloak.testsuite.util.WaitUtils.pause; -import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement; +import static org.keycloak.testsuite.util.WaitUtils.*; import org.keycloak.testsuite.util.Timer; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; @@ -43,10 +45,8 @@ public class CreateClientForm extends Form { @FindBy(id = "protocol") private Select protocolSelect; - @FindBy(id = "protocol") - private WebElement protocolSelectElement; - - @FindBy + + @Page private SAMLClientSettingsForm samlForm; public SAMLClientSettingsForm samlForm() { @@ -55,14 +55,13 @@ public class CreateClientForm extends Form { @FindBy(id = "accessType") private Select accessTypeSelect; - @FindBy(id = "accessType") - private WebElement accessTypeSelectElement; - @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='serviceAccountsEnabled']]") private OnOffSwitch serviceAccountsEnabledSwitch; @FindBy(id = "newRedirectUri") private WebElement newRedirectUriInput; + @FindBy(xpath = ".//i[contains(@data-ng-click, 'newRedirectUri')]") + private WebElement newRedirectUriSubmit; @FindBy(xpath = ".//input[@ng-model='client.redirectUris[i]']") private List redirectUriInputs; @FindBy(xpath = ".//i[contains(@data-ng-click, 'deleteRedirectUri')]") @@ -75,42 +74,22 @@ public class CreateClientForm extends Form { setName(client.getName()); setEnabled(client.isEnabled()); setConsentRequired(client.isConsentRequired()); - setStandardFlowEnabled(client.isStandardFlowEnabled()); - setImplicitFlowEnabled(client.isImplicitFlowEnabled()); - setDirectAccessGrantsEnabled(client.isDirectAccessGrantsEnabled()); setProtocol(client.getProtocol()); if (OIDC.equals(client.getProtocol())) { setAccessType(client); if (!client.isBearerOnly()) { - if (!client.isPublicClient()) { + setStandardFlowEnabled(client.isStandardFlowEnabled()); + setDirectAccessGrantsEnabled(client.isDirectAccessGrantsEnabled()); + if (client.isPublicClient()) { + setImplicitFlowEnabled(client.isImplicitFlowEnabled()); + } else {//confidential setServiceAccountsEnabled(client.isServiceAccountsEnabled()); } - setRedirectUris(client.getRedirectUris()); - } - } - } - - public ClientRepresentation getValues() { - ClientRepresentation values = new ClientRepresentation(); - values.setClientId(getClientId()); - values.setName(getName()); - values.setEnabled(isEnabled()); - values.setConsentRequired(isConsentRequired()); - values.setStandardFlowEnabled(isStandardFlowEnabled()); - values.setImplicitFlowEnabled(isImplicitFlowEnabled()); - values.setDirectAccessGrantsEnabled(isDirectAccessGrantsEnabled()); - values.setProtocol(getProtocol()); - if (OIDC.equals(values.getProtocol())) { - values.setBearerOnly(isBearerOnly()); - if (!values.isBearerOnly()) { - values.setPublicClient(isPublicClient()); - if (!values.isPublicClient()) { - values.setServiceAccountsEnabled(isServiceAccountsEnabled()); + if (client.isStandardFlowEnabled() || client.isImplicitFlowEnabled()) { + setRedirectUris(client.getRedirectUris()); } - values.setRedirectUris(getRedirectUris()); } } - return values; } public String getClientId() { @@ -137,40 +116,35 @@ public class CreateClientForm extends Form { enabledSwitch.setOn(enabled); } - public static final String BEARER_ONLY = "bearer-only"; - public static final String PUBLIC = "public"; - public static final String CONFIDENTIAL = "confidential"; + public enum OidcAccessType { + BEARER_ONLY("bearer-only"), + PUBLIC("public"), + CONFIDENTIAL("confidential"); + + private final String name; - public boolean isBearerOnly() { - return BEARER_ONLY.equals( - accessTypeSelect.getFirstSelectedOption().getAttribute(VALUE)); + private OidcAccessType(String name) { + this.name = name; + } + + public String getName() { + return name; + } } - - public boolean isPublicClient() { - return PUBLIC.equals( - accessTypeSelect.getFirstSelectedOption().getAttribute(VALUE)); - } - - public void setBearerOnly(boolean bearerOnly) { - accessTypeSelectElement.sendKeys(BEARER_ONLY); -// accessTypeSelect.selectByVisibleText(BEARER_ONLY); - } - - public void setPublicClient(boolean publicClient) { - accessTypeSelectElement.sendKeys(PUBLIC); -// accessTypeSelect.selectByVisibleText(PUBLIC); - } - - public void setAccessType(ClientRepresentation client) { // TODO verify - setBearerOnly(client.isBearerOnly()); - setPublicClient(client.isPublicClient()); - if (!client.isBearerOnly() && !client.isPublicClient()) { - accessTypeSelect.selectByVisibleText(CONFIDENTIAL); + + public void setAccessType(ClientRepresentation client) { + if (client.isBearerOnly()) { + accessTypeSelect.selectByVisibleText(BEARER_ONLY.getName()); + } else if (client.isPublicClient()) { + accessTypeSelect.selectByVisibleText(PUBLIC.getName()); + } else { + accessTypeSelect.selectByVisibleText(CONFIDENTIAL.getName()); } } public void addRedirectUri(String redirectUri) { newRedirectUriInput.sendKeys(redirectUri); + newRedirectUriSubmit.click(); } public List getRedirectUris() { @@ -236,7 +210,7 @@ public class CreateClientForm extends Form { public void setProtocol(String protocol) { Timer.time(); - protocolSelectElement.sendKeys(protocol); + protocolSelect.selectByVisibleText(protocol); Timer.time("clientSettings.setProtocol()"); } @@ -250,7 +224,83 @@ public class CreateClientForm extends Form { public class SAMLClientSettingsForm extends Form { - // TODO add SAML client attributes + public static final String SAML_ASSERTION_SIGNATURE = "saml.assertion.signature"; + public static final String SAML_AUTHNSTATEMENT = "saml.authnstatement"; + public static final String SAML_CLIENT_SIGNATURE = "saml.client.signature"; + public static final String SAML_ENCRYPT = "saml.encrypt"; + public static final String SAML_FORCE_POST_BINDING = "saml.force.post.binding"; + public static final String SAML_MULTIVALUED_ROLES = "saml.multivalued.roles"; + public static final String SAML_SERVER_SIGNATURE = "saml.server.signature"; + public static final String SAML_SIGNATURE_ALGORITHM = "saml.signature.algorithm"; + public static final String SAML_ASSERTION_CONSUMER_URL_POST = "saml_assertion_consumer_url_post"; + public static final String SAML_ASSERTION_CONSUMER_URL_REDIRECT = "saml_assertion_consumer_url_redirect"; + public static final String SAML_FORCE_NAME_ID_FORMAT = "saml_force_name_id_format"; + public static final String SAML_NAME_ID_FORMAT = "saml_name_id_format"; + public static final String SAML_SIGNATURE_CANONICALIZATION_METHOD = "saml_signature_canonicalization_method"; + public static final String SAML_SINGLE_LOGOUT_SERVICE_URL_POST = "saml_single_logout_service_url_post"; + public static final String SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT = "saml_single_logout_service_url_redirect"; + + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlAuthnStatement']]") + private OnOffSwitch samlAuthnStatement; + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlServerSignature']]") + private OnOffSwitch samlServerSignature; + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlAssertionSignature']]") + private OnOffSwitch samlAssertionSignature; + @FindBy(id = "signatureAlgorithm") + private Select signatureAlgorithm; + @FindBy(id = "canonicalization") + private Select canonicalization; + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlEncrypt']]") + private OnOffSwitch samlEncrypt; + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlClientSignature']]") + private OnOffSwitch samlClientSignature; + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlForcePostBinding']]") + private OnOffSwitch samlForcePostBinding; + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='frontchannelLogout']]") + private OnOffSwitch frontchannelLogout; + @FindBy(xpath = ".//div[@class='onoffswitch' and ./input[@id='samlForceNameIdFormat']]") + private OnOffSwitch samlForceNameIdFormat; + @FindBy(id = "samlNameIdFormat") + private Select samlNameIdFormat; + + @FindBy(xpath = "//fieldset[contains(@data-ng-show, 'saml')]//i") + private WebElement fineGrainCollapsor; + + @FindBy(id = "consumerServicePost") + private WebElement consumerServicePostInput; + @FindBy(id = "consumerServiceRedirect") + private WebElement consumerServiceRedirectInput; + @FindBy(id = "logoutPostBinding") + private WebElement logoutPostBindingInput; + @FindBy(id = "logoutRedirectBinding") + private WebElement logoutRedirectBindingInput; + + public void setValues(ClientRepresentation client) { + waitUntilElement(fineGrainCollapsor).is().visible(); + + Map attributes = client.getAttributes(); + samlAuthnStatement.setOn("true".equals(attributes.get(SAML_AUTHNSTATEMENT))); + samlServerSignature.setOn("true".equals(attributes.get(SAML_SERVER_SIGNATURE))); + samlAssertionSignature.setOn("true".equals(attributes.get(SAML_ASSERTION_SIGNATURE))); + if (samlServerSignature.isOn() || samlAssertionSignature.isOn()) { + signatureAlgorithm.selectByVisibleText(attributes.get(SAML_SIGNATURE_ALGORITHM)); + canonicalization.selectByValue("string:" + attributes.get(SAML_SIGNATURE_CANONICALIZATION_METHOD)); + } + samlEncrypt.setOn("true".equals(attributes.get(SAML_ENCRYPT))); + samlClientSignature.setOn("true".equals(attributes.get(SAML_CLIENT_SIGNATURE))); + samlForcePostBinding.setOn("true".equals(attributes.get(SAML_FORCE_POST_BINDING))); + frontchannelLogout.setOn(client.isFrontchannelLogout()); + samlForceNameIdFormat.setOn("true".equals(attributes.get(SAML_FORCE_NAME_ID_FORMAT))); + samlNameIdFormat.selectByVisibleText(attributes.get(SAML_NAME_ID_FORMAT)); + + fineGrainCollapsor.click(); + waitUntilElement(consumerServicePostInput).is().present(); + + setInputValue(consumerServicePostInput, attributes.get(SAML_ASSERTION_CONSUMER_URL_POST)); + setInputValue(consumerServiceRedirectInput, attributes.get(SAML_ASSERTION_CONSUMER_URL_REDIRECT)); + setInputValue(logoutPostBindingInput, attributes.get(SAML_SINGLE_LOGOUT_SERVICE_URL_POST)); + setInputValue(logoutRedirectBindingInput, attributes.get(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT)); + } } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/clustering/ClientClustering.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/clustering/ClientClustering.java new file mode 100644 index 0000000000..34c2bdfc9d --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/clustering/ClientClustering.java @@ -0,0 +1,24 @@ +package org.keycloak.testsuite.console.page.clients.clustering; + +import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.testsuite.console.page.clients.Client; + +/** + * + * @author tkyjovsk + */ +public class ClientClustering extends Client { + + @Override + public String getUriFragment() { + return super.getUriFragment() + "/clustering"; + } + + @Page + private ClientClusteringForm clientClusteringForm; + + public ClientClusteringForm form() { + return clientClusteringForm; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/clustering/ClientClusteringForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/clustering/ClientClusteringForm.java new file mode 100644 index 0000000000..e8e27485bd --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/clustering/ClientClusteringForm.java @@ -0,0 +1,66 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.page.clients.clustering; + +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 Vlastislav Ramik + */ +public class ClientClusteringForm extends Form { + + @FindBy(id = "nodeReRegistrationTimeout") + private WebElement nodeReRegistrationTimeoutInput; + + @FindBy(xpath = ".//select") + private Select nodeReRegistrationTimeoutUnitSelect; + + @FindBy(linkText = "Register node manually") + private WebElement registerNodeManuallyLink; + + @FindBy(id = "host") + private WebElement hostNameInput; + + private void setNodeReRegistrationTimeout(String value) { + setInputValue(nodeReRegistrationTimeoutInput, value); + } + + private void setNodeReRegistrationTimeoutUnit(String value) { + nodeReRegistrationTimeoutUnitSelect.selectByVisibleText(value); + } + + public void setNodeReRegistrationTimeout(String timeout, String unit) { + setNodeReRegistrationTimeoutUnit(unit); + setNodeReRegistrationTimeout(timeout); + } + + public void addNode(String hostName) { + registerNodeManuallyLink.click(); +// waitforElement(hostNameInput); + setInputValue(hostNameInput, hostName); + save(); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentials.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentials.java new file mode 100644 index 0000000000..d6a874f77a --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentials.java @@ -0,0 +1,24 @@ +package org.keycloak.testsuite.console.page.clients.credentials; + +import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.testsuite.console.page.clients.Client; + +/** + * + * @author tkyjovsk + */ +public class ClientCredentials extends Client { + + @Override + public String getUriFragment() { + return super.getUriFragment() + "/credentials"; + } + + @Page + private ClientCredentialsForm form; + + public ClientCredentialsForm form() { + return form; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsForm.java new file mode 100644 index 0000000000..991b175d2c --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsForm.java @@ -0,0 +1,66 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.page.clients.credentials; + +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 Vlastislav Ramik + */ +public class ClientCredentialsForm extends Form { + + @FindBy(id = "clientAuthenticatorType") + private Select clientAuthenticatorType; + + @FindBy(xpath = "//button[text()='Regenerate Secret']") + private WebElement regenerateSecretButton; + + @FindBy(xpath = "//button[text()='Generate new keys and certificate']") + private WebElement generateNewKeysAndCert; + + @FindBy(xpath = "//button[text()='Regenerate registration access token']") + private WebElement regenerateRegistrationAccessTokenButton; + + public void selectClientIdAndSecret() { + clientAuthenticatorType.selectByVisibleText("Client Id and Secret"); + } + + public void selectSignedJwt() { + clientAuthenticatorType.selectByVisibleText("Signed Jwt"); + } + + public void regenerateSecret() { + regenerateSecretButton.click(); + } + + public void regenerateRegistrationAccessToken() { + regenerateRegistrationAccessTokenButton.click(); + } + + public void generateNewKeysAndCert() { + generateNewKeysAndCert.click(); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsGeneratePrivateKeys.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsGeneratePrivateKeys.java new file mode 100644 index 0000000000..808ade622e --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsGeneratePrivateKeys.java @@ -0,0 +1,44 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.page.clients.credentials; + +import org.jboss.arquillian.graphene.page.Page; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientCredentialsGeneratePrivateKeys extends ClientCredentials { + + @Override + public String getUriFragment() { + return super.getUriFragment() + "/client-jwt/Signing/export/jwt.credential"; + } + + @Page + private ClientCredentialsGeneratePrivateKeysForm form; + + public ClientCredentialsGeneratePrivateKeysForm generateForm() { + return form; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsGeneratePrivateKeysForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsGeneratePrivateKeysForm.java new file mode 100644 index 0000000000..1994c0af80 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/credentials/ClientCredentialsGeneratePrivateKeysForm.java @@ -0,0 +1,73 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.page.clients.credentials; + +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 Vlastislav Ramik + */ +public class ClientCredentialsGeneratePrivateKeysForm extends Form { + + @FindBy(id = "downloadKeyFormat") + private Select downloadKeyFormat; + + @FindBy(id = "keyAlias") + private WebElement keyAliasInput; + + @FindBy(id = "keyPassword") + private WebElement keyPasswordInput; + + @FindBy(id = "storePassword") + private WebElement storePasswordInput; + + @FindBy(xpath = "//button[text()='Generate and Download']") + private WebElement generateAndDownloadButton; + + public void selectFormatJKS() { + downloadKeyFormat.selectByVisibleText("JKS"); + } + + public void selectFormatPKCS12() { + downloadKeyFormat.selectByVisibleText("PKCS12"); + } + + public void setKeyAlias(String value) { + setInputValue(keyAliasInput, value); + } + + public void setKeyPassword(String value) { + setInputValue(keyPasswordInput, value); + } + + public void setStorePassword(String value) { + setInputValue(storePasswordInput, value); + } + + public void clickGenerateAndDownload() { + generateAndDownloadButton.click(); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallation.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallation.java new file mode 100644 index 0000000000..0f665d6db0 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallation.java @@ -0,0 +1,24 @@ +package org.keycloak.testsuite.console.page.clients.installation; + +import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.testsuite.console.page.clients.Client; + +/** + * + * @author tkyjovsk + */ +public class ClientInstallation extends Client { + + @Override + public String getUriFragment() { + return super.getUriFragment() + "/installation"; + } + + @Page + private ClientInstallationForm form; + + public ClientInstallationForm form() { + return form; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallationForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallationForm.java new file mode 100644 index 0000000000..6ed4d9e3ab --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/installation/ClientInstallationForm.java @@ -0,0 +1,48 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.page.clients.installation; + +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 Vlastislav Ramik + */ +public class ClientInstallationForm extends Form { + + @FindBy(id = "configFormats") + private Select configFormatsSelect; + + @FindBy(tagName = "textarea") + private WebElement textarea; + + public void setConfigFormat(String value) { + configFormatsSelect.selectByVisibleText(value); + } + + public String getTextareaContent() { + return textarea.getText(); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/ClientMapper.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/ClientMapper.java new file mode 100644 index 0000000000..35df86663f --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/ClientMapper.java @@ -0,0 +1,63 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.page.clients.mappers; + +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientMapper extends ClientMappers { + + public static final String MAPPER_ID = "mapperId"; + + @FindBy(xpath = "//i[contains(@class, 'delete')]") + private WebElement deleteIcon; + + @FindBy(tagName = "form") + private MapperSettingsForm form; + + @Override + public String getUriFragment() { + return super.getUriFragment() + "/{" + MAPPER_ID + "}"; + } + + public void setMapperId(String id) { + setUriParameter(MAPPER_ID, id); + } + + public String getMapperId() { + return getUriParameter(MAPPER_ID).toString(); + } + + @Override + public void delete() { + deleteIcon.click(); + modalDialog.confirmDeletion(); + } + + public MapperSettingsForm form() { + return form; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientMappers.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/ClientMappers.java similarity index 86% rename from testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientMappers.java rename to testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/ClientMappers.java index cff0c2339e..20634b7c55 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientMappers.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/ClientMappers.java @@ -1,4 +1,4 @@ -package org.keycloak.testsuite.console.page.clients; +package org.keycloak.testsuite.console.page.clients.mappers; import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.testsuite.console.page.fragment.DataTable; @@ -8,6 +8,7 @@ import org.openqa.selenium.support.FindBy; import java.util.ArrayList; import java.util.List; +import org.keycloak.testsuite.console.page.clients.Client; /** * @@ -32,6 +33,9 @@ public class ClientMappers extends Client { public class ClientMapperTable extends DataTable { + @FindBy(xpath = "//button[text() = 'Add selected']") + private WebElement addSelectedButton; + public List searchMappings(String searchPattern) { search(searchPattern); return getMappingsFromRows(); @@ -80,6 +84,14 @@ public class ClientMappers extends Client { public void deleteMapper(ProtocolMapperRepresentation mapper) { clickMapperActionButton(mapper, DELETE); } + + public void checkBuiltinMapper(String mapperName) { + body().findElement(By.xpath("//td[text() = '" + mapperName + "']/..//input")).click(); + } + + public void clickAddSelectedBuiltinMapper() { + addSelectedButton.click(); + } public ProtocolMapperRepresentation getMappingFromRow(WebElement row) { if (!row.isDisplayed()) {return null;} // Is that necessary? @@ -96,7 +108,7 @@ public class ClientMappers extends Client { } public List getMappingsFromRows() { - List mappings = new ArrayList(); + List mappings = new ArrayList<>(); for (WebElement row : rows()) { ProtocolMapperRepresentation mapperRepresentation = getMappingFromRow(row); diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientMappers.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappers.java similarity index 87% rename from testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientMappers.java rename to testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappers.java index 962e7a51a1..aafe131295 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientMappers.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappers.java @@ -1,4 +1,4 @@ -package org.keycloak.testsuite.console.page.clients; +package org.keycloak.testsuite.console.page.clients.mappers; import org.jboss.arquillian.graphene.page.Page; import org.keycloak.testsuite.console.page.AdminConsoleCreate; diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientMappersForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappersForm.java similarity index 51% rename from testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientMappersForm.java rename to testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappersForm.java index 900b4d207a..fb4dacf4c5 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientMappersForm.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/CreateClientMappersForm.java @@ -1,20 +1,14 @@ -package org.keycloak.testsuite.console.page.clients; +package org.keycloak.testsuite.console.page.clients.mappers; -import org.jboss.arquillian.test.api.ArquillianResource; import org.keycloak.testsuite.console.page.fragment.OnOffSwitch; import org.keycloak.testsuite.page.Form; -import org.openqa.selenium.By; import org.openqa.selenium.WebElement; -import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.ui.Select; -import java.util.List; /** * @author Vaclav Muzikar - * - * TODO: SAML */ public class CreateClientMappersForm extends Form { @@ -27,7 +21,16 @@ public class CreateClientMappersForm extends Form { public static final String USERS_FULL_NAME = "User's full name"; public static final String USER_ATTRIBUTE = "User Attribute"; public static final String USER_PROPERTY = "User Property"; + public static final String GROUP_MEMBERSHIP = "Group Membership"; + public static final String ROLE_LIST = "Role list"; + public static final String HARDCODED_ATTRIBUTE = "Hardcoded attribute"; + public static final String GROUP_LIST = "Group list"; + public static final String HARDCODED_ROLE_SAML = "Hardcoded role"; + // Role types + public static final String REALM_ROLE = "realm"; + public static final String CLIENT_ROLE = "client"; + @FindBy(id = "name") private WebElement nameElement; @@ -52,7 +55,7 @@ public class CreateClientMappersForm extends Form { @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Multivalued']//following-sibling::node()//div[@class='onoffswitch']") private OnOffSwitch multivaluedInput; - @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Role']//following-sibling::node()//input[@type='text']") + @FindBy(xpath = ".//button[text() = 'Select Role']/../..//input") private WebElement roleInput; @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='New Role Name']//following-sibling::node()//input[@type='text']") @@ -72,7 +75,74 @@ public class CreateClientMappersForm extends Form { @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Add to access token']//following-sibling::node()//div[@class='onoffswitch']") private OnOffSwitch addToAccessTokenInput; + + @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Full group path']//following-sibling::node()//div[@class='onoffswitch']") + private OnOffSwitch fullGroupPath; + @FindBy(xpath = ".//button[text() = 'Select Role']") + private WebElement selectRoleButton; + + @FindBy(xpath = "//div[@class='modal-dialog']") + private RoleSelectorModalDialog roleSelectorModalDialog; + + public class RoleSelectorModalDialog { + @FindBy(id = "available") + private Select realmAvailable; + @FindBy(xpath = ".//button[@tooltip='Select realm role']") + private WebElement selectRealmRoleButton; + + @FindBy(id = "available-client") + private Select clientAvailable; + @FindBy(id = "clients") + private Select clientSelect; + @FindBy(xpath = ".//button[@tooltip='Select client role']") + private WebElement selectClientRoleButton; + @FindBy(xpath = ".//button[@class='close']") + private WebElement closeButton; + + public void closeRoleSelectorModalDialog() { + closeButton.click(); + } + + public void selectRealmRole(String roleName) { + if (roleName != null) { + realmAvailable.selectByVisibleText(roleName); + } + selectRealmRoleButton.click(); + } + + public void selectClientRole(String clientName, String roleName) { + if (roleName != null || clientName != null) { + clientSelect.selectByVisibleText(clientName); + clientAvailable.selectByVisibleText(roleName); + } + selectClientRoleButton.click(); + } + } + + public void selectRole(String roleType, String roleName, String clientName) { + selectRoleButton.click(); + switch (roleType) { + case REALM_ROLE: + roleSelectorModalDialog.selectRealmRole(roleName); + break; + case CLIENT_ROLE: + roleSelectorModalDialog.selectClientRole(clientName, roleName); + break; + default: + throw new IllegalArgumentException("No such role type, use \"" + + REALM_ROLE + "\" or \"" + CLIENT_ROLE + "\""); + } + } + + public void closeRoleSelectorModalDialog() { + roleSelectorModalDialog.closeRoleSelectorModalDialog(); + } + + public void setName(String value) { + setInputValue(nameElement, value); + } + public boolean isConsentRequired() { return consentRequiredSwitch.isOn(); } @@ -89,10 +159,6 @@ public class CreateClientMappersForm extends Form { setInputValue(consentTextElement, consentText); } - public String getMapperType() { - return mapperTypeSelect.getFirstSelectedOption().getText(); - } - public void setMapperType(String type) { mapperTypeSelect.selectByVisibleText(type); } @@ -184,4 +250,62 @@ public class CreateClientMappersForm extends Form { public void setAddToAccessToken(boolean value) { addToAccessTokenInput.setOn(value); } + + public boolean isFullGroupPath() { + return fullGroupPath.isOn(); + } + + public void setFullGroupPath(boolean value) { + fullGroupPath.setOn(value); + } + + //SAML + @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Role attribute name']//following-sibling::node()//input[@type='text']") + private WebElement roleAttributeNameInput; + + @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Friendly Name']//following-sibling::node()//input[@type='text']") + private WebElement friendlyNameInput; + + @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='SAML Attribute NameFormat']//following-sibling::node()//select") + private Select samlAttributeNameFormatSelect; + + @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Single Role Attribute']//following-sibling::node()//div[@class='onoffswitch']") + private OnOffSwitch singleRoleAttributeSwitch; + + @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Attribute value']//following-sibling::node()//input[@type='text']") + private WebElement attributeValueInput; + + @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Group attribute name']//following-sibling::node()//input[@type='text']") + private WebElement groupAttributeNameInput; + + @FindBy(xpath = ".//div[@properties='mapperType.properties']//label[text()='Single Group Attribute']//following-sibling::node()//div[@class='onoffswitch']") + private OnOffSwitch singleGroupAttributeSwitch; + + public void setRoleAttributeName(String value) { + setInputValue(roleAttributeNameInput, value); + } + + public void setFriendlyName(String value) { + setInputValue(friendlyNameInput, value); + } + + public void setSamlAttributeNameFormat(String value) { + samlAttributeNameFormatSelect.selectByVisibleText(value); + } + + public void setSingleRoleAttribute(boolean value) { + singleRoleAttributeSwitch.setOn(value); + } + + public void setAttributeValue(String value) { + setInputValue(attributeValueInput, value); + } + + public void setGroupAttributeName(String value) { + setInputValue(groupAttributeNameInput, value); + } + + public void setSingleGroupAttribute(boolean value) { + singleGroupAttributeSwitch.setOn(value); + } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/MapperSettingsForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/MapperSettingsForm.java new file mode 100644 index 0000000000..09a9ba92f8 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/mappers/MapperSettingsForm.java @@ -0,0 +1,56 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.page.clients.mappers; + +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +/** + * @author Vlastislav Ramik + */ +public class MapperSettingsForm extends CreateClientMappersForm { + + @FindBy(id = "protocol") + private WebElement protocolInput; + @FindBy(id = "mapperId") + private WebElement mapperIdInput; + @FindBy(id = "name") + private WebElement nameInput; + @FindBy(id = "mapperType") + private WebElement mapperTypeInput; + + public String getProtocol() { + return getInputValue(protocolInput); + } + + public String getMapperId() { + return getInputValue(mapperIdInput); + } + + public String getName() { + return getInputValue(nameInput); + } + + public String getMapperType() { + return getInputValue(mapperTypeInput); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientRole.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRole.java similarity index 65% rename from testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientRole.java rename to testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRole.java index d0a0b0d5e8..262199723a 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientRole.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRole.java @@ -1,6 +1,8 @@ -package org.keycloak.testsuite.console.page.clients; +package org.keycloak.testsuite.console.page.clients.roles; import org.keycloak.testsuite.console.page.roles.*; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; /** * @@ -9,6 +11,9 @@ import org.keycloak.testsuite.console.page.roles.*; public class ClientRole extends ClientRoles { public static final String ROLE_ID = "roleId"; + + @FindBy(xpath = "//i[contains(@class, 'delete')]") + private WebElement deleteIcon; @Override public String getUriFragment() { @@ -32,5 +37,11 @@ public class ClientRole extends ClientRoles { public void backToClientRolesViaBreadcrumb() { breadcrumb().clickItemOneLevelUp(); } + + @Override + public void delete() { + deleteIcon.click(); + modalDialog.confirmDeletion(); + } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientRoles.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java similarity index 83% rename from testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientRoles.java rename to testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java index a8ee969bbf..3542af2d86 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientRoles.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/roles/ClientRoles.java @@ -1,5 +1,6 @@ -package org.keycloak.testsuite.console.page.clients; +package org.keycloak.testsuite.console.page.clients.roles; +import org.keycloak.testsuite.console.page.clients.*; import org.keycloak.admin.client.resource.RolesResource; import org.keycloak.testsuite.console.page.roles.RolesTable; import org.openqa.selenium.support.FindBy; diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientRole.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/roles/CreateClientRole.java similarity index 77% rename from testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientRole.java rename to testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/roles/CreateClientRole.java index 8a3317ae00..96e2f032d2 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/CreateClientRole.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/roles/CreateClientRole.java @@ -1,4 +1,4 @@ -package org.keycloak.testsuite.console.page.clients; +package org.keycloak.testsuite.console.page.clients.roles; import static org.keycloak.testsuite.console.page.clients.Client.ID; import org.keycloak.testsuite.console.page.roles.CreateRole; @@ -14,11 +14,11 @@ public class CreateClientRole extends CreateRole { return super.getUriFragment() + "/clients/{" + ID + "}"; } - public void setClientId(String id) { + public void setId(String id) { setUriParameter(ID, id); } - public String getClientId() { + public String getId() { return getUriParameter(ID).toString(); } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/scope/ClientScope.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/scope/ClientScope.java new file mode 100644 index 0000000000..9fea7f0b51 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/scope/ClientScope.java @@ -0,0 +1,31 @@ +package org.keycloak.testsuite.console.page.clients.scope; + +import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.testsuite.console.page.clients.Client; +import org.keycloak.testsuite.console.page.roles.RoleCompositeRoles; + +/** + * + * @author tkyjovsk + */ +public class ClientScope extends Client { + + @Override + public String getUriFragment() { + return super.getUriFragment() + "/scope-mappings"; + } + + @Page + private ClientScopeForm clientScopeForm; + + @Page + private RoleCompositeRoles scopeRoleForm; + + public ClientScopeForm scopeForm() { + return clientScopeForm; + } + + public RoleCompositeRoles roleForm() { + return scopeRoleForm; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/scope/ClientScopeForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/scope/ClientScopeForm.java new file mode 100644 index 0000000000..e76ef1429d --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/scope/ClientScopeForm.java @@ -0,0 +1,41 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.page.clients.scope; + +import org.keycloak.testsuite.console.page.fragment.OnOffSwitch; +import org.keycloak.testsuite.page.Form; +import org.openqa.selenium.support.FindBy; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientScopeForm extends Form { + + @FindBy(className = "onoffswitch") + private OnOffSwitch fullScopeAllowedSwitch; + + + public void setFullScopeAllowed(boolean value) { + fullScopeAllowedSwitch.setOn(value); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettings.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettings.java similarity index 66% rename from testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettings.java rename to testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettings.java index 8fe1c2c3de..c4007bdfce 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettings.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettings.java @@ -1,6 +1,7 @@ -package org.keycloak.testsuite.console.page.clients; +package org.keycloak.testsuite.console.page.clients.settings; import org.jboss.arquillian.graphene.page.Page; +import org.keycloak.testsuite.console.page.clients.Client; /** * diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettingsForm.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java similarity index 86% rename from testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettingsForm.java rename to testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java index 589e68e0ab..2eaa5d0a7a 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/ClientSettingsForm.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/clients/settings/ClientSettingsForm.java @@ -1,4 +1,4 @@ -package org.keycloak.testsuite.console.page.clients; +package org.keycloak.testsuite.console.page.clients.settings; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.testsuite.console.page.fragment.OnOffSwitch; @@ -7,6 +7,7 @@ import org.openqa.selenium.support.FindBy; import java.util.ArrayList; import java.util.List; +import org.keycloak.testsuite.console.page.clients.CreateClientForm; import static org.keycloak.testsuite.auth.page.login.Login.OIDC; import static org.keycloak.testsuite.util.WaitUtils.pause; @@ -23,6 +24,8 @@ public class ClientSettingsForm extends CreateClientForm { @FindBy(id = "newWebOrigin") private WebElement newWebOriginInput; + @FindBy(xpath = ".//i[contains(@data-ng-click, 'newWebOrigin')]") + private WebElement newWebOriginSubmit; @FindBy(xpath = ".//input[ng-model='client.webOrigins[i]']") private List webOriginInputs; @FindBy(xpath = ".//i[contains(@data-ng-click, 'deleteWebOrigin')]") @@ -49,6 +52,7 @@ public class ClientSettingsForm extends CreateClientForm { public void addWebOrigin(String redirectUri) { newWebOriginInput.sendKeys(redirectUri); + newWebOriginSubmit.click(); } public List getWebOrigins() { @@ -83,16 +87,6 @@ public class ClientSettingsForm extends CreateClientForm { } @Override - public ClientRepresentation getValues() { - ClientRepresentation values = super.getValues(); - values.setBaseUrl(getBaseUrl()); - if (OIDC.equals(values.getProtocol())) { - values.setAdminUrl(getAdminUrl()); - values.setWebOrigins(getWebOrigins()); - } - return values; - } - public void setConsentRequired(boolean value) { consentRequired.setOn(value); } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java index 4db28a06ea..53dae19020 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/ModalDialog.java @@ -34,11 +34,10 @@ public class ModalDialog { waitUntilElement(cancelButton).is().present(); cancelButton.click(); } - + public void setName(String name) { waitUntilElement(nameInput).is().present(); nameInput.clear(); nameInput.sendKeys(name); } - } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java index d8c595e638..52f0949155 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/fragment/OnOffSwitch.java @@ -51,7 +51,7 @@ public class OnOffSwitch { private void click() { waitUntilElement(root).is().present(); - actions.moveToElement(root.findElements(By.tagName("span")).get(0)) + actions.moveToElement(root.findElement(By.tagName("label"))) .click().build().perform(); } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RoleCompositeRoles.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RoleCompositeRoles.java index 9dc25c7e4e..833acdd7ce 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RoleCompositeRoles.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/console/page/roles/RoleCompositeRoles.java @@ -1,7 +1,9 @@ package org.keycloak.testsuite.console.page.roles; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -88,6 +90,14 @@ public class RoleCompositeRoles extends Form { button.click(); } + public void addRealmRole(String role) { + addMissingRoles(availableRealmRolesSelect, addSelectedRealmRolesButton, Arrays.asList(role)); + } + + public void addClientRole(String role) { + addMissingRoles(availableClientRolesSelect, addSelectedClientRolesButton, Arrays.asList(role)); + } + protected void addMissingRoles(Select select, WebElement button, Collection roles) { select.deselectAll(); if (roles != null) { // if roles not provided, don't add any diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java index cad5e26576..57d6bb754f 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/page/AbstractAlert.java @@ -1,6 +1,7 @@ package org.keycloak.testsuite.page; import com.google.common.base.Predicate; +import java.util.Arrays; import static org.jboss.arquillian.graphene.Graphene.waitModel; import org.jboss.arquillian.graphene.fragment.Root; import org.jboss.logging.Logger; @@ -28,7 +29,7 @@ public abstract class AbstractAlert { waitModel().until(new Predicate() { @Override public boolean apply(WebDriver input) { - return !getAttributeClass().endsWith("alert-"); + return !Arrays.asList(getAttributeClass().split(" ")).contains("alert-"); } }); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java index 0fb0efede3..337a5048bc 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractAuthTest.java @@ -99,4 +99,4 @@ public abstract class AbstractAuthTest extends AbstractKeycloakTest { return adminClient.realm(testRealmPage.getAuthRealm()); } -} +} \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractDemoExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractDemoExampleAdapterTest.java index 4d0eed9ba6..2a48dac6f4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractDemoExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractDemoExampleAdapterTest.java @@ -17,7 +17,7 @@ import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.auth.page.account.Account; import org.keycloak.testsuite.auth.page.account.Applications; import org.keycloak.testsuite.auth.page.login.OAuthGrant; -import org.keycloak.testsuite.console.page.clients.ClientSettings; +import org.keycloak.testsuite.console.page.clients.settings.ClientSettings; import org.keycloak.testsuite.console.page.clients.Clients; import org.keycloak.testsuite.console.page.events.Config; import org.keycloak.testsuite.console.page.events.LoginEvents; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java index ab638626f8..5b7888c795 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/adapter/example/AbstractJSConsoleExampleAdapterTest.java @@ -12,7 +12,7 @@ import org.keycloak.testsuite.adapter.page.JSConsoleExample; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.auth.page.account.Applications; import org.keycloak.testsuite.auth.page.login.OAuthGrant; -import org.keycloak.testsuite.console.page.clients.ClientSettings; +import org.keycloak.testsuite.console.page.clients.settings.ClientSettings; import org.keycloak.testsuite.console.page.clients.Clients; import org.keycloak.testsuite.console.page.events.Config; import org.keycloak.testsuite.console.page.events.LoginEvents; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java index 94e9b4bed8..a3a1463df1 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/AbstractClientTest.java @@ -2,15 +2,40 @@ package org.keycloak.testsuite.console.clients; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.jboss.arquillian.graphene.page.Page; +import static org.junit.Assert.assertEquals; import org.junit.Before; import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; import static org.keycloak.testsuite.auth.page.login.OIDCLogin.OIDC; +import static org.keycloak.testsuite.auth.page.login.OIDCLogin.SAML; import org.keycloak.testsuite.console.AbstractConsoleTest; import org.keycloak.testsuite.console.page.clients.Client; import org.keycloak.testsuite.console.page.clients.Clients; import org.keycloak.testsuite.console.page.clients.CreateClient; +import org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.*; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_ASSERTION_CONSUMER_URL_POST; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_ASSERTION_CONSUMER_URL_REDIRECT; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_ASSERTION_SIGNATURE; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_AUTHNSTATEMENT; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_CLIENT_SIGNATURE; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_ENCRYPT; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_FORCE_NAME_ID_FORMAT; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_FORCE_POST_BINDING; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_MULTIVALUED_ROLES; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_NAME_ID_FORMAT; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_SERVER_SIGNATURE; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_SIGNATURE_ALGORITHM; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_SIGNATURE_CANONICALIZATION_METHOD; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_SINGLE_LOGOUT_SERVICE_URL_POST; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.SAMLClientSettingsForm.SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT; +import static org.keycloak.testsuite.util.AttributesAssert.assertEqualsBooleanAttributes; +import static org.keycloak.testsuite.util.AttributesAssert.assertEqualsListAttributes; +import static org.keycloak.testsuite.util.AttributesAssert.assertEqualsStringAttributes; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; /** @@ -19,6 +44,9 @@ import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; */ public abstract class AbstractClientTest extends AbstractConsoleTest { + public final String TEST_CLIENT_ID = "test-client"; + public final String TEST_REDIRECT_URIS = "http://example.test/app/*"; + @Page protected Clients clientsPage; @Page @@ -36,41 +64,141 @@ public abstract class AbstractClientTest extends AbstractConsoleTest { assertCurrentUrlEquals(clientsPage); clientsPage.table().createClient(); createClientPage.form().setValues(client); + if (SAML.equals(client.getProtocol())) { + createClientPage.form().samlForm().setValues(client); + } createClientPage.form().save(); } - public void deleteClientViaTable(String clientId) { - assertCurrentUrlEquals(clientsPage); - clientsPage.deleteClient(clientId); - } - - public void deleteClientViaPage(String clientId) { - assertCurrentUrlEquals(clientsPage); - clientsPage.table().search(clientId); - clientsPage.table().clickClient(clientId); - clientPage.delete(); - } - - public static ClientRepresentation createClientRepresentation(String clientId, String... redirectUris) { + private static ClientRepresentation createClientRep(String clientId) { ClientRepresentation client = new ClientRepresentation(); client.setClientId(clientId); client.setEnabled(true); client.setConsentRequired(false); - client.setStandardFlowEnabled(true); - client.setImplicitFlowEnabled(false); - client.setDirectAccessGrantsEnabled(true); - + return client; + } + + public static ClientRepresentation createOidcClientRep(OidcAccessType accessType, String clientId, String... redirectUris) { + ClientRepresentation client = createClientRep(clientId); + client.setProtocol(OIDC); - client.setBearerOnly(false); - client.setPublicClient(false); - client.setServiceAccountsEnabled(false); + switch (accessType) { + case BEARER_ONLY: + client.setBearerOnly(true); + break; + case PUBLIC: + client.setBearerOnly(false); + client.setPublicClient(true); + client.setStandardFlowEnabled(true); + client.setImplicitFlowEnabled(false); + client.setDirectAccessGrantsEnabled(true); + setRedirectUris(client, redirectUris); + break; + case CONFIDENTIAL: + client.setBearerOnly(false); + client.setPublicClient(false); + client.setStandardFlowEnabled(true); + client.setDirectAccessGrantsEnabled(true); + client.setServiceAccountsEnabled(true); + setRedirectUris(client, redirectUris); + break; + } + return client; + } + + public static ClientRepresentation createSamlClientRep(String clinetId) { + ClientRepresentation client = createClientRep(clinetId); - List redirectUrisList = new ArrayList(); - redirectUrisList.addAll(Arrays.asList(redirectUris)); - client.setRedirectUris(redirectUrisList); + client.setProtocol(SAML); + + client.setFrontchannelLogout(true); + client.setAttributes(getSAMLAttributes()); return client; } + + private static void setRedirectUris(ClientRepresentation client, String... redirectUris) { + List redirectUrisList = new ArrayList(); + redirectUrisList.addAll(Arrays.asList(redirectUris)); + client.setRedirectUris(redirectUrisList); + } + + protected static void setExpectedWebOrigins(ClientRepresentation client) { + List webOrigins = new ArrayList<>(); + for (String redirectUri : client.getRedirectUris()) { + //parse webOrigin from redirectUri: take substring from index 0 to + //first occurence of "/", excluded "http://" by starting search on index 7 + webOrigins.add(redirectUri.substring(0, redirectUri.indexOf("/", 7))); + } + client.setWebOrigins(webOrigins); + } + + public ClientRepresentation findClientByClientId(String clientId) { + ClientRepresentation found = null; + for (ClientRepresentation clientRepresentation : testRealmResource().clients().findAll()) { + if (clientRepresentation.getClientId().equals(clientId)) { + found = clientRepresentation; + break; + } + } + return found; + } + + public void assertClientSettingsEqual(ClientRepresentation c1, ClientRepresentation c2) { + assertEqualsStringAttributes(c1.getClientId(), c2.getClientId()); + assertEqualsStringAttributes(c1.getName(), c2.getName()); + assertEqualsBooleanAttributes(c1.isEnabled(), c2.isEnabled()); + assertEqualsBooleanAttributes(c1.isConsentRequired(), c2.isConsentRequired()); + assertEqualsBooleanAttributes(c1.isDirectAccessGrantsEnabled(), c2.isDirectAccessGrantsEnabled()); + assertEqualsStringAttributes(c1.getProtocol(), c2.getProtocol()); + assertEqualsBooleanAttributes(c1.isBearerOnly(), c2.isBearerOnly()); + assertEqualsBooleanAttributes(c1.isPublicClient(), c2.isPublicClient()); + assertEqualsBooleanAttributes(c1.isSurrogateAuthRequired(), c2.isSurrogateAuthRequired()); + + assertEqualsBooleanAttributes(c1.isFrontchannelLogout(), c2.isFrontchannelLogout()); + + assertEqualsBooleanAttributes(c1.isServiceAccountsEnabled(), c2.isServiceAccountsEnabled()); + assertEqualsListAttributes(c1.getRedirectUris(), c2.getRedirectUris()); + assertEqualsStringAttributes(c1.getBaseUrl(), c2.getBaseUrl()); + assertEqualsStringAttributes(c1.getAdminUrl(), c2.getAdminUrl()); + assertEqualsListAttributes(c1.getWebOrigins(), c2.getWebOrigins()); + } + + public void assertClientSamlAttributes(Map expected, Map actual) { + for (String key : expected.keySet()) { + assertEquals("Expected attribute " + key, expected.get(key), actual.get(key)); + } + } + + protected static Map getSAMLAttributes() { + Map attributes = new HashMap<>(); + attributes.put(SAML_ASSERTION_SIGNATURE, "true"); + attributes.put(SAML_AUTHNSTATEMENT, "false"); + attributes.put(SAML_CLIENT_SIGNATURE, "true"); + attributes.put(SAML_ENCRYPT, "true"); + attributes.put(SAML_FORCE_POST_BINDING, "true"); + attributes.put(SAML_MULTIVALUED_ROLES, "false"); + attributes.put(SAML_SERVER_SIGNATURE, "true"); + attributes.put(SAML_SIGNATURE_ALGORITHM, "RSA_SHA512"); + attributes.put(SAML_ASSERTION_CONSUMER_URL_POST, "http://example0.test"); + attributes.put(SAML_ASSERTION_CONSUMER_URL_REDIRECT, "http://example1.test"); + attributes.put(SAML_FORCE_NAME_ID_FORMAT, "true"); + attributes.put(SAML_NAME_ID_FORMAT, "email"); + attributes.put(SAML_SIGNATURE_CANONICALIZATION_METHOD, "http://www.w3.org/2001/10/xml-exc-c14n#WithComments"); + attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_POST, "http://example2.test"); + attributes.put(SAML_SINGLE_LOGOUT_SERVICE_URL_REDIRECT, "http://example3.test"); + return attributes; + } + + public ProtocolMapperRepresentation findClientMapperByName(String clientId, String mapperName) { + ProtocolMapperRepresentation found = null; + for (ProtocolMapperRepresentation mapper : testRealmResource().clients().get(clientId).getProtocolMappers().getMappers()) { + if (mapperName.equals(mapper.getName())) { + found = mapper; + } + } + return found; + } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientClusteringTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientClusteringTest.java new file mode 100644 index 0000000000..c2f8eec834 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientClusteringTest.java @@ -0,0 +1,98 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.clients; + +import org.jboss.arquillian.graphene.page.Page; +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.representations.idm.ClientRepresentation; +import static org.keycloak.testsuite.console.clients.AbstractClientTest.createOidcClientRep; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL; +import org.keycloak.testsuite.console.page.clients.clustering.ClientClustering; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientClusteringTest extends AbstractClientTest { + + private ClientRepresentation newClient; + private ClientRepresentation found; + + @Page + private ClientClustering clientClusteringPage; + + @Before + public void before() { + newClient = createOidcClientRep(CONFIDENTIAL, TEST_CLIENT_ID, TEST_REDIRECT_URIS); + testRealmResource().clients().create(newClient).close(); + + found = findClientByClientId(TEST_CLIENT_ID); + assertNotNull("Client " + TEST_CLIENT_ID + " was not found.", found); + clientClusteringPage.setId(found.getId()); + clientClusteringPage.navigateTo(); + } + + @Test + public void basicConfigurationTest() { + assertTrue(found.getNodeReRegistrationTimeout() == -1); + + clientClusteringPage.form().setNodeReRegistrationTimeout("10", "Seconds"); + clientClusteringPage.form().save(); + assertAlertSuccess(); + assertTrue(findClientByClientId(TEST_CLIENT_ID).getNodeReRegistrationTimeout() == 10); + + clientClusteringPage.form().setNodeReRegistrationTimeout("10", "Minutes"); + clientClusteringPage.form().save(); + assertAlertSuccess(); + assertTrue(findClientByClientId(TEST_CLIENT_ID).getNodeReRegistrationTimeout() == 600); + + clientClusteringPage.form().setNodeReRegistrationTimeout("1", "Hours"); + clientClusteringPage.form().save(); + assertAlertSuccess(); + assertTrue(findClientByClientId(TEST_CLIENT_ID).getNodeReRegistrationTimeout() == 3600); + + clientClusteringPage.form().setNodeReRegistrationTimeout("1", "Days"); + clientClusteringPage.form().save(); + assertAlertSuccess(); + assertTrue(findClientByClientId(TEST_CLIENT_ID).getNodeReRegistrationTimeout() == 86400); + + clientClusteringPage.form().setNodeReRegistrationTimeout("", "Days"); + clientClusteringPage.form().save(); + assertAlertDanger(); + + clientClusteringPage.form().setNodeReRegistrationTimeout("text", "Days"); + clientClusteringPage.form().save(); + assertAlertDanger(); + } + + @Test + public void registerNodeTest() { + clientClusteringPage.form().addNode("new node"); + assertAlertSuccess(); + assertNotNull(findClientByClientId(TEST_CLIENT_ID).getRegisteredNodes().get("new node")); + + clientClusteringPage.form().addNode(""); + assertAlertDanger(); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientCredentialsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientCredentialsTest.java new file mode 100644 index 0000000000..4030231755 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientCredentialsTest.java @@ -0,0 +1,86 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.clients; + +import org.jboss.arquillian.graphene.page.Page; +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.representations.idm.ClientRepresentation; +import static org.keycloak.testsuite.console.clients.AbstractClientTest.createOidcClientRep; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL; +import org.keycloak.testsuite.console.page.clients.credentials.ClientCredentials; +import org.keycloak.testsuite.console.page.clients.credentials.ClientCredentialsGeneratePrivateKeys; +import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientCredentialsTest extends AbstractClientTest { + + private ClientRepresentation newClient; + + @Page + private ClientCredentials clientCredentialsPage; + @Page + private ClientCredentialsGeneratePrivateKeys generatePrivateKeysPage; + + @Before + public void before() { + newClient = createOidcClientRep(CONFIDENTIAL, TEST_CLIENT_ID, TEST_REDIRECT_URIS); + testRealmResource().clients().create(newClient).close(); + + ClientRepresentation found = findClientByClientId(TEST_CLIENT_ID); + assertNotNull("Client " + TEST_CLIENT_ID + " was not found.", found); + clientCredentialsPage.setId(found.getId()); + clientCredentialsPage.navigateTo(); + } + + @Test + public void regenerateSecret() { + clientCredentialsPage.form().selectClientIdAndSecret(); + clientCredentialsPage.form().regenerateSecret(); + assertAlertSuccess(); + } + + @Test + public void regenerateRegistrationAccessToken() { + clientCredentialsPage.form().regenerateRegistrationAccessToken(); + assertAlertSuccess(); + } + + @Test + public void generateNewKeysAndCert() { + generatePrivateKeysPage.setId(clientCredentialsPage.getId()); + clientCredentialsPage.form().selectSignedJwt(); + clientCredentialsPage.form().generateNewKeysAndCert(); + assertCurrentUrlEquals(generatePrivateKeysPage); + + generatePrivateKeysPage.generateForm().clickGenerateAndDownload(); + assertAlertDanger(); + +// generatePrivateKeysPage.generateForm().setKeyPassword("pass"); +// generatePrivateKeysPage.generateForm().setStorePassword("pass2"); +// assertAlertSuccess();//fails with phantomjs + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientInstallationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientInstallationTest.java new file mode 100644 index 0000000000..3ee6335be9 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientInstallationTest.java @@ -0,0 +1,67 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.clients; + +import org.jboss.arquillian.graphene.page.Page; +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.representations.idm.ClientRepresentation; +import static org.keycloak.testsuite.console.clients.AbstractClientTest.createOidcClientRep; +import org.keycloak.testsuite.console.page.clients.installation.ClientInstallation; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientInstallationTest extends AbstractClientTest { + + private ClientRepresentation newClient; + private ClientRepresentation found; + + @Page + private ClientInstallation clientInstallationPage; + + @Before + public void before() { + newClient = createOidcClientRep(CONFIDENTIAL, TEST_CLIENT_ID, TEST_REDIRECT_URIS); + testRealmResource().clients().create(newClient).close(); + + found = findClientByClientId(TEST_CLIENT_ID); + assertNotNull("Client " + TEST_CLIENT_ID + " was not found.", found); + clientInstallationPage.setId(found.getId()); + clientInstallationPage.navigateTo(); + } + + @Test + public void jsonTest() { + clientInstallationPage.form().setConfigFormat("Keycloak JSON"); + assertTrue(clientInstallationPage.form().getTextareaContent().contains("\"realm\": \"test\"")); + } + + @Test + public void wildflySubsystemTest() { + clientInstallationPage.form().setConfigFormat("Wildfly/EAP Subsystem XML"); + assertTrue(clientInstallationPage.form().getTextareaContent().contains("test")); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientMappersOIDCTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientMappersOIDCTest.java new file mode 100644 index 0000000000..084f317f45 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientMappersOIDCTest.java @@ -0,0 +1,378 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.clients; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.jboss.arquillian.graphene.page.Page; +import org.junit.Test; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL; +import org.keycloak.testsuite.console.page.clients.mappers.ClientMapper; +import org.keycloak.testsuite.console.page.clients.mappers.ClientMappers; +import org.keycloak.testsuite.console.page.clients.mappers.CreateClientMappers; +import static org.keycloak.testsuite.console.page.clients.mappers.CreateClientMappersForm.*; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientMappersOIDCTest extends AbstractClientTest { + + private String id; + + @Page + private ClientMappers clientMappersPage; + @Page + private ClientMapper clientMapperPage; + + @Page + private CreateClientMappers createClientMappersPage; + + @Before + public void beforeClientMappersTest() { + ClientRepresentation newClient = createOidcClientRep(CONFIDENTIAL, TEST_CLIENT_ID, TEST_REDIRECT_URIS); + testRealmResource().clients().create(newClient).close(); + + id = findClientByClientId(TEST_CLIENT_ID).getId(); + clientMappersPage.setId(id); + clientMappersPage.navigateTo(); + } + + private void setInitialValues(String name, boolean consentRequired, String consentText) { + createClientMappersPage.form().setName(name); + createClientMappersPage.form().setConsentRequired(consentRequired); + if (consentRequired) { + createClientMappersPage.form().setConsentText(consentText); + } + } + + @Test + public void testHardcodedRole() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("hardcoded role", true, "Consent Text"); + createClientMappersPage.form().setMapperType(HARDCODED_ROLE); + createClientMappersPage.form().selectRole(REALM_ROLE, "offline_access", null); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "hardcoded role"); + assertNotNull(found); + + assertTrue(found.isConsentRequired()); + assertEquals("Consent Text", found.getConsentText()); + assertEquals("oidc-hardcoded-role-mapper", found.getProtocolMapper()); + Map config = found.getConfig(); + + assertEquals(1, config.size()); + assertEquals("offline_access", config.get("role")); + + //edit + createClientMappersPage.form().selectRole(CLIENT_ROLE, "view-profile", "account"); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + config = findClientMapperByName(id, "hardcoded role").getConfig(); + assertEquals("account.view-profile", config.get("role")); + + //delete + clientMapperPage.setMapperId(found.getId()); + clientMapperPage.delete(); + assertAlertSuccess(); + + //check + assertNull(findClientMapperByName(id, "hardcoded role")); + } + + @Test + public void testHardcodedClaim() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("hardcoded claim", false, null); + createClientMappersPage.form().setMapperType(HARDCODED_CLAIM); + createClientMappersPage.form().setTokenClaimName("claim name"); + createClientMappersPage.form().setTokenClaimValue("claim value"); + createClientMappersPage.form().setClaimJSONType("long"); + createClientMappersPage.form().setAddToIDToken(true); + createClientMappersPage.form().setAddToAccessToken(true); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "hardcoded claim"); + assertNotNull(found); + + assertFalse(found.isConsentRequired()); + assertEquals("oidc-hardcoded-claim-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals("true", config.get("id.token.claim")); + assertEquals("true", config.get("access.token.claim")); + assertEquals("claim name", config.get("claim.name")); + assertEquals("claim value", config.get("claim.value")); + assertEquals("long", config.get("jsonType.label")); + } + + @Test + public void testUserSessionNote() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("user session note", false, null); + createClientMappersPage.form().setMapperType(USER_SESSION_NOTE); + createClientMappersPage.form().setUserSessionNote("session note"); + createClientMappersPage.form().setTokenClaimName("claim name"); + createClientMappersPage.form().setClaimJSONType("int"); + createClientMappersPage.form().setAddToIDToken(false); + createClientMappersPage.form().setAddToAccessToken(false); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "user session note"); + assertNotNull(found); + + assertFalse(found.isConsentRequired()); + assertEquals("oidc-usersessionmodel-note-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertNull(config.get("id.token.claim")); + assertNull(config.get("access.token.claim")); + assertEquals("claim name", config.get("claim.name")); + assertEquals("session note", config.get("user.session.note")); + assertEquals("int", config.get("jsonType.label")); + } + + @Test + public void testRoleName() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("role name", false, null); + createClientMappersPage.form().setMapperType(ROLE_NAME_MAPPER); + createClientMappersPage.form().setRole("offline_access"); + createClientMappersPage.form().setNewRole("new role"); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "role name"); + assertEquals("oidc-role-name-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals("offline_access", config.get("role")); + assertEquals("new role", config.get("new.role.name")); + } + + @Test + public void testUserAddress() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("user address", false, null); + createClientMappersPage.form().setMapperType(USERS_FULL_NAME); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "user address"); + assertEquals("oidc-full-name-mapper", found.getProtocolMapper()); + } + + @Test + public void testUserFullName() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("user full name", false, null); + createClientMappersPage.form().setMapperType(USERS_FULL_NAME); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "user full name"); + assertEquals("oidc-full-name-mapper", found.getProtocolMapper()); + } + + @Test + public void testUserAttribute() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("user attribute", false, null); + createClientMappersPage.form().setMapperType(USER_ATTRIBUTE); + createClientMappersPage.form().setUserAttribute("user attribute"); + createClientMappersPage.form().setMultivalued(true); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "user attribute"); + assertEquals("oidc-usermodel-attribute-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals("true", config.get("multivalued")); + assertEquals("user attribute", config.get("user.attribute")); + } + + @Test + public void testUserProperty() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("user property", false, null); + createClientMappersPage.form().setMapperType(USER_PROPERTY); + createClientMappersPage.form().setProperty("property"); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "user property"); + assertEquals("oidc-usermodel-property-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals("property", config.get("user.attribute")); + } + + @Test + public void testGroupMembership() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("group membership", false, null); + createClientMappersPage.form().setMapperType(GROUP_MEMBERSHIP); + createClientMappersPage.form().setFullGroupPath(true); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "group membership"); + assertEquals("oidc-group-membership-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals("true", config.get("full.path")); + } + + @Test + public void testEditMapper() { + //prepare data + ProtocolMapperRepresentation mapper = new ProtocolMapperRepresentation(); + mapper.setName("mapper name"); + mapper.setConsentRequired(true); + mapper.setConsentText("consent text"); + mapper.setProtocol("openid-connect"); + mapper.setProtocolMapper("oidc-usersessionmodel-note-mapper"); + + Map config = new HashMap<>(); + config.put("access.token.claim", "true"); + config.put("id.token.claim", "true"); + config.put("claim.name", "claim name"); + config.put("jsonType.label", "String"); + config.put("user.session.note", "session note"); + + mapper.setConfig(config); + + //insert data + testRealmResource().clients().get(id).getProtocolMappers().createMapper(mapper).close(); + + //check form + clientMapperPage.setId(id); + String mapperId = findClientMapperByName(id, "mapper name").getId(); + clientMapperPage.setMapperId(mapperId); + clientMapperPage.navigateTo(); + + assertEquals("openid-connect", clientMapperPage.form().getProtocol()); + assertEquals(mapperId, clientMapperPage.form().getMapperId()); + assertEquals("mapper name", clientMapperPage.form().getName()); + assertTrue(clientMapperPage.form().isConsentRequired()); + assertEquals("consent text", clientMapperPage.form().getConsentText()); + assertEquals("User Session Note", clientMapperPage.form().getMapperType()); + assertEquals("session note", clientMapperPage.form().getUserSessionNote()); + assertEquals("claim name", clientMapperPage.form().getTokenClaimName()); + assertEquals("String", clientMapperPage.form().getClaimJSONType()); + assertTrue(clientMapperPage.form().isAddToIDToken()); + assertTrue(clientMapperPage.form().isAddToAccessToken()); + + //edit + clientMapperPage.form().setConsentRequired(false); + clientMapperPage.form().save(); + assertAlertSuccess(); + + //check + assertFalse(findClientMapperByName(id, "mapper name").isConsentRequired()); + } + + @Test + public void testAddBuiltin() { + clientMappersPage.mapperTable().addBuiltin(); + clientMappersPage.mapperTable().checkBuiltinMapper("locale"); + clientMappersPage.mapperTable().clickAddSelectedBuiltinMapper(); + assertAlertSuccess(); + + assertTrue("Builtin mapper \"locale\" should be present.", isMapperPresent("locale")); + + clientMappersPage.mapperTable().deleteMapper("locale"); + modalDialog.confirmDeletion(); + assertAlertSuccess(); + + assertFalse("Builtin mapper \"locale\" should not be present.", isMapperPresent("locale")); + } + + private boolean isMapperPresent(String name) { + List mappers = testRealmResource().clients().get(id).getProtocolMappers().getMappers(); + boolean found = false; + for (ProtocolMapperRepresentation mapper : mappers) { + if (name.equals(mapper.getName())) { + found = true; + } + } + return found; + } + + @Test + public void testCreateMapperInvalidValues() { + //empty mapper type + clientMappersPage.mapperTable().createMapper(); + createClientMappersPage.form().save(); + assertAlertDanger(); + + //empty name + createClientMappersPage.form().setMapperType(HARDCODED_ROLE); + createClientMappersPage.form().save(); + assertAlertDanger(); + + createClientMappersPage.form().setName(""); + createClientMappersPage.form().save(); + assertAlertDanger(); + + createClientMappersPage.form().setName("name"); + createClientMappersPage.form().setName(""); + createClientMappersPage.form().save(); + assertAlertDanger(); + + //existing name + createClientMappersPage.form().setName("email"); + createClientMappersPage.form().save(); + assertAlertDanger(); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientMappersSAMLTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientMappersSAMLTest.java new file mode 100644 index 0000000000..7905bbd22c --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientMappersSAMLTest.java @@ -0,0 +1,212 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.clients; + +import java.util.Map; +import org.jboss.arquillian.graphene.page.Page; +import org.junit.Test; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; +import org.keycloak.testsuite.console.page.clients.mappers.ClientMapper; +import org.keycloak.testsuite.console.page.clients.mappers.ClientMappers; +import org.keycloak.testsuite.console.page.clients.mappers.CreateClientMappers; +import static org.keycloak.testsuite.console.page.clients.mappers.CreateClientMappersForm.*; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientMappersSAMLTest extends AbstractClientTest { + + private String id; + + @Page + private ClientMappers clientMappersPage; + @Page + private ClientMapper clientMapperPage; + + @Page + private CreateClientMappers createClientMappersPage; + + @Before + public void beforeClientMappersTest() { + ClientRepresentation newClient = createSamlClientRep(TEST_CLIENT_ID); + testRealmResource().clients().create(newClient).close(); + + id = findClientByClientId(TEST_CLIENT_ID).getId(); + clientMappersPage.setId(id); + clientMappersPage.navigateTo(); + } + + private void setInitialValues(String name, boolean consentRequired, String consentText) { + createClientMappersPage.form().setName(name); + createClientMappersPage.form().setConsentRequired(consentRequired); + if (consentRequired) { + createClientMappersPage.form().setConsentText(consentText); + } + } + + @Test + public void testRoleName() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("role name", false, null); + createClientMappersPage.form().setMapperType(ROLE_NAME_MAPPER); + createClientMappersPage.form().setRole("offline_access"); + createClientMappersPage.form().setNewRole("new role"); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "role name"); + assertEquals("saml-role-name-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals("offline_access", config.get("role")); + assertEquals("new role", config.get("new.role.name")); + } + + @Test + public void testRoleList() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("new role list", false, null); + createClientMappersPage.form().setMapperType(ROLE_LIST); + createClientMappersPage.form().setRoleAttributeName("role attribute name"); + createClientMappersPage.form().setFriendlyName("friendly name"); + createClientMappersPage.form().setSamlAttributeNameFormat("URI Reference"); + createClientMappersPage.form().setSingleRoleAttribute(true); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "new role list"); + assertNotNull(found); + + assertFalse(found.isConsentRequired()); + assertEquals("saml-role-list-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals("role attribute name", config.get("attribute.name")); + assertEquals("URI Reference", config.get("attribute.nameformat")); + assertEquals("friendly name", config.get("friendly.name")); + assertEquals("true", config.get("single")); + } + + @Test + public void testUserProperty() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("user property", false, null); + createClientMappersPage.form().setMapperType(USER_PROPERTY); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "user property"); + assertEquals("saml-user-property-mapper", found.getProtocolMapper()); + } + + @Test + public void testUserSessionNote() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("user session note", false, null); + createClientMappersPage.form().setMapperType(USER_SESSION_NOTE); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "user session note"); + assertNotNull(found); + + assertFalse(found.isConsentRequired()); + assertEquals("saml-user-session-note-mapper", found.getProtocolMapper()); + } + + @Test + public void testHardcodedAttribute() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("hardcoded attribute", false, null); + createClientMappersPage.form().setMapperType(HARDCODED_ATTRIBUTE); + createClientMappersPage.form().setAttributeValue("attribute value"); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "hardcoded attribute"); + assertNotNull(found); + + assertFalse(found.isConsentRequired()); + assertEquals("saml-hardcode-attribute-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals("attribute value", config.get("attribute.value")); + } + + @Test + public void testGroupList() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("group list", false, null); + createClientMappersPage.form().setMapperType(GROUP_LIST); + createClientMappersPage.form().setGroupAttributeName("group attribute name"); + createClientMappersPage.form().setSingleGroupAttribute(true); + createClientMappersPage.form().setFullGroupPath(true); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "group list"); + assertEquals("saml-group-membership-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals("true", config.get("full.path")); + assertEquals("true", config.get("single")); + assertEquals("group attribute name", config.get("attribute.name")); + } + + @Test + public void testHardcodedRole() { + //create + clientMappersPage.mapperTable().createMapper(); + setInitialValues("hardcoded role", false, null); + createClientMappersPage.form().setMapperType(HARDCODED_ROLE_SAML); + createClientMappersPage.form().selectRole(REALM_ROLE, "offline_access", null); + createClientMappersPage.form().save(); + assertAlertSuccess(); + + //check + ProtocolMapperRepresentation found = findClientMapperByName(id, "hardcoded role"); + assertNotNull(found); + + assertEquals("saml-hardcode-role-mapper", found.getProtocolMapper()); + + Map config = found.getConfig(); + assertEquals(1, config.size()); + assertEquals("offline_access", config.get("role")); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientRolesTest.java index 0142911529..92d144ca5a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientRolesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientRolesTest.java @@ -1,22 +1,29 @@ package org.keycloak.testsuite.console.clients; +import java.util.List; import org.jboss.arquillian.graphene.page.Page; import org.junit.Test; import org.keycloak.testsuite.console.page.users.UserRoleMappingsForm; import static org.junit.Assert.*; +import org.junit.Before; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RoleRepresentation; -import org.keycloak.testsuite.console.page.clients.ClientRole; -import org.keycloak.testsuite.console.page.clients.ClientRoles; -import org.keycloak.testsuite.console.page.clients.CreateClientRole; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL; +import org.keycloak.testsuite.console.page.clients.roles.ClientRole; +import org.keycloak.testsuite.console.page.clients.roles.ClientRoles; +import org.keycloak.testsuite.console.page.clients.roles.CreateClientRole; import org.keycloak.testsuite.console.page.users.User; +import org.keycloak.testsuite.util.URLAssert; /** * Created by fkiss. */ public class ClientRolesTest extends AbstractClientTest { + private String id; + private final String TEST_CLIENT_ROLE_NAME = "test-client-role"; + @Page private ClientRoles clientRolesPage; @Page @@ -30,10 +37,22 @@ public class ClientRolesTest extends AbstractClientTest { @Page private UserRoleMappingsForm userRolesPage; - public void addClientRole(RoleRepresentation roleRep) { -// assertCurrentUrl(clientRoles); + @Before + public void beforeClientRolesTest() { + ClientRepresentation newClient = createOidcClientRep(CONFIDENTIAL, TEST_CLIENT_ID, TEST_REDIRECT_URIS); + testRealmResource().clients().create(newClient).close(); + + id = findClientByClientId(TEST_CLIENT_ID).getId(); + clientPage.setId(id); + clientRolePage.setId(id); + clientRolesPage.setId(id); + createClientRolePage.setId(id); + + clientPage.navigateTo(); + } + + public void addNewClientRole(RoleRepresentation roleRep) { clientRolesPage.roles().addRole(); -// assertCurrentUrl(createClientRole); // can't do this, need client id to build uri createClientRolePage.form().setBasicAttributes(roleRep); createClientRolePage.form().save(); assertAlertSuccess(); @@ -42,25 +61,32 @@ public class ClientRolesTest extends AbstractClientTest { } @Test - public void testAddClientRole() { - ClientRepresentation newClient = createClientRepresentation("test-client1", "http://example.com/*"); - RoleRepresentation newRole = new RoleRepresentation("client-role", "", false); - - createClient(newClient); - assertAlertSuccess(); - + public void testCRUDClientRole() { + RoleRepresentation newRole = new RoleRepresentation(TEST_CLIENT_ROLE_NAME, "description", false); + clientPage.tabs().roles(); - addClientRole(newRole); + addNewClientRole(newRole); - clientRolePage.backToClientRolesViaBreadcrumb(); - assertFalse(clientRolesPage.roles().getRolesFromTableRows().isEmpty()); - - configure().clients(); - clientsPage.table().search(newClient.getClientId()); - clientsPage.table().deleteClient(newClient.getClientId()); - modalDialog.confirmDeletion(); + List clientRoles = testRealmResource().clients().get(id).roles().list(); + assertEquals("Client roles should contain exactly 1 role.", 1, clientRoles.size()); + RoleRepresentation role = clientRoles.get(0); + assertEquals(TEST_CLIENT_ROLE_NAME, role.getName()); + assertEquals("description", role.getDescription()); + assertFalse(role.isScopeParamRequired()); + assertFalse(role.isComposite()); + assertNull(role.getComposites()); + + //edit + clientRolesPage.navigateTo(); + clientRolesPage.roles().editRole(TEST_CLIENT_ROLE_NAME); + + clientRolePage.setRoleId(role.getId()); + URLAssert.assertCurrentUrlEquals(clientRolePage); + + //delete + clientRolePage.delete(); assertAlertSuccess(); - assertNull(clientsPage.table().findClient(newClient.getClientId())); + assertTrue("Role should be deleted.", testRealmResource().clients().get(id).roles().list().isEmpty()); } // @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientScopeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientScopeTest.java new file mode 100644 index 0000000000..da68ca31b6 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientScopeTest.java @@ -0,0 +1,99 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.clients; + +import java.util.List; +import java.util.Map; +import org.jboss.arquillian.graphene.page.Page; +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.representations.idm.ClientMappingsRepresentation; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.MappingsRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import static org.keycloak.testsuite.console.clients.AbstractClientTest.createOidcClientRep; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL; +import org.keycloak.testsuite.console.page.clients.scope.ClientScope; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientScopeTest extends AbstractClientTest { + + private ClientRepresentation newClient; + private ClientRepresentation found; + + @Page + private ClientScope clientScopePage; + + @Before + public void before() { + newClient = createOidcClientRep(CONFIDENTIAL, TEST_CLIENT_ID, TEST_REDIRECT_URIS); + testRealmResource().clients().create(newClient).close(); + + found = findClientByClientId(TEST_CLIENT_ID); + assertNotNull("Client " + TEST_CLIENT_ID + " was not found.", found); + clientScopePage.setId(found.getId()); + clientScopePage.navigateTo(); + } + + @Test + public void clientScopeTest() { + assertTrue(found.isFullScopeAllowed()); + clientScopePage.scopeForm().setFullScopeAllowed(false); + assertAlertSuccess(); + + found = findClientByClientId(TEST_CLIENT_ID); + assertFalse(found.isFullScopeAllowed()); + assertNull(getAllMappingsRepresentation().getRealmMappings()); + assertNull(getAllMappingsRepresentation().getClientMappings()); + + clientScopePage.roleForm().addRealmRole("offline_access"); + assertAlertSuccess(); + + clientScopePage.roleForm().selectClientRole("account"); + clientScopePage.roleForm().addClientRole("view-profile"); + assertAlertSuccess(); + + found = findClientByClientId(TEST_CLIENT_ID); + List realmMappings = getAllMappingsRepresentation().getRealmMappings(); + assertEquals(1, realmMappings.size()); + assertEquals("offline_access", realmMappings.get(0).getName()); + Map clientMappings = getAllMappingsRepresentation().getClientMappings(); + assertEquals(1, clientMappings.size()); + assertEquals("view-profile", clientMappings.get("account").getMappings().get(0).getName()); + +// clientScopePage.roleForm().removeAssignedRole("offline_access"); +// assertAlertSuccess();//fails with phantomjs +// clientScopePage.roleForm().removeAssignedClientRole("view-profile"); +// assertAlertSuccess();//fails with phantomjs +// +// assertNull(getAllMappingsRepresentation().getRealmMappings()); +// assertNull(getAllMappingsRepresentation().getClientMappings()); + } + + private MappingsRepresentation getAllMappingsRepresentation() { + return testRealmResource().clients().get(found.getId()).getScopeMappings().getAll(); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java index 9f1fd625f2..da601e783b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientSettingsTest.java @@ -17,19 +17,17 @@ */ package org.keycloak.testsuite.console.clients; +import java.util.ArrayList; +import java.util.List; import javax.ws.rs.core.Response; import org.jboss.arquillian.graphene.page.Page; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import org.junit.Test; import org.keycloak.representations.idm.ClientRepresentation; import static org.keycloak.testsuite.admin.ApiUtil.getCreatedId; -import org.keycloak.testsuite.console.page.clients.ClientSettings; -import static org.keycloak.testsuite.util.AttributesAssert.assertEqualsBooleanAttributes; -import static org.keycloak.testsuite.util.AttributesAssert.assertEqualsListAttributes; -import static org.keycloak.testsuite.util.AttributesAssert.assertEqualsStringAttributes; -import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.*; +import org.keycloak.testsuite.console.page.clients.settings.ClientSettings; import static org.keycloak.testsuite.util.WaitUtils.pause; import org.keycloak.testsuite.util.Timer; @@ -45,56 +43,102 @@ public class ClientSettingsTest extends AbstractClientTest { private ClientRepresentation newClient; + @Test public void crudOIDCConfidential() { - newClient = createClientRepresentation("oidc-confidential", "http://example.test/app/*"); + newClient = createOidcClientRep(CONFIDENTIAL, "oidc-confidential", TEST_REDIRECT_URIS); createClient(newClient); assertAlertSuccess(); - clientPage.backToClientsViaBreadcrumb(); - assertCurrentUrlEquals(clientsPage); - assertEquals(1, clientsPage.table().searchClients(newClient.getClientId()).size()); - + setExpectedWebOrigins(newClient); + // read & verify - clientsPage.table().clickClient(newClient); - ClientRepresentation found = clientSettingsPage.form().getValues(); + ClientRepresentation found = findClientByClientId(newClient.getClientId()); + assertNotNull("Client " + newClient.getClientId() + " was not found.", found); + assertClientSettingsEqual(newClient, found); + + // update & verify + newClient.setClientId("oidc-confidential-updated"); + newClient.setName("updatedName"); + + List redirectUris = new ArrayList<>(); + redirectUris.add("http://example2.test/app/*"); + redirectUris.add("http://example2.test/app2/*"); + redirectUris.add("http://example3.test/app/*"); + newClient.setRedirectUris(redirectUris); + + List webOrigins = new ArrayList<>(); + webOrigins.clear(); + webOrigins.add("http://example2.test"); + webOrigins.add("http://example3.test"); + newClient.setWebOrigins(webOrigins); + + clientSettingsPage.form().setClientId("oidc-confidential-updated"); + clientSettingsPage.form().setName("updatedName"); + clientSettingsPage.form().setRedirectUris(redirectUris); + clientSettingsPage.form().setWebOrigins(webOrigins); + clientSettingsPage.form().save(); + assertAlertSuccess(); + + found = findClientByClientId(newClient.getClientId()); + assertNotNull("Client " + newClient.getClientId() + " was not found.", found); assertClientSettingsEqual(newClient, found); - // update & verify - // TODO change attributes, add redirect uris and weborigins // delete - // TODO - clientPage.backToClientsViaBreadcrumb(); - } - - public void createOIDCPublic() { - newClient = createClientRepresentation("oidc-public", "http://example.test/app/*"); - newClient.setPublicClient(true); - createClient(newClient); + clientPage.delete(); assertAlertSuccess(); - - clientPage.backToClientsViaBreadcrumb(); - assertCurrentUrlEquals(clientsPage); - assertEquals(1, clientsPage.table().searchClients(newClient.getClientId()).size()); - } - - public void createOIDCBearerOnly() { - newClient = createClientRepresentation("oidc-bearer-only", "http://example.test/app/*"); - newClient.setBearerOnly(true); - createClient(newClient); - assertAlertSuccess(); - - clientPage.backToClientsViaBreadcrumb(); - assertCurrentUrlEquals(clientsPage); - assertEquals(1, clientsPage.table().searchClients(newClient.getClientId()).size()); + found = findClientByClientId(newClient.getClientId()); + assertNull("Deleted client " + newClient.getClientId() + " was found.", found); } @Test - public void successfulCRUD() { - crudOIDCConfidential(); - createOIDCPublic(); - createOIDCBearerOnly(); + public void createOIDCPublic() { + newClient = createOidcClientRep(PUBLIC, "oidc-public", TEST_REDIRECT_URIS); + createClient(newClient); + assertAlertSuccess(); + + setExpectedWebOrigins(newClient); + + ClientRepresentation found = findClientByClientId(newClient.getClientId()); + assertNotNull("Client " + newClient.getClientId() + " was not found.", found); + assertClientSettingsEqual(newClient, found); + } + + @Test + public void createOIDCPublicWithoutRedirectURIs() { + newClient = createOidcClientRep(PUBLIC, "oidc-public"); + newClient.setStandardFlowEnabled(false); + createClient(newClient); + assertAlertSuccess(); + + ClientRepresentation found = findClientByClientId(newClient.getClientId()); + assertNotNull("Client " + newClient.getClientId() + " was not found.", found); + assertClientSettingsEqual(newClient, found); } + @Test + public void createOIDCBearerOnly() { + newClient = createOidcClientRep(BEARER_ONLY, "oidc-bearer-only"); + createClient(newClient); + assertAlertSuccess(); + + ClientRepresentation found = findClientByClientId(newClient.getClientId()); + assertNotNull("Client " + newClient.getClientId() + " was not found.", found); + assertClientSettingsEqual(newClient, found); + } + + @Test + public void createSAML() { + newClient = createSamlClientRep("saml"); + createClient(newClient); + assertAlertSuccess(); + + ClientRepresentation found = findClientByClientId(newClient.getClientId()); + System.out.println("...." + found.isFrontchannelLogout()); + assertNotNull("Client " + newClient.getClientId() + " was not found.", found); + assertClientSettingsEqual(newClient, found); + assertClientSamlAttributes(getSAMLAttributes(), found.getAttributes()); + } + @Test public void invalidSettings() { clientsPage.table().createClient(); @@ -106,32 +150,9 @@ public class ClientSettingsTest extends AbstractClientTest { assertAlertDanger(); } - public void assertClientSettingsEqual(ClientRepresentation c1, ClientRepresentation c2) { - assertEqualsStringAttributes(c1.getClientId(), c2.getClientId()); - assertEqualsStringAttributes(c1.getName(), c2.getName()); - assertEqualsBooleanAttributes(c1.isEnabled(), c2.isEnabled()); - assertEqualsBooleanAttributes(c1.isConsentRequired(), c2.isConsentRequired()); - assertEqualsBooleanAttributes(c1.isStandardFlowEnabled(), c2.isStandardFlowEnabled()); - assertEqualsBooleanAttributes(c1.isImplicitFlowEnabled(), c2.isImplicitFlowEnabled()); - assertEqualsBooleanAttributes(c1.isDirectAccessGrantsEnabled(), c2.isDirectAccessGrantsEnabled()); - assertEqualsStringAttributes(c1.getProtocol(), c2.getProtocol()); - - assertEqualsBooleanAttributes(c1.isBearerOnly(), c2.isBearerOnly()); - assertEqualsBooleanAttributes(c1.isPublicClient(), c2.isPublicClient()); - assertEqualsBooleanAttributes(c1.isSurrogateAuthRequired(), c2.isSurrogateAuthRequired()); - - assertEqualsBooleanAttributes(c1.isFrontchannelLogout(), c2.isFrontchannelLogout()); - - assertEqualsBooleanAttributes(c1.isServiceAccountsEnabled(), c2.isServiceAccountsEnabled()); - assertEqualsListAttributes(c1.getRedirectUris(), c2.getRedirectUris()); - assertEqualsStringAttributes(c1.getBaseUrl(), c2.getBaseUrl()); - assertEqualsStringAttributes(c1.getAdminUrl(), c2.getAdminUrl()); - assertEqualsListAttributes(c1.getWebOrigins(), c2.getWebOrigins()); - } - // @Test public void createInconsistentClient() { - ClientRepresentation c = createClientRepresentation("inconsistent_client"); + ClientRepresentation c = createOidcClientRep(CONFIDENTIAL, "inconsistent_client"); c.setPublicClient(true); c.setBearerOnly(true); @@ -147,7 +168,7 @@ public class ClientSettingsTest extends AbstractClientTest { public void createClients(String clientIdPrefix, int count) { for (int i = 0; i < count; i++) { String clientId = String.format("%s%02d", clientIdPrefix, i); - ClientRepresentation cr = createClientRepresentation(clientId, "http://example.test/*"); + ClientRepresentation cr = createOidcClientRep(CONFIDENTIAL, clientId, "http://example.test/*"); Timer.time(); Response r = testRealmResource().clients().create(cr); r.close(); @@ -161,5 +182,4 @@ public class ClientSettingsTest extends AbstractClientTest { clientsPage.navigateTo(); pause(120000); } - } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientsTest.java new file mode 100644 index 0000000000..d9e64a7ac7 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/clients/ClientsTest.java @@ -0,0 +1,74 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2012, Red Hat, Inc., and individual contributors + * as indicated by the @author tags. See the copyright.txt file in the + * distribution for a full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.keycloak.testsuite.console.clients; + +import org.jboss.arquillian.graphene.page.Page; +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.representations.idm.ClientRepresentation; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL; +import org.keycloak.testsuite.console.page.clients.settings.ClientSettings; +import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlEquals; + +/** + * + * @author Vlastislav Ramik + */ +public class ClientsTest extends AbstractClientTest { + + private ClientRepresentation newClient; + + @Page + private ClientSettings clientSettingsPage; + + @Before + public void beforeClientsTest() { + newClient = createOidcClientRep(CONFIDENTIAL, TEST_CLIENT_ID, TEST_REDIRECT_URIS); + testRealmResource().clients().create(newClient).close(); + + ClientRepresentation found = findClientByClientId(TEST_CLIENT_ID); + assertNotNull("Client " + TEST_CLIENT_ID + " was not found.", found); + clientSettingsPage.setId(found.getId()); + } + + @Test + public void clientsCRUD() { + //create + clientsPage.table().createClient(); + assertCurrentUrlEquals(createClientPage); + + //edit + clientsPage.navigateTo(); + clientsPage.table().editClient(TEST_CLIENT_ID); + assertEquals(TEST_CLIENT_ID, clientSettingsPage.form().getClientId()); + + //delete + clientsPage.navigateTo(); + clientsPage.table().deleteClient(TEST_CLIENT_ID); + modalDialog.confirmDeletion(); + assertAlertSuccess(); + + ClientRepresentation found = findClientByClientId(TEST_CLIENT_ID); + assertNull("Deleted client " + TEST_CLIENT_ID + " was found.", found); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java index 74418dd36c..c25756491c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/console/events/AdminEventsTest.java @@ -18,6 +18,7 @@ import javax.ws.rs.core.Response; import java.util.List; import static org.junit.Assert.assertEquals; +import static org.keycloak.testsuite.console.page.clients.CreateClientForm.OidcAccessType.CONFIDENTIAL; /** @@ -48,7 +49,7 @@ public class AdminEventsTest extends AbstractConsoleTest { @Test public void clientsAdminEventsTest() { - newClient = AbstractClientTest.createClientRepresentation("test_client", "http://example.test/test_client/*"); + newClient = AbstractClientTest.createOidcClientRep(CONFIDENTIAL, "test_client", "http://example.test/test_client/*"); Response response = clientsPage.clientsResource().create(newClient); String id = ApiUtil.getCreatedId(response); response.close();