Merge remote-tracking branch 'upstream/master'

This commit is contained in:
mhajas 2015-12-09 10:53:50 +01:00
commit b82346761c
53 changed files with 2202 additions and 325 deletions

View file

@ -21,7 +21,7 @@ CODE_TO_TOKEN events add the following to keycloak-server.json:
...
"eventsListener": {
"sysout" {
"sysout": {
"exclude": [ "REFRESH_TOKEN", "CODE_TO_TOKEN" ]
}
}

View file

@ -17,7 +17,7 @@
<div class="form-group">
<label class="col-md-2 control-label" for="host">Host</label>
<div class="col-sm-6">
<input ng-disabled="!create" class="form-control" type="text" id="host" name="host" data-ng-model="node.host">
<input ng-disabled="!create" class="form-control" type="text" id="host" name="host" data-ng-model="node.host" required>
</div>
</div>
<div class="form-group">

View file

@ -76,9 +76,9 @@
</div>
<div class="row" data-ng-show="targetClient">
<div class="col-md-3">
<label class="control-label" for="client-available">{{:: 'available-roles' | translate}}</label>
<label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label>
<kc-tooltip>{{:: 'assign.available-roles.tooltip' | translate}}</kc-tooltip>
<select id="client-available" class="form-control" multiple size="5"
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
@ -88,9 +88,9 @@
</button>
</div>
<div class="col-md-3">
<label class="control-label" for="client-assigned">{{:: 'assigned-roles' | translate}}</label>
<label class="control-label" for="assigned-client">{{:: 'assigned-roles' | translate}}</label>
<kc-tooltip>{{:: 'client.assigned-roles.tooltip' | translate}}</kc-tooltip>
<select id="client-assigned" class="form-control" multiple size=5
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">

View file

@ -65,9 +65,9 @@
</div>
<div class="row" data-ng-show="targetClient">
<div class="col-md-3">
<label class="control-label" for="client-available">{{:: 'available-roles' | translate}}</label>
<label class="control-label" for="available-client">{{:: 'available-roles' | translate}}</label>
<kc-tooltip>{{:: 'assign.available-roles.tooltip' | translate}}</kc-tooltip>
<select id="client-available" class="form-control" multiple size="5"
<select id="available-client" class="form-control" multiple size="5"
ng-multiple="true"
ng-model="selectedClientRoles"
ng-options="r.name for r in clientRoles">
@ -77,9 +77,9 @@
</button>
</div>
<div class="col-md-3">
<label class="control-label" for="client-assigned">{{:: 'assigned-roles' | translate}}</label>
<label class="control-label" for="assigned-client">{{:: 'assigned-roles' | translate}}</label>
<kc-tooltip>{{:: 'client.assigned-roles.tooltip' | translate}}</kc-tooltip>
<select id="client-assigned" class="form-control" multiple size=5
<select id="assigned-client" class="form-control" multiple size=5
ng-multiple="true"
ng-model="selectedClientMappings"
ng-options="r.name for r in clientMappings">

View file

@ -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")
@ -98,6 +102,10 @@ public class Client extends Clients {
installationLink.click();
}
public WebElement getTabs() {
return tabs;
}
}
public ClientResource clientResource() {

View file

@ -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";
}
}

View file

@ -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";
}
}

View file

@ -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";
}
}

View file

@ -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";
}
}

View file

@ -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";
}
}

View file

@ -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";
}
}

View file

@ -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();
}

View file

@ -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<WebElement> 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());
}
if (client.isStandardFlowEnabled() || client.isImplicitFlowEnabled()) {
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());
}
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");
public boolean isBearerOnly() {
return BEARER_ONLY.equals(
accessTypeSelect.getFirstSelectedOption().getAttribute(VALUE));
private final String name;
private OidcAccessType(String name) {
this.name = name;
}
public boolean isPublicClient() {
return PUBLIC.equals(
accessTypeSelect.getFirstSelectedOption().getAttribute(VALUE));
public String getName() {
return name;
}
}
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<String> 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<String, String> 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));
}
}
}

View file

@ -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;
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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();
}
}

View file

@ -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;
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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();
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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;
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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();
}
}

View file

@ -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;
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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();
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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;
}
}

View file

@ -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<ProtocolMapperRepresentation> searchMappings(String searchPattern) {
search(searchPattern);
return getMappingsFromRows();
@ -81,6 +85,14 @@ public class ClientMappers extends Client {
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<ProtocolMapperRepresentation> getMappingsFromRows() {
List<ProtocolMapperRepresentation> mappings = new ArrayList<ProtocolMapperRepresentation>();
List<ProtocolMapperRepresentation> mappings = new ArrayList<>();
for (WebElement row : rows()) {
ProtocolMapperRepresentation mapperRepresentation = getMappingFromRow(row);

View file

@ -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;

View file

@ -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 <vmuzikar@redhat.com>
*
* TODO: SAML
*/
public class CreateClientMappersForm extends Form {
@ -27,6 +21,15 @@ 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']")
@ -73,6 +76,73 @@ 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);
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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);
}
}

View file

@ -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;
/**
*
@ -10,6 +12,9 @@ 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() {
return super.getUriFragment() + "/{" + ROLE_ID + "}";
@ -33,4 +38,10 @@ public class ClientRole extends ClientRoles {
breadcrumb().clickItemOneLevelUp();
}
@Override
public void delete() {
deleteIcon.click();
modalDialog.confirmDeletion();
}
}

View file

@ -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;

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
public class ClientScopeForm extends Form {
@FindBy(className = "onoffswitch")
private OnOffSwitch fullScopeAllowedSwitch;
public void setFullScopeAllowed(boolean value) {
fullScopeAllowedSwitch.setOn(value);
}
}

View file

@ -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;
/**
*

View file

@ -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<WebElement> 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<String> 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);
}

View file

@ -1,12 +1,15 @@
package org.keycloak.testsuite.console.page.fragment;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import java.util.List;
import static org.keycloak.testsuite.util.WaitUtils.pause;
import static org.keycloak.testsuite.util.WaitUtils.waitUntilElement;
import org.openqa.selenium.By;
import static org.openqa.selenium.By.xpath;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
*
@ -23,7 +26,7 @@ public class DataTable {
private WebElement header;
@FindBy(css = "tbody")
private WebElement body;
@FindBy(css = "tbody tr.ng-scope")
@FindBy(xpath = "(//table)[1]/tbody/tr[@class='ng-scope']")
private List<WebElement> rows;
@FindBy

View file

@ -40,5 +40,4 @@ public class ModalDialog {
nameInput.clear();
nameInput.sendKeys(name);
}
}

View file

@ -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();
}

View file

@ -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<String> roles) {
select.deselectAll();
if (roles != null) { // if roles not provided, don't add any

View file

@ -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<WebDriver>() {
@Override
public boolean apply(WebDriver input) {
return !getAttributeClass().endsWith("alert-");
return !Arrays.asList(getAttributeClass().split(" ")).contains("alert-");
}
});
}

View file

@ -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;

View file

@ -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;

View file

@ -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);
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.setServiceAccountsEnabled(false);
client.setStandardFlowEnabled(true);
client.setDirectAccessGrantsEnabled(true);
client.setServiceAccountsEnabled(true);
setRedirectUris(client, redirectUris);
break;
}
return client;
}
List<String> redirectUrisList = new ArrayList();
redirectUrisList.addAll(Arrays.asList(redirectUris));
client.setRedirectUris(redirectUrisList);
public static ClientRepresentation createSamlClientRep(String clinetId) {
ClientRepresentation client = createClientRep(clinetId);
client.setProtocol(SAML);
client.setFrontchannelLogout(true);
client.setAttributes(getSAMLAttributes());
return client;
}
private static void setRedirectUris(ClientRepresentation client, String... redirectUris) {
List<String> redirectUrisList = new ArrayList();
redirectUrisList.addAll(Arrays.asList(redirectUris));
client.setRedirectUris(redirectUrisList);
}
protected static void setExpectedWebOrigins(ClientRepresentation client) {
List<String> 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<String, String> expected, Map<String, String> actual) {
for (String key : expected.keySet()) {
assertEquals("Expected attribute " + key, expected.get(key), actual.get(key));
}
}
protected static Map<String, String> getSAMLAttributes() {
Map<String, String> 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;
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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();
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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("<realm>test</realm>"));
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<ProtocolMapperRepresentation> 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();
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> config = found.getConfig();
assertEquals(1, config.size());
assertEquals("offline_access", config.get("role"));
}
}

View file

@ -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());
List<RoleRepresentation> 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());
configure().clients();
clientsPage.table().search(newClient.getClientId());
clientsPage.table().deleteClient(newClient.getClientId());
modalDialog.confirmDeletion();
//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

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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<RoleRepresentation> realmMappings = getAllMappingsRepresentation().getRealmMappings();
assertEquals(1, realmMappings.size());
assertEquals("offline_access", realmMappings.get(0).getName());
Map<String, ClientMappingsRepresentation> 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();
}
}

View file

@ -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,54 +43,100 @@ 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
// TODO change attributes, add redirect uris and weborigins
newClient.setClientId("oidc-confidential-updated");
newClient.setName("updatedName");
List<String> 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<String> 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);
// 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
@ -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);
}
}

View file

@ -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 <a href="mailto:vramik@redhat.com">Vlastislav Ramik</a>
*/
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);
}
}

View file

@ -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();

View file

@ -50,12 +50,15 @@ public class LoginEventsTest extends AbstractConsoleTest {
loginEventsPage.navigateTo();
loginEventsPage.table().filter();
List<WebElement> resultList = loginEventsPage.table().rows();
assertEquals(3, resultList.size());
loginEventsPage.table().filterForm().addEventType("LOGIN");
loginEventsPage.table().update();
List<WebElement> resultList = loginEventsPage.table().rows();
resultList = loginEventsPage.table().rows();
assertEquals(8, resultList.size());
assertEquals(1, resultList.size());
resultList.get(0).findElement(By.xpath("//td[text()='LOGIN']"));
resultList.get(0).findElement(By.xpath("//td[text()='User']/../td[text()='" + testUser.getId() + "']"));
resultList.get(0).findElement(By.xpath("//td[text()='Client']/../td[text()='security-admin-console']"));
@ -67,7 +70,7 @@ public class LoginEventsTest extends AbstractConsoleTest {
resultList = loginEventsPage.table().rows();
assertEquals(2, resultList.size());
assertEquals(1, resultList.size());
resultList.get(0).findElement(By.xpath("//td[text()='LOGOUT']"));
resultList.get(0).findElement(By.xpath("//td[text()='User']/../td[text()='" + testUser.getId() + "']"));
resultList.get(0).findElement(By.xpath("//td[text()='IP Address']/../td[text()='127.0.0.1']"));
@ -78,7 +81,7 @@ public class LoginEventsTest extends AbstractConsoleTest {
resultList = loginEventsPage.table().rows();
assertEquals(6, resultList.size());
assertEquals(1, resultList.size());
resultList.get(0).findElement(By.xpath("//td[text()='LOGIN_ERROR']"));
resultList.get(0).findElement(By.xpath("//td[text()='User']/../td[text()='" + testUser.getId() + "']"));
resultList.get(0).findElement(By.xpath("//td[text()='Client']/../td[text()='security-admin-console']"));