Merge pull request #2664 from stianst/master

Migrate pages from old testsuite, make OAuthClient injectable
This commit is contained in:
Stian Thorgersen 2016-04-19 22:08:47 +02:00
commit d9f82affb0
44 changed files with 2416 additions and 176 deletions

View file

@ -62,6 +62,16 @@
<artifactId>integration-arquillian-event-queue</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>

View file

@ -38,6 +38,7 @@ import org.jboss.arquillian.test.spi.event.suite.BeforeClass;
import org.jboss.arquillian.test.spi.event.suite.BeforeSuite;
import org.jboss.logging.Logger;
import org.keycloak.testsuite.util.LogChecker;
import org.keycloak.testsuite.util.OAuthClient;
/**
*
@ -76,6 +77,10 @@ public class AuthServerTestEnricher {
@ClassScoped
private InstanceProducer<TestContext> testContextProducer;
@Inject
@ClassScoped
private InstanceProducer<OAuthClient> oAuthClientProducer;
public static String getAuthServerContextRoot() {
return getAuthServerContextRoot(0);
}
@ -198,4 +203,9 @@ public class AuthServerTestEnricher {
testContextProducer.set(testContext);
}
public void initializeOAuthClient(@Observes(precedence = 3) BeforeClass event) {
OAuthClient oAuthClient = new OAuthClient();
oAuthClientProducer.set(oAuthClient);
}
}

View file

@ -22,6 +22,7 @@ import org.jboss.arquillian.core.api.annotation.Inject;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider;
import org.keycloak.testsuite.util.DeleteMeOAuthClient;
import org.keycloak.testsuite.util.OAuthClient;
import java.lang.annotation.Annotation;
@ -31,11 +32,11 @@ import java.lang.annotation.Annotation;
public class OAuthClientProvider implements ResourceProvider {
@Inject
Instance<DeleteMeOAuthClient> oauthClient;
Instance<OAuthClient> oauthClient;
@Override
public boolean canProvide(Class<?> type) {
return DeleteMeOAuthClient.class.isAssignableFrom(type);
return OAuthClient.class.isAssignableFrom(type);
}
@Override

View file

@ -0,0 +1,64 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.page;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class LoginPasswordUpdatePage {
@Drone
protected WebDriver driver;
@FindBy(id = "password-new")
private WebElement newPasswordInput;
@FindBy(id = "password-confirm")
private WebElement passwordConfirmInput;
@FindBy(css = "input[type=\"submit\"]")
private WebElement submitButton;
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
public void changePassword(String newPassword, String passwordConfirm) {
newPasswordInput.sendKeys(newPassword);
passwordConfirmInput.sendKeys(passwordConfirm);
submitButton.click();
}
public boolean isCurrent() {
return driver.getTitle().equals("Update password");
}
public void open() {
throw new UnsupportedOperationException();
}
public String getError() {
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public abstract class AbstractAccountPage extends AbstractPage {
@FindBy(linkText = "Sign Out")
private WebElement logoutLink;
@FindBy(id = "kc-current-locale-link")
private WebElement languageText;
@FindBy(id = "kc-locale-dropdown")
private WebElement localeDropdown;
public void logout() {
logoutLink.click();
}
public String getLanguageDropdownText() {
return languageText.getText();
}
public void openLanguage(String language){
localeDropdown.findElement(By.linkText(language)).click();
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.Assert;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.testsuite.arquillian.SuiteContext;
import org.openqa.selenium.WebDriver;
import java.net.URI;
import java.net.URISyntaxException;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public abstract class AbstractPage {
@ArquillianResource
protected SuiteContext suiteContext;
@ArquillianResource
protected WebDriver driver;
public void assertCurrent() {
String name = getClass().getSimpleName();
Assert.assertTrue("Expected " + name + " but was " + driver.getTitle() + " (" + driver.getCurrentUrl() + ")",
isCurrent());
}
protected URI getAuthServerRoot() {
try {
return KeycloakUriBuilder.fromUri(suiteContext.getAuthServerInfo().getContextRoot().toURI()).path("/auth/").build();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
abstract public boolean isCurrent();
abstract public void open() throws Exception;
}

View file

@ -0,0 +1,147 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.keycloak.services.Urls;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AccountApplicationsPage extends AbstractAccountPage {
@Override
public boolean isCurrent() {
return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().endsWith("/account/applications");
}
@Override
public void open() {
driver.navigate().to(getPath());
}
private String getPath() {
return Urls.accountApplicationsPage(getAuthServerRoot(), "test").toString();
}
public void revokeGrant(String clientId) {
driver.findElement(By.id("revoke-" + clientId)).click();
}
public Map<String, AppEntry> getApplications() {
Map<String, AppEntry> table = new HashMap<String, AppEntry>();
for (WebElement r : driver.findElements(By.tagName("tr"))) {
int count = 0;
AppEntry currentEntry = null;
for (WebElement col : r.findElements(By.tagName("td"))) {
count++;
switch (count) {
case 1:
currentEntry = new AppEntry();
String client = col.getText();
table.put(client, currentEntry);
break;
case 2:
String rolesStr = col.getText();
String[] roles = rolesStr.split(",");
for (String role : roles) {
role = role.trim();
currentEntry.addAvailableRole(role);
}
break;
case 3:
rolesStr = col.getText();
if (rolesStr.isEmpty()) break;
roles = rolesStr.split(",");
for (String role : roles) {
role = role.trim();
currentEntry.addGrantedRole(role);
}
break;
case 4:
String protMappersStr = col.getText();
if (protMappersStr.isEmpty()) break;
String[] protMappers = protMappersStr.split(",");
for (String protMapper : protMappers) {
protMapper = protMapper.trim();
currentEntry.addMapper(protMapper);
}
break;
case 5:
String additionalGrant = col.getText();
if (additionalGrant.isEmpty()) break;
String[] grants = additionalGrant.split(",");
for (String grant : grants) {
grant = grant.trim();
currentEntry.addAdditionalGrant(grant);
}
break;
}
}
}
table.remove("Application");
return table;
}
public static class AppEntry {
private final List<String> rolesAvailable = new ArrayList<String>();
private final List<String> rolesGranted = new ArrayList<String>();
private final List<String> protocolMappersGranted = new ArrayList<String>();
private final List<String> additionalGrants = new ArrayList<>();
private void addAvailableRole(String role) {
rolesAvailable.add(role);
}
private void addGrantedRole(String role) {
rolesGranted.add(role);
}
private void addMapper(String protocolMapper) {
protocolMappersGranted.add(protocolMapper);
}
private void addAdditionalGrant(String grant) {
additionalGrants.add(grant);
}
public List<String> getRolesGranted() {
return rolesGranted;
}
public List<String> getRolesAvailable() {
return rolesAvailable;
}
public List<String> getProtocolMappersGranted() {
return protocolMappersGranted;
}
public List<String> getAdditionalGrants() {
return additionalGrants;
}
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.keycloak.services.Urls;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AccountFederatedIdentityPage extends AbstractAccountPage {
@FindBy(className = "alert-error")
private WebElement errorMessage;
public AccountFederatedIdentityPage() {};
private String realmName = "test";
public void open() {
driver.navigate().to(getPath());
}
public void realm(String realmName) {
this.realmName = realmName;
}
public String getPath() {
return Urls.accountFederatedIdentityPage(getAuthServerRoot(), realmName).toString();
}
@Override
public boolean isCurrent() {
return driver.getTitle().contains("Account Management") && driver.getPageSource().contains("Federated Identities");
}
public void clickAddProvider(String providerId) {
driver.findElement(By.id("add-" + providerId)).click();
}
public void clickRemoveProvider(String providerId) {
driver.findElement(By.id("remove-" + providerId)).click();
}
public String getError() {
return errorMessage.getText();
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.keycloak.services.Urls;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AccountLogPage extends AbstractAccountPage {
public boolean isCurrent() {
return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().endsWith("/account/log");
}
private String getPath() {
return Urls.accountLogPage(getAuthServerRoot(), "test").toString();
}
public void open() {
driver.navigate().to(getPath());
}
public List<List<String>> getEvents() {
List<List<String>> table = new LinkedList<List<String>>();
for (WebElement r : driver.findElements(By.tagName("tr"))) {
List<String> row = new LinkedList<String>();
for (WebElement col : r.findElements(By.tagName("td"))) {
row.add(col.getText());
}
table.add(row);
}
table.remove(0);
return table;
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.keycloak.services.resources.AccountService;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import javax.ws.rs.core.UriBuilder;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AccountPasswordPage extends AbstractAccountPage {
@FindBy(id = "password")
private WebElement passwordInput;
@FindBy(id = "password-new")
private WebElement newPasswordInput;
@FindBy(id = "password-confirm")
private WebElement passwordConfirmInput;
@FindBy(className = "btn-primary")
private WebElement submitButton;
private String realmName = "test";
public void changePassword(String password, String newPassword, String passwordConfirm) {
passwordInput.sendKeys(password);
newPasswordInput.sendKeys(newPassword);
passwordConfirmInput.sendKeys(passwordConfirm);
submitButton.click();
}
public void changePassword(String newPassword, String passwordConfirm) {
newPasswordInput.sendKeys(newPassword);
passwordConfirmInput.sendKeys(passwordConfirm);
submitButton.click();
}
public boolean isCurrent() {
return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().split("\\?")[0].endsWith("/account/password");
}
public void open() {
driver.navigate().to(getPath());
}
public void realm(String realmName) {
this.realmName = realmName;
}
public String getPath() {
return AccountService.passwordUrl(UriBuilder.fromUri(getAuthServerRoot())).build(this.realmName).toString();
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.keycloak.services.Urls;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AccountSessionsPage extends AbstractAccountPage {
private String realmName = "test";
@FindBy(id = "logout-all-sessions")
private WebElement logoutAllLink;
public boolean isCurrent() {
return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().endsWith("/account/sessions");
}
public void realm(String realmName) {
this.realmName = realmName;
}
public String getPath() {
return Urls.accountSessionsPage(getAuthServerRoot(), realmName).toString();
}
public void open() {
driver.navigate().to(getPath());
}
public void logoutAll() {
logoutAllLink.click();
}
public List<List<String>> getSessions() {
List<List<String>> table = new LinkedList<List<String>>();
for (WebElement r : driver.findElements(By.tagName("tr"))) {
List<String> row = new LinkedList<String>();
for (WebElement col : r.findElements(By.tagName("td"))) {
row.add(col.getText());
}
table.add(row);
}
table.remove(0);
return table;
}
}

View file

@ -0,0 +1,67 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.keycloak.services.resources.AccountService;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import javax.ws.rs.core.UriBuilder;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AccountTotpPage extends AbstractAccountPage {
@FindBy(id = "totpSecret")
private WebElement totpSecret;
@FindBy(id = "totp")
private WebElement totpInput;
@FindBy(css = "button[type=\"submit\"]")
private WebElement submitButton;
@FindBy(id = "remove-mobile")
private WebElement removeLink;
private String getPath() {
return AccountService.totpUrl(UriBuilder.fromUri(getAuthServerRoot())).build("test").toString();
}
public void configure(String totp) {
totpInput.sendKeys(totp);
submitButton.click();
}
public String getTotpSecret() {
return totpSecret.getAttribute("value");
}
public boolean isCurrent() {
return driver.getTitle().contains("Account Management") && driver.getCurrentUrl().split("\\?")[0].endsWith("/account/totp");
}
public void open() {
driver.navigate().to(getPath());
}
public void removeTotp() {
removeLink.click();
}
}

View file

@ -0,0 +1,143 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.keycloak.services.resources.RealmsResource;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import javax.ws.rs.core.UriBuilder;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AccountUpdateProfilePage extends AbstractAccountPage {
@FindBy(id = "username")
private WebElement usernameInput;
@FindBy(id = "firstName")
private WebElement firstNameInput;
@FindBy(id = "lastName")
private WebElement lastNameInput;
@FindBy(id = "email")
private WebElement emailInput;
@FindBy(id = "referrer")
private WebElement backToApplicationLink;
@FindBy(css = "button[type=\"submit\"][value=\"Save\"]")
private WebElement submitButton;
@FindBy(css = "button[type=\"submit\"][value=\"Cancel\"]")
private WebElement cancelButton;
@FindBy(className = "alert-success")
private WebElement successMessage;
@FindBy(className = "alert-error")
private WebElement errorMessage;
private String getPath() {
return RealmsResource.accountUrl(UriBuilder.fromUri(getAuthServerRoot())).build("test").toString();
}
public void updateProfile(String firstName, String lastName, String email) {
firstNameInput.clear();
firstNameInput.sendKeys(firstName);
lastNameInput.clear();
lastNameInput.sendKeys(lastName);
emailInput.clear();
emailInput.sendKeys(email);
submitButton.click();
}
public void updateProfile(String username, String firstName, String lastName, String email) {
usernameInput.clear();
usernameInput.sendKeys(username);
firstNameInput.clear();
firstNameInput.sendKeys(firstName);
lastNameInput.clear();
lastNameInput.sendKeys(lastName);
emailInput.clear();
emailInput.sendKeys(email);
submitButton.click();
}
public void updateUsername(String username) {
usernameInput.clear();
usernameInput.sendKeys(username);
submitButton.click();
}
public void updateEmail(String email) {
emailInput.clear();
emailInput.sendKeys(email);
submitButton.click();
}
public void clickCancel() {
cancelButton.click();
}
public String getUsername() {
return usernameInput.getAttribute("value");
}
public String getFirstName() {
return firstNameInput.getAttribute("value");
}
public String getLastName() {
return lastNameInput.getAttribute("value");
}
public String getEmail() {
return emailInput.getAttribute("value");
}
public boolean isCurrent() {
return driver.getTitle().contains("Account Management") && driver.getPageSource().contains("Edit Account");
}
public void open() {
driver.navigate().to(getPath());
}
public void backToApplication() {
backToApplicationLink.click();
}
public String getSuccess(){
return successMessage.getText();
}
public String getError() {
return errorMessage.getText();
}
public boolean isPasswordUpdateSupported() {
return driver.getPageSource().contains(getPath() + "/password");
}
}

View file

@ -0,0 +1,67 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.keycloak.OAuth2Constants;
import org.keycloak.protocol.oidc.OIDCLoginProtocolService;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import javax.ws.rs.core.UriBuilder;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class AppPage extends AbstractPage {
public static final String AUTH_SERVER_URL = "http://localhost:8081/auth";
public static final String baseUrl = "http://localhost:8081/app";
@FindBy(id = "account")
private WebElement accountLink;
@Override
public void open() {
driver.navigate().to(baseUrl);
}
@Override
public boolean isCurrent() {
return driver.getCurrentUrl().startsWith(baseUrl);
}
public RequestType getRequestType() {
return RequestType.valueOf(driver.getTitle());
}
public void openAccount() {
accountLink.click();
}
public enum RequestType {
AUTH_RESPONSE, LOGOUT_REQUEST, APP_REQUEST
}
public void logout() {
String logoutUri = OIDCLoginProtocolService.logoutUrl(UriBuilder.fromUri(AUTH_SERVER_URL))
.queryParam(OAuth2Constants.REDIRECT_URI,baseUrl).build("test").toString();
driver.navigate().to(logoutUri);
}
}

View file

@ -0,0 +1,43 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class BypassKerberosPage extends AbstractPage {
@FindBy(name = "continue")
private WebElement continueButton;
public boolean isCurrent() {
return driver.getTitle().equals("Log in to test") || driver.getTitle().equals("Anmeldung bei test");
}
public void clickContinue() {
continueButton.click();
}
@Override
public void open() throws Exception {
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.keycloak.testsuite.util.OAuthClient;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class ErrorPage extends AbstractPage {
@ArquillianResource
protected OAuthClient oauth;
@FindBy(className = "instruction")
private WebElement errorMessage;
@FindBy(id = "backToApplication")
private WebElement backToApplicationLink;
public String getError() {
return errorMessage.getText();
}
public void clickBackToApplication() {
backToApplicationLink.click();
}
public boolean isCurrent() {
return driver.getTitle() != null && driver.getTitle().equals("We're sorry...");
}
@Override
public void open() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class IdpConfirmLinkPage extends AbstractPage {
@FindBy(id = "updateProfile")
private WebElement updateProfileButton;
@FindBy(id = "linkAccount")
private WebElement linkAccountButton;
@FindBy(className = "alert-error")
private WebElement message;
@Override
public boolean isCurrent() {
return driver.getTitle().equals("Account already exists");
}
public String getMessage() {
return message.getText();
}
public void clickReviewProfile() {
updateProfileButton.click();
}
public void clickLinkAccount() {
linkAccountButton.click();
}
@Override
public void open() throws Exception {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class IdpLinkEmailPage extends AbstractPage {
@FindBy(id = "instruction1")
private WebElement message;
@Override
public boolean isCurrent() {
return driver.getTitle().startsWith("Link ");
}
@Override
public void open() throws Exception {
throw new UnsupportedOperationException();
}
public String getMessage() {
return message.getText();
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.keycloak.testsuite.util.OAuthClient;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class InfoPage extends AbstractPage {
@ArquillianResource
protected OAuthClient oauth;
@FindBy(className = "instruction")
private WebElement infoMessage;
public String getInfo() {
return infoMessage.getText();
}
public boolean isCurrent() {
return driver.getPageSource().contains("kc-info-message");
}
@Override
public void open() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,53 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class LoginConfigTotpPage extends AbstractPage {
@FindBy(id = "totpSecret")
private WebElement totpSecret;
@FindBy(id = "totp")
private WebElement totpInput;
@FindBy(css = "input[type=\"submit\"]")
private WebElement submitButton;
public void configure(String totp) {
totpInput.sendKeys(totp);
submitButton.click();
}
public String getTotpSecret() {
return totpSecret.getAttribute("value");
}
public boolean isCurrent() {
return driver.getTitle().equals("Mobile Authenticator Setup");
}
public void open() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,190 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.keycloak.testsuite.util.OAuthClient;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class LoginPage extends AbstractPage {
@ArquillianResource
protected OAuthClient oauth;
@FindBy(id = "username")
private WebElement usernameInput;
@FindBy(id = "password")
private WebElement passwordInput;
@FindBy(id = "totp")
private WebElement totp;
@FindBy(id = "rememberMe")
private WebElement rememberMe;
@FindBy(name = "login")
private WebElement submitButton;
@FindBy(name = "cancel")
private WebElement cancelButton;
@FindBy(linkText = "Register")
private WebElement registerLink;
@FindBy(linkText = "Forgot Password?")
private WebElement resetPasswordLink;
@FindBy(linkText = "Username")
private WebElement recoverUsernameLink;
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
@FindBy(className = "alert-warning")
private WebElement loginWarningMessage;
@FindBy(className = "alert-success")
private WebElement loginSuccessMessage;
@FindBy(className = "alert-info")
private WebElement loginInfoMessage;
@FindBy(id = "kc-current-locale-link")
private WebElement languageText;
@FindBy(id = "kc-locale-dropdown")
private WebElement localeDropdown;
public void login(String username, String password) {
usernameInput.clear();
usernameInput.sendKeys(username);
passwordInput.clear();
passwordInput.sendKeys(password);
submitButton.click();
}
public void login(String password) {
passwordInput.clear();
passwordInput.sendKeys(password);
submitButton.click();
}
public void missingPassword(String username) {
usernameInput.clear();
usernameInput.sendKeys(username);
passwordInput.clear();
submitButton.click();
}
public void missingUsername() {
usernameInput.clear();
submitButton.click();
}
public String getUsername() {
return usernameInput.getAttribute("value");
}
public boolean isUsernameInputEnabled() {
return usernameInput.isEnabled();
}
public String getPassword() {
return passwordInput.getAttribute("value");
}
public void cancel() {
cancelButton.click();
}
public String getError() {
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
}
public String getSuccessMessage() {
return loginSuccessMessage != null ? loginSuccessMessage.getText() : null;
}
public String getInfoMessage() {
return loginInfoMessage != null ? loginInfoMessage.getText() : null;
}
public boolean isCurrent() {
return driver.getTitle().equals("Log in to test") || driver.getTitle().equals("Anmeldung bei test");
}
public void clickRegister() {
registerLink.click();
}
public void clickSocial(String providerId) {
WebElement socialButton = findSocialButton(providerId);
socialButton.click();
}
public WebElement findSocialButton(String providerId) {
String id = "zocial-" + providerId;
return this.driver.findElement(By.id(id));
}
public void resetPassword() {
resetPasswordLink.click();
}
public void recoverUsername() {
recoverUsernameLink.click();
}
public void setRememberMe(boolean enable) {
boolean current = rememberMe.isSelected();
if (current != enable) {
rememberMe.click();
}
}
public boolean isRememberMeChecked() {
return rememberMe.isSelected();
}
@Override
public void open() {
oauth.openLoginForm();
assertCurrent();
}
public String getLanguageDropdownText() {
return languageText.getText();
}
public void openLanguage(String language){
localeDropdown.findElement(By.linkText(language)).click();
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class LoginPasswordResetPage extends AbstractPage {
@FindBy(id = "username")
private WebElement usernameInput;
@FindBy(css = "input[type=\"submit\"]")
private WebElement submitButton;
@FindBy(className = "alert-success")
private WebElement emailSuccessMessage;
@FindBy(className = "alert-error")
private WebElement emailErrorMessage;
@FindBy(partialLinkText = "Back to Login")
private WebElement backToLogin;
public void changePassword(String username) {
usernameInput.sendKeys(username);
submitButton.click();
}
public boolean isCurrent() {
return driver.getTitle().equals("Forgot Your Password?");
}
public void open() {
throw new UnsupportedOperationException();
}
public String getSuccessMessage() {
return emailSuccessMessage != null ? emailSuccessMessage.getText() : null;
}
public String getErrorMessage() {
return emailErrorMessage != null ? emailErrorMessage.getText() : null;
}
public void backToLogin() {
backToLogin.click();
}
}

View file

@ -0,0 +1,58 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class LoginPasswordUpdatePage extends AbstractPage {
@FindBy(id = "password-new")
private WebElement newPasswordInput;
@FindBy(id = "password-confirm")
private WebElement passwordConfirmInput;
@FindBy(css = "input[type=\"submit\"]")
private WebElement submitButton;
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
public void changePassword(String newPassword, String passwordConfirm) {
newPasswordInput.sendKeys(newPassword);
passwordConfirmInput.sendKeys(passwordConfirm);
submitButton.click();
}
public boolean isCurrent() {
return driver.getTitle().equals("Update password");
}
public void open() {
throw new UnsupportedOperationException();
}
public String getError() {
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class LoginRecoverUsernamePage extends AbstractPage {
@FindBy(id = "email")
private WebElement emailInput;
@FindBy(css = "input[type=\"submit\"]")
private WebElement submitButton;
@FindBy(className = "alert-error")
private WebElement emailErrorMessage;
public void recoverUsername(String email) {
emailInput.sendKeys(email);
submitButton.click();
}
public boolean isCurrent() {
return driver.getTitle().equals("Forgot Your Username?");
}
public void open() {
throw new UnsupportedOperationException();
}
public String getMessage() {
return emailErrorMessage != null ? emailErrorMessage.getText() : null;
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class LoginTotpPage extends AbstractPage {
@FindBy(id = "totp")
private WebElement totpInput;
@FindBy(id = "password-token")
private WebElement passwordToken;
@FindBy(css = "input[type=\"submit\"]")
private WebElement submitButton;
@FindBy(id = "kc-cancel")
private WebElement cancelButton;
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
public void login(String totp) {
totpInput.clear();
if (totp != null) totpInput.sendKeys(totp);
submitButton.click();
}
public void cancel() {
cancelButton.click();
}
public String getError() {
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
}
public boolean isCurrent() {
if (driver.getTitle().startsWith("Log in to ")) {
try {
driver.findElement(By.id("totp"));
return true;
} catch (Throwable t) {
}
}
return false;
}
@Override
public void open() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class LoginUpdateProfileEditUsernameAllowedPage extends LoginUpdateProfilePage {
@FindBy(id = "username")
private WebElement usernameInput;
public void update(String firstName, String lastName, String email, String username) {
usernameInput.clear();
usernameInput.sendKeys(username);
update(firstName, lastName, email);
}
public String getUsername() {
return usernameInput.getAttribute("value");
}
public boolean isCurrent() {
return driver.getTitle().equals("Update Account Information");
}
@Override
public void open() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class LoginUpdateProfilePage extends AbstractPage {
@FindBy(id = "firstName")
private WebElement firstNameInput;
@FindBy(id = "lastName")
private WebElement lastNameInput;
@FindBy(id = "email")
private WebElement emailInput;
@FindBy(css = "input[type=\"submit\"]")
private WebElement submitButton;
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
public void update(String firstName, String lastName, String email) {
firstNameInput.clear();
firstNameInput.sendKeys(firstName);
lastNameInput.clear();
lastNameInput.sendKeys(lastName);
emailInput.clear();
emailInput.sendKeys(email);
submitButton.click();
}
public String getError() {
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
}
public String getFirstName() {
return firstNameInput.getAttribute("value");
}
public String getLastName() {
return lastNameInput.getAttribute("value");
}
public String getEmail() {
return emailInput.getAttribute("value");
}
public boolean isCurrent() {
return driver.getTitle().equals("Update Account Information");
}
@Override
public void open() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class OAuthGrantPage extends AbstractPage {
@FindBy(css = "input[name=\"accept\"]")
private WebElement acceptButton;
@FindBy(css = "input[name=\"cancel\"]")
private WebElement cancelButton;
public void accept(){
acceptButton.click();
}
public void cancel(){
cancelButton.click();
}
@Override
public boolean isCurrent() {
return driver.getTitle().equals("Grant Access");
}
@Override
public void open() {
}
}

View file

@ -0,0 +1,174 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.junit.Assert;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class RegisterPage extends AbstractPage {
@FindBy(id = "firstName")
private WebElement firstNameInput;
@FindBy(id = "lastName")
private WebElement lastNameInput;
@FindBy(id = "email")
private WebElement emailInput;
@FindBy(id = "username")
private WebElement usernameInput;
@FindBy(id = "password")
private WebElement passwordInput;
@FindBy(id = "password-confirm")
private WebElement passwordConfirmInput;
@FindBy(css = "input[type=\"submit\"]")
private WebElement submitButton;
@FindBy(className = "alert-error")
private WebElement loginErrorMessage;
@FindBy(className = "instruction")
private WebElement loginInstructionMessage;
public void register(String firstName, String lastName, String email, String username, String password, String passwordConfirm) {
firstNameInput.clear();
if (firstName != null) {
firstNameInput.sendKeys(firstName);
}
lastNameInput.clear();
if (lastName != null) {
lastNameInput.sendKeys(lastName);
}
emailInput.clear();
if (email != null) {
emailInput.sendKeys(email);
}
usernameInput.clear();
if (username != null) {
usernameInput.sendKeys(username);
}
passwordInput.clear();
if (password != null) {
passwordInput.sendKeys(password);
}
passwordConfirmInput.clear();
if (passwordConfirm != null) {
passwordConfirmInput.sendKeys(passwordConfirm);
}
submitButton.click();
}
public void registerWithEmailAsUsername(String firstName, String lastName, String email, String password, String passwordConfirm) {
firstNameInput.clear();
if (firstName != null) {
firstNameInput.sendKeys(firstName);
}
lastNameInput.clear();
if (lastName != null) {
lastNameInput.sendKeys(lastName);
}
emailInput.clear();
if (email != null) {
emailInput.sendKeys(email);
}
try {
usernameInput.clear();
Assert.fail("Form must be without username field");
} catch (NoSuchElementException e) {
// OK
}
passwordInput.clear();
if (password != null) {
passwordInput.sendKeys(password);
}
passwordConfirmInput.clear();
if (passwordConfirm != null) {
passwordConfirmInput.sendKeys(passwordConfirm);
}
submitButton.click();
}
public String getError() {
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
}
public String getInstruction() {
try {
return loginInstructionMessage != null ? loginInstructionMessage.getText() : null;
} catch (NoSuchElementException e){
// OK
}
return null;
}
public String getFirstName() {
return firstNameInput.getAttribute("value");
}
public String getLastName() {
return lastNameInput.getAttribute("value");
}
public String getEmail() {
return emailInput.getAttribute("value");
}
public String getUsername() {
return usernameInput.getAttribute("value");
}
public String getPassword() {
return passwordInput.getAttribute("value");
}
public String getPasswordConfirm() {
return passwordConfirmInput.getAttribute("value");
}
public boolean isCurrent() {
return driver.getTitle().equals("Register with test");
}
@Override
public void open() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class TermsAndConditionsPage extends AbstractPage {
@FindBy(id = "kc-accept")
private WebElement submitButton;
@FindBy(id = "kc-decline")
private WebElement cancelButton;
public boolean isCurrent() {
return driver.getTitle().equals("Terms and Conditions");
}
public void acceptTerms() {
submitButton.click();
}
public void declineTerms() {
cancelButton.click();
}
@Override
public void open() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class ValidatePassworrdEmailResetPage extends AbstractPage {
@FindBy(id = "key")
private WebElement keyInput;
@FindBy(id="kc-submit")
private WebElement submitButton;
@FindBy(id="kc-cancel")
private WebElement cancelButton;
@FindBy(className = "alert-success")
private WebElement emailSuccessMessage;
@FindBy(className = "alert-error")
private WebElement emailErrorMessage;
public void submitCode(String code) {
keyInput.sendKeys(code);
submitButton.click();
}
public void cancel() {
cancelButton.click();
}
public boolean isCurrent() {
return driver.getTitle().equals("Forgot Your Password?");
}
public void open() {
throw new UnsupportedOperationException();
}
public String getSuccessMessage() {
return emailSuccessMessage != null ? emailSuccessMessage.getText() : null;
}
public String getErrorMessage() {
return emailErrorMessage != null ? emailErrorMessage.getText() : null;
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.keycloak.testsuite.util.OAuthClient;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
/**
* @author <a href="mailto:vrockai@redhat.com">Viliam Rockai</a>
*/
public class VerifyEmailPage extends AbstractPage {
@ArquillianResource
protected OAuthClient oauth;
@FindBy(linkText = "Click here")
private WebElement resendEmailLink;
@Override
public void open() {
}
public boolean isCurrent() {
return driver.getTitle().equals("Email verification");
}
public void clickResendEmail() {
resendEmailLink.click();
}
public String getResendEmailLink() {
return resendEmailLink.getAttribute("href");
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.util;
import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetup;
import org.junit.rules.ExternalResource;
import org.keycloak.models.RealmModel;
import javax.mail.internet.MimeMessage;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class GreenMailRule extends ExternalResource {
private GreenMail greenMail;
@Override
protected void before() throws Throwable {
ServerSetup setup = new ServerSetup(3025, "localhost", "smtp");
greenMail = new GreenMail(setup);
greenMail.start();
}
@Override
protected void after() {
if (greenMail != null) {
// Suppress error from GreenMail on shutdown
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
if (!(e.getCause() instanceof SocketException && t.getClass().getName()
.equals("com.icegreen.greenmail.smtp.SmtpHandler"))) {
System.err.print("Exception in thread \"" + t.getName() + "\" ");
e.printStackTrace(System.err);
}
}
});
greenMail.stop();
}
}
public void configureRealm(RealmModel realm) {
Map<String, String> config = new HashMap<>();
config.put("from", "auto@keycloak.org");
config.put("host", "localhost");
config.put("port", "3025");
realm.setSmtpConfig(config);
}
public MimeMessage[] getReceivedMessages() {
return greenMail.getReceivedMessages();
}
}

View file

@ -0,0 +1,66 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.util;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.junit.Assert.assertEquals;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class MailUtils {
private static Pattern mailPattern = Pattern.compile("http[^\\s\"]*");
public static String getLink(String body) {
Matcher matcher = mailPattern.matcher(body);
if (matcher.find()) {
return matcher.group();
}
throw new AssertionError("No link found in " + body);
}
public static String getPasswordResetEmailLink(MimeMessage message) throws IOException, MessagingException {
Multipart multipart = (Multipart) message.getContent();
final String textContentType = multipart.getBodyPart(0).getContentType();
assertEquals("text/plain; charset=UTF-8", textContentType);
final String textBody = (String) multipart.getBodyPart(0).getContent();
final String textChangePwdUrl = getLink(textBody);
final String htmlContentType = multipart.getBodyPart(1).getContentType();
assertEquals("text/html; charset=UTF-8", htmlContentType);
final String htmlBody = (String) multipart.getBodyPart(1).getContent();
final String htmlChangePwdUrl = getLink(htmlBody);
assertEquals(htmlChangePwdUrl, textChangePwdUrl);
return htmlChangePwdUrl;
}
}

View file

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.util;
import org.apache.commons.io.IOUtils;
@ -29,6 +30,7 @@ import org.apache.http.message.BasicNameValuePair;
import org.junit.Assert;
import org.keycloak.OAuth2Constants;
import org.keycloak.RSATokenVerifier;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.common.VerificationException;
import org.keycloak.common.util.PemUtils;
import org.keycloak.constants.AdapterConstants;
@ -64,6 +66,8 @@ public class OAuthClient {
public static final String AUTH_SERVER_ROOT = SERVER_ROOT + "/auth";
public static final String APP_ROOT = AUTH_SERVER_ROOT + "/realms/master/app";
private Keycloak adminClient;
private WebDriver driver;
private String baseUrl = AUTH_SERVER_ROOT;
@ -80,20 +84,18 @@ public class OAuthClient {
private String uiLocales = null;
private PublicKey realmPublicKey;
private String clientSessionState;
private String clientSessionHost;
public OAuthClient(WebDriver driver, String publicKey) {
this.driver = driver;
private Map<String, PublicKey> publicKeys = new HashMap<>();
try {
realmPublicKey = PemUtils.decodePublicKey(publicKey);
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve realm public key", e);
}
public void setAdminClient(Keycloak adminClient) {
this.adminClient = adminClient;
}
public void setDriver(WebDriver driver) {
this.driver = driver;
}
public AuthorizationCodeResponse doLogin(String username, String password) {
@ -373,7 +375,7 @@ public class OAuthClient {
public AccessToken verifyToken(String token) {
try {
return RSATokenVerifier.verifyToken(token, realmPublicKey, baseUrl + "/realms/" + realm);
return RSATokenVerifier.verifyToken(token, getRealmPublicKey(realm), baseUrl + "/realms/" + realm);
} catch (VerificationException e) {
throw new RuntimeException("Failed to verify token", e);
}
@ -382,7 +384,7 @@ public class OAuthClient {
public RefreshToken verifyRefreshToken(String refreshToken) {
try {
JWSInput jws = new JWSInput(refreshToken);
if (!RSAProvider.verify(jws, realmPublicKey)) {
if (!RSAProvider.verify(jws, getRealmPublicKey(realm))) {
throw new RuntimeException("Invalid refresh token");
}
return jws.readJsonContent(RefreshToken.class);
@ -497,10 +499,6 @@ public class OAuthClient {
this.realm = realm;
return this;
}
public OAuthClient realmPublicKey(PublicKey key) {
this.realmPublicKey = key;
return this;
}
public OAuthClient clientId(String clientId) {
this.clientId = clientId;
@ -642,4 +640,19 @@ public class OAuthClient {
}
}
public PublicKey getRealmPublicKey(String realm) {
if (!publicKeys.containsKey(realm)) {
String publicKeyPem = adminClient.realms().realm(realm).toRepresentation().getPublicKey();
PublicKey publicKey = null;
try {
publicKey = PemUtils.decodePublicKey(publicKeyPem);
} catch (Exception e) {
throw new RuntimeException(e);
}
publicKeys.put(realm, publicKey);
}
return publicKeys.get(realm);
}
}

View file

@ -19,7 +19,6 @@ package org.keycloak.testsuite;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.io.IOUtils;
import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.testsuite.arquillian.TestContext;
@ -28,13 +27,10 @@ import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.NotFoundException;
import org.jboss.arquillian.container.test.api.RunAsClient;
@ -61,6 +57,7 @@ import org.keycloak.testsuite.arquillian.AuthServerTestEnricher;
import org.keycloak.testsuite.arquillian.SuiteContext;
import org.keycloak.testsuite.auth.page.WelcomePage;
import org.keycloak.testsuite.util.DeleteMeOAuthClient;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.util.JsonSerialization;
import org.openqa.selenium.WebDriver;
import org.keycloak.testsuite.auth.page.AuthServer;
@ -97,7 +94,10 @@ public abstract class AbstractKeycloakTest {
protected Keycloak adminClient;
protected DeleteMeOAuthClient oauthClient;
@ArquillianResource
protected OAuthClient oauthClient;
protected DeleteMeOAuthClient deleteMeOAuthClient;
protected List<RealmRepresentation> testRealmReps;
@ -132,7 +132,7 @@ public abstract class AbstractKeycloakTest {
public void beforeAbstractKeycloakTest() {
adminClient = Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth",
MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
oauthClient = new DeleteMeOAuthClient(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
deleteMeOAuthClient = new DeleteMeOAuthClient(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth");
adminUser = createAdminUserRepresentation();
@ -150,6 +150,9 @@ public abstract class AbstractKeycloakTest {
}
importTestRealms();
oauthClient.setAdminClient(adminClient);
oauthClient.setDriver(driver);
}
@After
@ -346,4 +349,12 @@ public abstract class AbstractKeycloakTest {
return constantsProperties;
}
public URI getAuthServerRoot() {
try {
return KeycloakUriBuilder.fromUri(suiteContext.getAuthServerInfo().getContextRoot().toURI()).path("/auth/").build();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}

View file

@ -17,12 +17,11 @@
package org.keycloak.testsuite;
import org.keycloak.testsuite.util.OAuthClient;
import java.util.List;
import org.junit.Before;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import java.util.List;
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
/**
@ -33,8 +32,6 @@ import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
*/
public abstract class TestRealmKeycloakTest extends AbstractKeycloakTest {
protected OAuthClient oauth;
protected ClientRepresentation findTestApp(RealmRepresentation testRealm) {
for (ClientRepresentation client : testRealm.getClients()) {
if (client.getClientId().equals("test-app")) return client;
@ -47,8 +44,6 @@ public abstract class TestRealmKeycloakTest extends AbstractKeycloakTest {
public void addTestRealms(List<RealmRepresentation> testRealms) {
RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class);
oauth = new OAuthClient(driver, testRealm.getPublicKey());
testRealms.add(testRealm);
configureTestRealm(testRealm);

View file

@ -101,12 +101,12 @@ public class ClientTest extends AbstractAdminTest {
@Test
public void getClientSessions() throws Exception {
OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", "test-user@localhost", "password");
OAuthClient.AccessTokenResponse response = oauthClient.doGrantAccessTokenRequest("password", "test-user@localhost", "password");
assertEquals(200, response.getStatusCode());
OAuthClient.AuthorizationCodeResponse codeResponse = oauth.doLogin("test-user@localhost", "password");
OAuthClient.AuthorizationCodeResponse codeResponse = oauthClient.doLogin("test-user@localhost", "password");
OAuthClient.AccessTokenResponse response2 = oauth.doAccessTokenRequest(codeResponse.getCode(), "password");
OAuthClient.AccessTokenResponse response2 = oauthClient.doAccessTokenRequest(codeResponse.getCode(), "password");
assertEquals(200, response2.getStatusCode());
ClientResource app = ApiUtil.findClientByClientId(adminClient.realm("test"), "test-app");

View file

@ -17,21 +17,29 @@
package org.keycloak.testsuite.admin;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.page.Page;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.resource.IdentityProviderResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.*;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.ErrorRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.resources.RealmsResource;
import org.keycloak.testsuite.Constants;
import org.keycloak.testsuite.actions.RequiredActionEmailVerificationTest;
import org.keycloak.testsuite.forms.ResetPasswordTest;
import org.keycloak.testsuite.pages.*;
import org.keycloak.testsuite.rule.GreenMailRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testsuite.page.LoginPasswordUpdatePage;
import org.keycloak.testsuite.pages.InfoPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.util.GreenMailRule;
import org.keycloak.testsuite.util.MailUtils;
import org.keycloak.testsuite.util.OAuthClient;
import org.openqa.selenium.WebDriver;
import javax.mail.MessagingException;
@ -39,39 +47,37 @@ import javax.mail.internet.MimeMessage;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.io.IOException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assert.*;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class UserTest extends AbstractClientTest {
@Rule
public WebRule webRule = new WebRule(this);
public class UserTest extends AbstractAdminTest {
@Rule
public GreenMailRule greenMail = new GreenMailRule();
@WebResource
protected LoginPasswordUpdatePage passwordUpdatePage;
@WebResource
@Drone
protected WebDriver driver;
@WebResource
@Page
protected LoginPasswordUpdatePage passwordUpdatePage;
@ArquillianResource
protected OAuthClient oAuthClient;
@Page
protected InfoPage infoPage;
@WebResource
@Page
protected LoginPage loginPage;
public String createUser() {
@ -485,7 +491,7 @@ public class UserTest extends AbstractClientTest {
MimeMessage message = greenMail.getReceivedMessages()[0];
String link = ResetPasswordTest.getPasswordResetEmailLink(message);
String link = MailUtils.getPasswordResetEmailLink(message);
driver.navigate().to(link);
@ -546,9 +552,9 @@ public class UserTest extends AbstractClientTest {
}
user.sendVerifyEmail();
assertEquals(1, greenMail.getReceivedMessages().length);
Assert.assertEquals(1, greenMail.getReceivedMessages().length);
String link = RequiredActionEmailVerificationTest.getPasswordResetEmailLink(greenMail.getReceivedMessages()[0]);
String link = MailUtils.getPasswordResetEmailLink(greenMail.getReceivedMessages()[0]);
driver.navigate().to(link);
@ -659,7 +665,7 @@ public class UserTest extends AbstractClientTest {
realm.users().get(userId).resetPassword(cred);
String accountUrl = RealmsResource.accountUrl(UriBuilder.fromUri(Constants.AUTH_SERVER_ROOT)).build(REALM_NAME).toString();
String accountUrl = RealmsResource.accountUrl(UriBuilder.fromUri(getAuthServerRoot())).build(REALM_NAME).toString();
driver.navigate().to(accountUrl);

View file

@ -120,7 +120,7 @@ public abstract class AbstractClientRegistrationTest extends AbstractKeycloakTes
}
private String getToken(String username, String password) {
return oauthClient.getToken(REALM_NAME, Constants.ADMIN_CLI_CLIENT_ID, null, username, password).getToken();
return deleteMeOAuthClient.getToken(REALM_NAME, Constants.ADMIN_CLI_CLIENT_ID, null, username, password).getToken();
}
}

View file

@ -62,7 +62,7 @@ public class ClientRegistrationTest extends AbstractClientRegistrationTest {
public void registerClientInMasterRealm() throws ClientRegistrationException {
ClientRegistration masterReg = ClientRegistration.create().url(suiteContext.getAuthServerInfo().getContextRoot() + "/auth", "master").build();
String token = oauthClient.getToken("master", Constants.ADMIN_CLI_CLIENT_ID, null, "admin", "admin").getToken();
String token = deleteMeOAuthClient.getToken("master", Constants.ADMIN_CLI_CLIENT_ID, null, "admin", "admin").getToken();
masterReg.auth(Auth.token(token));
ClientRepresentation client = new ClientRepresentation();

View file

@ -50,7 +50,7 @@ public abstract class AbstractGroupTest extends AbstractKeycloakTest {
AccessToken login(String login, String clientId, String clientSecret, String userId) throws Exception {
AccessTokenResponse tokenResponse = oauthClient.getToken("test", clientId, clientSecret, login, "password");
AccessTokenResponse tokenResponse = deleteMeOAuthClient.getToken("test", clientId, clientSecret, login, "password");
String accessToken = tokenResponse.getToken();
String refreshToken = tokenResponse.getRefreshToken();

View file

@ -108,10 +108,10 @@ public class TokenIntrospectionTest extends TestRealmKeycloakTest {
@Test
public void testConfidentialClientCredentialsBasicAuthentication() throws Exception {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
oauthClient.doLogin("test-user@localhost", "password");
String code = oauthClient.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauthClient.doAccessTokenRequest(code, "password");
String tokenResponse = oauthClient.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(tokenResponse);
@ -144,10 +144,10 @@ public class TokenIntrospectionTest extends TestRealmKeycloakTest {
@Test
public void testInvalidClientCredentials() throws Exception {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "bad_credential", accessTokenResponse.getAccessToken());
oauthClient.doLogin("test-user@localhost", "password");
String code = oauthClient.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauthClient.doAccessTokenRequest(code, "password");
String tokenResponse = oauthClient.introspectAccessTokenWithClientCredential("confidential-cli", "bad_credential", accessTokenResponse.getAccessToken());
assertEquals("{\"error_description\":\"Authentication failed.\",\"error\":\"invalid_request\"}", tokenResponse);
@ -156,12 +156,12 @@ public class TokenIntrospectionTest extends TestRealmKeycloakTest {
@Test
public void testIntrospectRefreshToken() throws Exception {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
oauthClient.doLogin("test-user@localhost", "password");
String code = oauthClient.getCurrentQuery().get(OAuth2Constants.CODE);
EventRepresentation loginEvent = events.expectLogin().assertEvent();
String sessionId = loginEvent.getSessionId();
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
AccessTokenResponse accessTokenResponse = oauthClient.doAccessTokenRequest(code, "password");
String tokenResponse = oauthClient.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(tokenResponse);
@ -192,11 +192,11 @@ public class TokenIntrospectionTest extends TestRealmKeycloakTest {
@Test
public void testPublicClientCredentialsNotAllowed() throws Exception {
oauth.doLogin("test-user@localhost", "password");
oauthClient.doLogin("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("public-cli", "it_doesnt_matter", accessTokenResponse.getAccessToken());
String code = oauthClient.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauthClient.doAccessTokenRequest(code, "password");
String tokenResponse = oauthClient.introspectAccessTokenWithClientCredential("public-cli", "it_doesnt_matter", accessTokenResponse.getAccessToken());
assertEquals("{\"error_description\":\"Client not allowed.\",\"error\":\"invalid_request\"}", tokenResponse);
@ -205,9 +205,9 @@ public class TokenIntrospectionTest extends TestRealmKeycloakTest {
@Test
public void testInactiveAccessToken() throws Exception {
oauth.doLogin("test-user@localhost", "password");
oauthClient.doLogin("test-user@localhost", "password");
String inactiveAccessToken = "eyJhbGciOiJSUzI1NiJ9.eyJub25jZSI6IjczMGZjNjQ1LTBlMDQtNDE3Yi04MDY0LTkyYWIyY2RjM2QwZSIsImp0aSI6ImU5ZGU1NjU2LWUzMjctNDkxNC1hNjBmLTI1MzJlYjBiNDk4OCIsImV4cCI6MTQ1MjI4MTAwMCwibmJmIjowLCJpYXQiOjE0NTIyODA3MDAsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9hdXRoL3JlYWxtcy9leGFtcGxlIiwiYXVkIjoianMtY29uc29sZSIsInN1YiI6IjFkNzQ0MDY5LWYyOTgtNGU3Yy1hNzNiLTU1YzlhZjgzYTY4NyIsInR5cCI6IkJlYXJlciIsImF6cCI6ImpzLWNvbnNvbGUiLCJzZXNzaW9uX3N0YXRlIjoiNzc2YTA0OTktODNjNC00MDhkLWE5YjctYTZiYzQ5YmQ3MThjIiwiY2xpZW50X3Nlc3Npb24iOiJjN2Y5ODczOC05MDhlLTQxOWYtYTdkNC1kODYxYjRhYTI3NjkiLCJhbGxvd2VkLW9yaWdpbnMiOltdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsidXNlciJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJ2aWV3LXByb2ZpbGUiXX19LCJuYW1lIjoiU2FtcGxlIFVzZXIiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ1c2VyIiwiZ2l2ZW5fbmFtZSI6IlNhbXBsZSIsImZhbWlseV9uYW1lIjoiVXNlciIsImVtYWlsIjoic2FtcGxlLXVzZXJAZXhhbXBsZSJ9.YyPV74j9CqOG2Jmq692ZZpqycjNpUgtYVRfQJccS_FU84tGVXoKKsXKYeY2UJ1Y_bPiYG1I1J6JSXC8XqgQijCG7Nh7oK0yN74JbRN58HG75fvg6K9BjR6hgJ8mHT8qPrCux2svFucIMIZ180eoBoRvRstkidOhl_mtjT_i31fU";
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", inactiveAccessToken);
String tokenResponse = oauthClient.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", inactiveAccessToken);
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(tokenResponse);
@ -225,11 +225,11 @@ public class TokenIntrospectionTest extends TestRealmKeycloakTest {
@Test
public void testIntrospectAccessToken() throws Exception {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
oauthClient.doLogin("test-user@localhost", "password");
String code = oauthClient.getCurrentQuery().get(OAuth2Constants.CODE);
EventRepresentation loginEvent = events.expectLogin().assertEvent();
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
AccessTokenResponse accessTokenResponse = oauthClient.doAccessTokenRequest(code, "password");
String tokenResponse = oauthClient.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
TokenMetadataRepresentation rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
assertTrue(rep.isActive());
@ -242,12 +242,12 @@ public class TokenIntrospectionTest extends TestRealmKeycloakTest {
@Test
public void testIntrospectAccessTokenSessionInvalid() throws Exception {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
oauth.doLogout(accessTokenResponse.getRefreshToken(), "password");
oauthClient.doLogin("test-user@localhost", "password");
String code = oauthClient.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauthClient.doAccessTokenRequest(code, "password");
oauthClient.doLogout(accessTokenResponse.getRefreshToken(), "password");
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
String tokenResponse = oauthClient.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
TokenMetadataRepresentation rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
assertFalse(rep.isActive());
@ -260,18 +260,18 @@ public class TokenIntrospectionTest extends TestRealmKeycloakTest {
@Test
public void testIntrospectAccessTokenUserDisabled() throws Exception {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
oauthClient.doLogin("test-user@localhost", "password");
String code = oauthClient.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauthClient.doAccessTokenRequest(code, "password");
EventRepresentation loginEvent = events.expectLogin().assertEvent();
UserRepresentation userRep = new UserRepresentation();
try {
userRep.setEnabled(false);
adminClient.realm(oauth.getRealm()).users().get(loginEvent.getUserId()).update(userRep);
adminClient.realm(oauthClient.getRealm()).users().get(loginEvent.getUserId()).update(userRep);
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
String tokenResponse = oauthClient.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
TokenMetadataRepresentation rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
assertFalse(rep.isActive());
@ -282,20 +282,20 @@ public class TokenIntrospectionTest extends TestRealmKeycloakTest {
events.clear();
} finally {
userRep.setEnabled(true);
adminClient.realm(oauth.getRealm()).users().get(loginEvent.getUserId()).update(userRep);
adminClient.realm(oauthClient.getRealm()).users().get(loginEvent.getUserId()).update(userRep);
}
}
@Test
public void testIntrospectAccessTokenExpired() throws Exception {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code, "password");
oauthClient.doLogin("test-user@localhost", "password");
String code = oauthClient.getCurrentQuery().get(OAuth2Constants.CODE);
AccessTokenResponse accessTokenResponse = oauthClient.doAccessTokenRequest(code, "password");
try {
Time.setOffset(adminClient.realm(oauth.getRealm()).toRepresentation().getAccessTokenLifespan() + 1);
Time.setOffset(adminClient.realm(oauthClient.getRealm()).toRepresentation().getAccessTokenLifespan() + 1);
String tokenResponse = oauth.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
String tokenResponse = oauthClient.introspectAccessTokenWithClientCredential("confidential-cli", "secret1", accessTokenResponse.getAccessToken());
TokenMetadataRepresentation rep = JsonSerialization.readValue(tokenResponse, TokenMetadataRepresentation.class);
assertFalse(rep.isActive());

View file

@ -1,75 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.admin;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.admin.client.resource.ClientInitialAccessResource;
import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation;
import org.keycloak.representations.idm.ClientInitialAccessPresentation;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.List;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class ClientInitialAccessTest extends AbstractClientTest {
@Test
public void create() {
ClientInitialAccessResource resource = keycloak.realm(REALM_NAME).clientInitialAccess();
ClientInitialAccessPresentation access = resource.create(new ClientInitialAccessCreatePresentation(1000, 2));
Assert.assertEquals(new Integer(2), access.getCount());
Assert.assertEquals(new Integer(2), access.getRemainingCount());
Assert.assertEquals(new Integer(1000), access.getExpiration());
Assert.assertNotNull(access.getTimestamp());
Assert.assertNotNull(access.getToken());
ClientInitialAccessPresentation access2 = resource.create(new ClientInitialAccessCreatePresentation());
List<ClientInitialAccessPresentation> list = resource.list();
Assert.assertEquals(2, list.size());
for (ClientInitialAccessPresentation r : list) {
if (r.getId().equals(access.getId())) {
Assert.assertEquals(new Integer(2), r.getCount());
Assert.assertEquals(new Integer(2), r.getRemainingCount());
Assert.assertEquals(new Integer(1000), r.getExpiration());
Assert.assertNotNull(r.getTimestamp());
Assert.assertNull(r.getToken());
} else if(r.getId().equals(access2.getId())) {
Assert.assertEquals(new Integer(1), r.getCount());
Assert.assertEquals(new Integer(1), r.getRemainingCount());
Assert.assertEquals(new Integer(0), r.getExpiration());
Assert.assertNotNull(r.getTimestamp());
Assert.assertNull(r.getToken());
} else {
Assert.fail("Unexpected id");
}
}
resource.delete(access.getId());
resource.delete(access2.getId());
Assert.assertTrue(resource.list().isEmpty());
}
}