Merge pull request #2792 from ssilvert/migrate-forms

KEYCLOAK-2906 Migrate forms package to new testsuite
This commit is contained in:
Stian Thorgersen 2016-05-06 07:00:10 +02:00
commit 1d87d1cce1
25 changed files with 949 additions and 806 deletions

View file

@ -0,0 +1,38 @@
/*
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
*
* 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.drone;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.jboss.arquillian.drone.api.annotation.Qualifier;
/**
* Taken from Drone example https://docs.jboss.org/author/display/ARQ/Drone
* This allows you to have more than one instance of a Drone WebDriver.
*
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Qualifier
public @interface Different {
}

View file

@ -30,7 +30,7 @@ import javax.ws.rs.core.UriBuilder;
public class AppPage extends AbstractPage {
public static final String AUTH_SERVER_URL = "http://localhost:8180/auth";
public static final String baseUrl = "http://localhost:8180/auth/realms/master/app";
public static final String baseUrl = "http://localhost:8180/auth/realms/master/app/auth";
@FindBy(id = "account")
private WebElement accountLink;

View file

@ -21,6 +21,8 @@ import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import java.util.List;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.representations.idm.UserRepresentation;
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
@ -32,6 +34,36 @@ import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
*/
public abstract class TestRealmKeycloakTest extends AbstractKeycloakTest {
protected UserRepresentation findUserInRealmRep(RealmRepresentation testRealm, String userName) {
for (UserRepresentation user : testRealm.getUsers()) {
if (user.getUsername().equals(userName)) return user;
}
return null;
}
protected ClientRepresentation findClientInRealmRep(RealmRepresentation testRealm, String clientId) {
for (ClientRepresentation client : testRealm.getClients()) {
if (client.getClientId().equals(clientId)) return client;
}
return null;
}
protected RealmResource testRealm() {
return adminClient.realm("test");
}
protected UserRepresentation findUser(String userNameOrEmail) {
List<UserRepresentation> repList = testRealm().users().search(userNameOrEmail, -1, -1);
if (repList.size() != 1) throw new IllegalStateException("User search expected one result. Found " + repList.size() + " users.");
return repList.get(0);
}
protected void updateUser(UserRepresentation user) {
testRealm().users().get(user.getId()).update(user);
}
protected ClientRepresentation findTestApp(RealmRepresentation testRealm) {
for (ClientRepresentation client : testRealm.getClients()) {
if (client.getClientId().equals("test-app")) return client;

View file

@ -74,6 +74,8 @@ public class ProvidersTest extends AbstractAuthenticationTest {
"Validates client based on signed JWT issued by client and signed with the Client private key");
addProviderInfo(expected, "client-secret", "Client Id and Secret", "Validates client based on 'client_id' and " +
"'client_secret' sent either in request parameters or in 'Authorization: Basic' header");
addProviderInfo(expected, "testsuite-client-passthrough", "Testsuite Dummy Client Validation", "Testsuite dummy authenticator, " +
"which automatically authenticates hardcoded client (like 'test-app' )");
compareProviders(expected, result);
}
@ -119,6 +121,10 @@ public class ProvidersTest extends AbstractAuthenticationTest {
"Will also set it if execution is OPTIONAL and the OTP is currently configured for it.");
addProviderInfo(result, "reset-password", "Reset Password", "Sets the Update Password required action if execution is REQUIRED. " +
"Will also set it if execution is OPTIONAL and the password is currently configured for it.");
addProviderInfo(result, "testsuite-dummy-passthrough", "Testsuite Dummy Pass Thru",
"Testsuite Dummy authenticator. Just passes through and is hardcoded to a specific user");
addProviderInfo(result, "testsuite-dummy-registration", "Testsuite Dummy Pass Thru",
"Testsuite Dummy authenticator. Just passes through and is hardcoded to a specific user");
return result;
}

View file

@ -0,0 +1,42 @@
/*
* Copyright 2016 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @author tags. All rights reserved.
*
* 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.forms;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.TestRealmKeycloakTest;
/**
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public abstract class AbstractFlowTest extends TestRealmKeycloakTest {
protected AuthenticationFlowRepresentation findFlowByAlias(String alias) {
for (AuthenticationFlowRepresentation rep : testRealm().flows().getFlows()) {
if (rep.getAlias().equals(alias)) return rep;
}
return null;
}
protected void setRegistrationFlow(AuthenticationFlowRepresentation flow) {
RealmRepresentation realm = testRealm().toRepresentation();
realm.setRegistrationFlow(flow.getAlias());
testRealm().update(realm);
}
}

View file

@ -18,94 +18,78 @@ package org.keycloak.testsuite.forms;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.models.Constants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.LoginTotpPage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.rule.GreenMailRule;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import java.net.MalformedURLException;
import java.util.Collections;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.util.GreenMailRule;
import org.keycloak.testsuite.util.OAuthClient;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class BruteForceTest {
public class BruteForceTest extends TestRealmKeycloakTest {
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost");
CredentialRepresentation credRep = new CredentialRepresentation();
credRep.setType(CredentialRepresentation.TOTP);
credRep.setValue("totpSecret");
user.getCredentials().add(credRep);
user.setTotp(Boolean.TRUE);
@Override
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
testRealm.setBruteForceProtected(true);
testRealm.setFailureFactor(2);
UserCredentialModel credentials = new UserCredentialModel();
credentials.setType(CredentialRepresentation.TOTP);
credentials.setValue("totpSecret");
user.updateCredential(credentials);
findClientInRealmRep(testRealm, "test-app").setDirectAccessGrantsEnabled(true);
}
user.setOtpEnabled(true);
appRealm.setEventsListeners(Collections.singleton("dummy"));
@Before
public void config() {
appRealm.setBruteForceProtected(true);
appRealm.setFailureFactor(2);
}
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
}
});
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
@Rule
public WebRule webRule = new WebRule(this);
public AssertEvents events = new AssertEvents(this);
@Rule
public GreenMailRule greenMail = new GreenMailRule();
@WebResource
protected WebDriver driver;
@WebResource
@Page
protected AppPage appPage;
@WebResource
@Page
protected LoginPage loginPage;
@WebResource
@Page
private RegisterPage registerPage;
@WebResource
@Page
protected LoginTotpPage loginTotpPage;
@WebResource
protected OAuthClient oauth;
private TimeBasedOTP totp = new TimeBasedOTP();
private int lifespan;

View file

@ -0,0 +1,272 @@
/*
* 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.forms;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.resource.AuthenticationManagementResource;
import org.keycloak.authentication.AuthenticationFlow;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.RefreshToken;
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.ExecutionBuilder;
import org.keycloak.testsuite.util.FlowBuilder;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.UserBuilder;
import static org.junit.Assert.assertEquals;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class CustomFlowTest extends AbstractFlowTest {
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
UserRepresentation user = UserBuilder.create()
.username("login-test")
.email("login@test.com")
.enabled(true)
.build();
testRealm.getUsers().add(user);
// Set passthrough clientAuthenticator for our clients
ClientRepresentation dummyClient = ClientBuilder.create()
.clientId("dummy-client")
.name("dummy-client")
.authenticatorType(PassThroughClientAuthenticator.PROVIDER_ID)
.directAccessGrants()
.build();
testRealm.getClients().add(dummyClient);
ClientRepresentation testApp = findClientInRealmRep(testRealm, "test-app");
testApp.setClientAuthenticatorType(PassThroughClientAuthenticator.PROVIDER_ID);
testApp.setDirectAccessGrantsEnabled(true);
}
@Before
public void configureFlows() {
userId = findUser("login-test").getId();
AuthenticationFlowRepresentation flow = FlowBuilder.create()
.alias("dummy")
.description("dummy pass through flow")
.providerId("basic-flow")
.topLevel(true)
.builtIn(false)
.build();
testRealm().flows().createFlow(flow);
RealmRepresentation realm = testRealm().toRepresentation();
realm.setBrowserFlow(flow.getAlias());
realm.setDirectGrantFlow(flow.getAlias());
testRealm().update(realm);
// refresh flow to find its id
flow = findFlowByAlias(flow.getAlias());
AuthenticationExecutionRepresentation execution = ExecutionBuilder.create()
.parentFlow(flow.getId())
.requirement(AuthenticationExecutionModel.Requirement.REQUIRED.toString())
.authenticator(PassThroughAuthenticator.PROVIDER_ID)
.priority(10)
.authenticatorFlow(false)
.build();
testRealm().flows().addExecution(execution);
flow = FlowBuilder.create()
.alias("dummy registration")
.description("dummy pass through registration")
.providerId("basic-flow")
.topLevel(true)
.builtIn(false)
.build();
testRealm().flows().createFlow(flow);
setRegistrationFlow(flow);
// refresh flow to find its id
flow = findFlowByAlias(flow.getAlias());
execution = ExecutionBuilder.create()
.parentFlow(flow.getId())
.requirement(AuthenticationExecutionModel.Requirement.REQUIRED.toString())
.authenticator(PassThroughRegistration.PROVIDER_ID)
.priority(10)
.authenticatorFlow(false)
.build();
testRealm().flows().addExecution(execution);
AuthenticationFlowRepresentation clientFlow = FlowBuilder.create()
.alias("client-dummy")
.description("dummy pass through flow")
.providerId(AuthenticationFlow.CLIENT_FLOW)
.topLevel(true)
.builtIn(false)
.build();
testRealm().flows().createFlow(clientFlow);
realm = testRealm().toRepresentation();
realm.setClientAuthenticationFlow(clientFlow.getAlias());
testRealm().update(realm);
// refresh flow to find its id
clientFlow = findFlowByAlias(clientFlow.getAlias());
execution = ExecutionBuilder.create()
.parentFlow(clientFlow.getId())
.requirement(AuthenticationExecutionModel.Requirement.REQUIRED.toString())
.authenticator(PassThroughClientAuthenticator.PROVIDER_ID)
.priority(10)
.authenticatorFlow(false)
.build();
testRealm().flows().addExecution(execution);
}
@Rule
public AssertEvents events = new AssertEvents(this);
@Page
protected AppPage appPage;
@Page
protected LoginPage loginPage;
@Page
protected ErrorPage errorPage;
@Page
protected LoginPasswordUpdatePage updatePasswordPage;
@Page
protected RegisterPage registerPage;
private static String userId;
@Test
public void loginSuccess() {
PassThroughAuthenticator.username = "login-test";
oauth.openLoginForm();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
}
@Test
public void grantTest() throws Exception {
PassThroughAuthenticator.username = "login-test";
grantAccessToken("test-app", "login-test");
}
@Test
public void clientAuthTest() throws Exception {
PassThroughClientAuthenticator.clientId = "dummy-client";
PassThroughAuthenticator.username = "login-test";
grantAccessToken("dummy-client", "login-test");
PassThroughClientAuthenticator.clientId = "test-app";
grantAccessToken("test-app", "login-test");
PassThroughClientAuthenticator.clientId = "unknown";
OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", "test-user", "password");
assertEquals(400, response.getStatusCode());
assertEquals("unauthorized_client", response.getError());
events.expectLogin()
.client((String) null)
.user((String) null)
.session((String) null)
.removeDetail(Details.CODE_ID)
.removeDetail(Details.REDIRECT_URI)
.removeDetail(Details.CONSENT)
.error(Errors.INVALID_CLIENT_CREDENTIALS)
.assertEvent();
}
private void grantAccessToken(String clientId, String login) throws Exception {
OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", login, "password");
assertEquals(200, response.getStatusCode());
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken());
events.expectLogin()
.client(clientId)
.user(userId)
.session(accessToken.getSessionState())
.detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD)
.detail(Details.TOKEN_ID, accessToken.getId())
.detail(Details.REFRESH_TOKEN_ID, refreshToken.getId())
.detail(Details.USERNAME, login)
.detail(Details.CLIENT_AUTH_METHOD, PassThroughClientAuthenticator.PROVIDER_ID)
.removeDetail(Details.CODE_ID)
.removeDetail(Details.REDIRECT_URI)
.removeDetail(Details.CONSENT)
.assertEvent();
assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());
OAuthClient.AccessTokenResponse refreshedResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
AccessToken refreshedAccessToken = oauth.verifyToken(refreshedResponse.getAccessToken());
RefreshToken refreshedRefreshToken = oauth.verifyRefreshToken(refreshedResponse.getRefreshToken());
assertEquals(accessToken.getSessionState(), refreshedAccessToken.getSessionState());
assertEquals(accessToken.getSessionState(), refreshedRefreshToken.getSessionState());
events.expectRefresh(refreshToken.getId(), refreshToken.getSessionState())
.user(userId)
.client(clientId)
.detail(Details.CLIENT_AUTH_METHOD, PassThroughClientAuthenticator.PROVIDER_ID)
.assertEvent();
}
}

View file

@ -0,0 +1,107 @@
/*
* 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.forms;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.util.ExecutionBuilder;
import org.keycloak.testsuite.util.FlowBuilder;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class CustomRegistrationFlowTest extends AbstractFlowTest {
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
}
@Before
public void configureFlow() {
AuthenticationFlowRepresentation flow = FlowBuilder.create()
.alias("dummy registration")
.description("dummy pass through registration")
.providerId("basic-flow")
.topLevel(true)
.builtIn(false)
.build();
testRealm().flows().createFlow(flow);
setRegistrationFlow(flow);
// refresh flow to find its id
flow = findFlowByAlias(flow.getAlias());
AuthenticationExecutionRepresentation execution = ExecutionBuilder.create()
.parentFlow(flow.getId())
.requirement(AuthenticationExecutionModel.Requirement.REQUIRED.toString())
.authenticator(PassThroughRegistration.PROVIDER_ID)
.priority(10)
.authenticatorFlow(false)
.build();
testRealm().flows().addExecution(execution);
}
@Rule
public AssertEvents events = new AssertEvents(this);
@Page
protected AppPage appPage;
@Page
protected LoginPage loginPage;
@Page
protected ErrorPage errorPage;
@Page
protected LoginPasswordUpdatePage updatePasswordPage;
@Page
protected RegisterPage registerPage;
@Test
public void registerUserSuccess() {
loginPage.open();
loginPage.clickRegister();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
String userId = events.expectRegister(PassThroughRegistration.username, PassThroughRegistration.email).assertEvent().getUserId();
events.expectLogin().detail("username", PassThroughRegistration.username).user(userId).assertEvent();
}
}

View file

@ -18,82 +18,58 @@ package org.keycloak.testsuite.forms;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.events.Details;
import org.keycloak.models.OTPPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.HmacOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.LoginTotpPage;
import org.keycloak.testsuite.rule.GreenMailRule;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
import java.util.Collections;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.util.GreenMailRule;
import org.keycloak.testsuite.util.UserBuilder;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class LoginHotpTest {
public class LoginHotpTest extends TestRealmKeycloakTest {
public static OTPPolicy policy;
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
policy = appRealm.getOTPPolicy();
policy.setType(UserCredentialModel.HOTP);
policy.setLookAheadWindow(2);
appRealm.setOTPPolicy(policy);
UserCredentialModel credentials = new UserCredentialModel();
credentials.setType(CredentialRepresentation.HOTP);
credentials.setValue("hotpSecret");
user.updateCredential(credentials);
user.setOtpEnabled(true);
appRealm.setEventsListeners(Collections.singleton("dummy"));
}
});
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost");
UserBuilder.edit(user)
.hotpSecret("hotpSecret")
.otpEnabled();
}
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
@Rule
public WebRule webRule = new WebRule(this);
public AssertEvents events = new AssertEvents(this);
@Rule
public GreenMailRule greenMail = new GreenMailRule();
@WebResource
protected WebDriver driver;
@WebResource
@Page
protected AppPage appPage;
@WebResource
@Page
protected LoginPage loginPage;
@WebResource
@Page
protected LoginTotpPage loginTotpPage;
private HmacOTP otp = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow());
private HmacOTP otp; // = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow());
private int lifespan;
@ -101,6 +77,19 @@ public class LoginHotpTest {
@Before
public void before() throws MalformedURLException {
RealmRepresentation testRealm = testRealm().toRepresentation();
testRealm.setOtpPolicyType(UserCredentialModel.HOTP);
testRealm.setOtpPolicyLookAheadWindow(2);
testRealm().update(testRealm);
policy = new OTPPolicy();
policy.setAlgorithm(testRealm.getOtpPolicyAlgorithm());
policy.setDigits(testRealm.getOtpPolicyDigits());
policy.setInitialCounter(testRealm.getOtpPolicyInitialCounter());
policy.setLookAheadWindow(testRealm.getOtpPolicyLookAheadWindow());
policy.setPeriod(testRealm.getOtpPolicyLookAheadWindow());
policy.setType(testRealm.getOtpPolicyType());
otp = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow());
}
@ -109,7 +98,7 @@ public class LoginHotpTest {
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
Assert.assertTrue(loginTotpPage.isCurrent());
loginTotpPage.login("123456");
loginTotpPage.assertCurrent();
@ -128,7 +117,7 @@ public class LoginHotpTest {
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
Assert.assertTrue(loginTotpPage.isCurrent());
loginTotpPage.login(null);
loginTotpPage.assertCurrent();
@ -147,7 +136,7 @@ public class LoginHotpTest {
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
Assert.assertTrue(loginTotpPage.isCurrent());
loginTotpPage.login(otp.generateHOTP("hotpSecret", counter++));
@ -161,7 +150,7 @@ public class LoginHotpTest {
loginPage.open();
loginPage.login("test-user@localhost", "invalid");
loginPage.assertCurrent();
Assert.assertTrue(loginPage.isCurrent());
Assert.assertEquals("Invalid username or password.", loginPage.getError());

View file

@ -18,73 +18,51 @@ package org.keycloak.testsuite.forms;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.events.Details;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.LoginTotpPage;
import org.keycloak.testsuite.rule.GreenMailRule;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import java.net.MalformedURLException;
import java.util.Collections;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.util.GreenMailRule;
import org.keycloak.testsuite.util.UserBuilder;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class LoginTotpTest {
public class LoginTotpTest extends TestRealmKeycloakTest {
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
UserCredentialModel credentials = new UserCredentialModel();
credentials.setType(CredentialRepresentation.TOTP);
credentials.setValue("totpSecret");
user.updateCredential(credentials);
user.setOtpEnabled(true);
appRealm.setEventsListeners(Collections.singleton("dummy"));
}
});
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost");
UserBuilder.edit(user)
.totpSecret("totpSecret")
.otpEnabled();
}
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
@Rule
public WebRule webRule = new WebRule(this);
public AssertEvents events = new AssertEvents(this);
@Rule
public GreenMailRule greenMail = new GreenMailRule();
@WebResource
protected WebDriver driver;
@WebResource
@Page
protected AppPage appPage;
@WebResource
@Page
protected LoginPage loginPage;
@WebResource
@Page
protected LoginTotpPage loginTotpPage;
private TimeBasedOTP totp = new TimeBasedOTP();
@ -101,7 +79,7 @@ public class LoginTotpTest {
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
Assert.assertTrue(loginTotpPage.isCurrent());
loginTotpPage.login("123456");
loginTotpPage.assertCurrent();
@ -120,7 +98,7 @@ public class LoginTotpTest {
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
Assert.assertTrue(loginTotpPage.isCurrent());
loginTotpPage.login(null);
loginTotpPage.assertCurrent();
@ -139,7 +117,7 @@ public class LoginTotpTest {
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
Assert.assertTrue(loginTotpPage.isCurrent());
loginTotpPage.login(totp.generateTOTP("totpSecret"));
@ -153,7 +131,7 @@ public class LoginTotpTest {
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
Assert.assertTrue(loginTotpPage.isCurrent());
loginTotpPage.cancel();
loginPage.assertCurrent();
}
@ -163,7 +141,7 @@ public class LoginTotpTest {
loginPage.open();
loginPage.login("test-user@localhost", "invalid");
loginPage.assertCurrent();
Assert.assertTrue(loginPage.isCurrent());
Assert.assertEquals("Invalid username or password.", loginPage.getError());

View file

@ -16,49 +16,39 @@
*/
package org.keycloak.testsuite.forms;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.events.Details;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import java.io.IOException;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import static org.junit.Assert.*;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class LogoutTest {
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule();
public class LogoutTest extends TestRealmKeycloakTest {
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
public AssertEvents events = new AssertEvents(this);
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected OAuthClient oauth;
@WebResource
protected WebDriver driver;
@WebResource
@Page
protected AppPage appPage;
@WebResource
@Page
protected LoginPage loginPage;
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
}
@Test
public void logoutRedirect() {
loginPage.open();

View file

@ -16,54 +16,41 @@
*/
package org.keycloak.testsuite.forms;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.*;
import org.keycloak.events.Details;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import static org.junit.Assert.assertEquals;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class RegisterTest {
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule();
public class RegisterTest extends TestRealmKeycloakTest {
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
public AssertEvents events = new AssertEvents(this);
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected WebDriver driver;
@WebResource
@Page
protected AppPage appPage;
@WebResource
@Page
protected LoginPage loginPage;
@WebResource
@Page
protected RegisterPage registerPage;
@WebResource
protected OAuthClient oauth;
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
}
@Test
public void registerExistingUser() {
@ -133,12 +120,15 @@ public class RegisterTest {
@Test
public void registerPasswordPolicy() {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
/*keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setPasswordPolicy(new PasswordPolicy("length"));
}
});
});*/
RealmRepresentation realm = testRealm().toRepresentation();
realm.setPasswordPolicy("length");
testRealm().update(realm);
try {
loginPage.open();
@ -162,12 +152,12 @@ public class RegisterTest {
events.expectLogin().user(userId).detail(Details.USERNAME, "registerpasswordpolicy").assertEvent();
} finally {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
/*keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setPasswordPolicy(new PasswordPolicy(null));
}
});
});*/
}
}
@ -251,7 +241,7 @@ public class RegisterTest {
String userId = events.expectRegister("registerUserSuccess", "registerUserSuccess@email").assertEvent().getUserId();
events.expectLogin().detail("username", "registerusersuccess").user(userId).assertEvent();
UserModel user = getUser(userId);
UserRepresentation user = getUser(userId);
Assert.assertNotNull(user);
Assert.assertNotNull(user.getCreatedTimestamp());
// test that timestamp is current with 10s tollerance
@ -263,7 +253,7 @@ public class RegisterTest {
assertEquals("lastName", user.getLastName());
}
protected UserModel getUser(String userId) {
/*protected UserModel getUser(String userId) {
KeycloakSession samlServerSession = keycloakRule.startSession();
try {
RealmModel brokerRealm = samlServerSession.realms().getRealm("test");
@ -271,6 +261,10 @@ public class RegisterTest {
} finally {
keycloakRule.stopSession(samlServerSession, false);
}
}*/
protected UserRepresentation getUser(String userId) {
return testRealm().users().get(userId).toRepresentation();
}
@Test
@ -319,7 +313,7 @@ public class RegisterTest {
@Test
public void registerUserSuccess_emailAsUsername() {
configureRelamRegistrationEmailAsUsername(true);
try {
loginPage.open();
loginPage.clickRegister();
@ -332,7 +326,7 @@ public class RegisterTest {
String userId = events.expectRegister("registerUserSuccessE@email", "registerUserSuccessE@email").assertEvent().getUserId();
events.expectLogin().detail("username", "registerusersuccesse@email").user(userId).assertEvent();
UserModel user = getUser(userId);
UserRepresentation user = getUser(userId);
Assert.assertNotNull(user);
Assert.assertNotNull(user.getCreatedTimestamp());
// test that timestamp is current with 10s tollerance
@ -344,12 +338,9 @@ public class RegisterTest {
}
protected void configureRelamRegistrationEmailAsUsername(final boolean value) {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setRegistrationEmailAsUsername(value);
}
});
RealmRepresentation realm = testRealm().toRepresentation();
realm.setRegistrationEmailAsUsername(value);
testRealm().update(realm);
}
}

View file

@ -19,122 +19,96 @@ package org.keycloak.testsuite.forms;
import org.junit.*;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.Event;
import org.keycloak.events.EventType;
import org.keycloak.models.PasswordPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.Constants;
import org.keycloak.testsuite.MailUtil;
import org.keycloak.testsuite.OAuthClient;
//import org.keycloak.testsuite.Constants;
import org.keycloak.testsuite.util.MailUtils;
import org.keycloak.testsuite.pages.*;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.rule.GreenMailRule;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.common.util.Time;
import org.openqa.selenium.WebDriver;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.util.GreenMailRule;
import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.UserBuilder;
import static org.junit.Assert.*;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class ResetPasswordTest {
public class ResetPasswordTest extends TestRealmKeycloakTest {
static int lifespan = 0;
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule((new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
UserModel user = manager.getSession().users().addUser(appRealm, "login-test");
user.setEmail("login@test.com");
user.setEnabled(true);
userId = user.getId();
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
UserRepresentation user = UserBuilder.create()
.username("login-test")
.email("login@test.com")
.enabled(true)
.password("password")
.build();
testRealm.getUsers().add(user);
}
UserCredentialModel creds = new UserCredentialModel();
creds.setType(CredentialRepresentation.PASSWORD);
creds.setValue("password");
@Before
public void setAccessCodeLifespanUserAction() {
// Must do this with adminClient because default is not set until after testRealm.json is loaded.
lifespan = testRealm().toRepresentation().getAccessCodeLifespanUserAction();
}
@Before
public void setUserId() {
userId = findUser("login-test").getId();
}
user.updateCredential(creds);
appRealm.setEventsListeners(Collections.singleton("dummy"));
lifespan = appRealm.getAccessCodeLifespanUserAction();
}
}));
private static String userId;
@Rule
public WebRule webRule = new WebRule(this);
@Rule
public GreenMailRule greenMail = new GreenMailRule();
@WebResource
protected WebDriver driver;
@WebResource
protected OAuthClient oauth;
@WebResource
@Page
protected AppPage appPage;
@WebResource
@Page
protected LoginPage loginPage;
@WebResource
@Page
protected ErrorPage errorPage;
@WebResource
@Page
protected InfoPage infoPage;
@WebResource
@Page
protected VerifyEmailPage verifyEmailPage;
@WebResource
@Page
protected LoginPasswordResetPage resetPasswordPage;
@WebResource
@Page
protected LoginPasswordUpdatePage updatePasswordPage;
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
@Before
public void resetPasswordToOriginal() {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
UserModel user = session.users().getUserByUsername("login-test", appRealm);
UserCredentialModel creds = new UserCredentialModel();
creds.setType(CredentialRepresentation.PASSWORD);
creds.setValue("password");
user.updateCredential(creds);
}
});
}
public AssertEvents events = new AssertEvents(this);
@Test
public void resetPasswordLink() throws IOException, MessagingException {
String username = "login-test";
String resetUri = Constants.AUTH_SERVER_ROOT + "/realms/test/login-actions/reset-credentials";
String resetUri = oauth.AUTH_SERVER_ROOT + "/realms/test/login-actions/reset-credentials";
driver.navigate().to(resetUri);
resetPasswordPage.assertCurrent();
@ -146,7 +120,7 @@ public class ResetPasswordTest {
events.expectRequiredAction(EventType.SEND_RESET_PASSWORD)
.user(userId)
.detail(Details.REDIRECT_URI, Constants.AUTH_SERVER_ROOT + "/realms/test/account/")
.detail(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/account/")
.client("account")
.detail(Details.USERNAME, username)
.detail(Details.EMAIL, "login@test.com")
@ -166,12 +140,12 @@ public class ResetPasswordTest {
updatePasswordPage.changePassword("resetPassword", "resetPassword");
String sessionId = events.expectRequiredAction(EventType.UPDATE_PASSWORD)
.detail(Details.REDIRECT_URI, Constants.AUTH_SERVER_ROOT + "/realms/test/account/")
.detail(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/account/")
.client("account")
.user(userId).detail(Details.USERNAME, username).assertEvent().getSessionId();
events.expectLogin().user(userId).detail(Details.USERNAME, username)
.detail(Details.REDIRECT_URI, Constants.AUTH_SERVER_ROOT + "/realms/test/account/")
.detail(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/account/")
.client("account")
.session(sessionId).assertEvent();
@ -213,7 +187,7 @@ public class ResetPasswordTest {
loginPage.login("login@test.com", "password");
Event loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "login@test.com").assertEvent();
EventRepresentation loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "login@test.com").assertEvent();
String code = oauth.getCurrentQuery().get("code");
OAuthClient.AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code, "password");
@ -358,7 +332,7 @@ public class ResetPasswordTest {
events.expectRequiredAction(EventType.RESET_PASSWORD).user((String) null).session((String) null).detail(Details.USERNAME, "invalid").removeDetail(Details.EMAIL).removeDetail(Details.CODE_ID).error("user_not_found").assertEvent();
}
@Test
public void resetPasswordMissingUsername() throws IOException, MessagingException, InterruptedException {
loginPage.open();
@ -373,9 +347,9 @@ public class ResetPasswordTest {
assertEquals("Please specify username.", resetPasswordPage.getErrorMessage());
assertEquals(0, greenMail.getReceivedMessages().length);
events.expectRequiredAction(EventType.RESET_PASSWORD).user((String) null).session((String) null).clearDetails().error("username_missing").assertEvent();
}
@Test
@ -401,7 +375,7 @@ public class ResetPasswordTest {
String changePasswordUrl = getPasswordResetEmailLink(message);
Time.setOffset(1800 + 23);
setTimeOffset(1800 + 23);
driver.navigate().to(changePasswordUrl.trim());
@ -411,20 +385,18 @@ public class ResetPasswordTest {
events.expectRequiredAction(EventType.RESET_PASSWORD).error("expired_code").client("test-app").user((String) null).session((String) null).clearDetails().assertEvent();
} finally {
Time.setOffset(0);
setTimeOffset(0);
}
}
@Test
public void resetPasswordExpiredCodeShort() throws IOException, MessagingException, InterruptedException {
final AtomicInteger originalValue = new AtomicInteger();
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
originalValue.set(appRealm.getAccessCodeLifespan());
appRealm.setAccessCodeLifespanUserAction(60);
}
});
RealmRepresentation realmRep = testRealm().toRepresentation();
originalValue.set(realmRep.getAccessCodeLifespan());
realmRep.setAccessCodeLifespanUserAction(60);
testRealm().update(realmRep);
try {
loginPage.open();
@ -447,7 +419,7 @@ public class ResetPasswordTest {
String changePasswordUrl = getPasswordResetEmailLink(message);
Time.setOffset(70);
setTimeOffset(70);
driver.navigate().to(changePasswordUrl.trim());
@ -457,139 +429,94 @@ public class ResetPasswordTest {
events.expectRequiredAction(EventType.RESET_PASSWORD).error("expired_code").client("test-app").user((String) null).session((String) null).clearDetails().assertEvent();
} finally {
Time.setOffset(0);
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setAccessCodeLifespanUserAction(originalValue.get());
}
});
setTimeOffset(0);
}
}
@Test
public void resetPasswordDisabledUser() throws IOException, MessagingException, InterruptedException {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
session.users().getUserByUsername("login-test", appRealm).setEnabled(false);
}
});
UserRepresentation user = findUser("login-test");
user.setEnabled(false);
updateUser(user);
try {
loginPage.open();
loginPage.resetPassword();
loginPage.open();
loginPage.resetPassword();
resetPasswordPage.assertCurrent();
resetPasswordPage.assertCurrent();
resetPasswordPage.changePassword("login-test");
resetPasswordPage.changePassword("login-test");
loginPage.assertCurrent();
assertEquals("You should receive an email shortly with further instructions.", loginPage.getSuccessMessage());
loginPage.assertCurrent();
assertEquals("You should receive an email shortly with further instructions.", loginPage.getSuccessMessage());
assertEquals(0, greenMail.getReceivedMessages().length);
assertEquals(0, greenMail.getReceivedMessages().length);
events.expectRequiredAction(EventType.RESET_PASSWORD).session((String) null).user(userId).detail(Details.USERNAME, "login-test").removeDetail(Details.CODE_ID).error("user_disabled").assertEvent();
} finally {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
session.users().getUserByUsername("login-test", appRealm).setEnabled(true);
}
});
}
events.expectRequiredAction(EventType.RESET_PASSWORD).session((String) null).user(userId).detail(Details.USERNAME, "login-test").removeDetail(Details.CODE_ID).error("user_disabled").assertEvent();
}
@Test
public void resetPasswordNoEmail() throws IOException, MessagingException, InterruptedException {
final String[] email = new String[1];
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
UserModel user = session.users().getUserByUsername("login-test", appRealm);
email[0] = user.getEmail();
user.setEmail(null);
}
});
UserRepresentation user = findUser("login-test");
email[0] = user.getEmail();
user.setEmail("");
updateUser(user);
try {
loginPage.open();
loginPage.resetPassword();
loginPage.open();
loginPage.resetPassword();
resetPasswordPage.assertCurrent();
resetPasswordPage.assertCurrent();
resetPasswordPage.changePassword("login-test");
resetPasswordPage.changePassword("login-test");
loginPage.assertCurrent();
assertEquals("You should receive an email shortly with further instructions.", loginPage.getSuccessMessage());
loginPage.assertCurrent();
assertEquals("You should receive an email shortly with further instructions.", loginPage.getSuccessMessage());
assertEquals(0, greenMail.getReceivedMessages().length);
assertEquals(0, greenMail.getReceivedMessages().length);
events.expectRequiredAction(EventType.RESET_PASSWORD_ERROR).session((String) null).user(userId).detail(Details.USERNAME, "login-test").removeDetail(Details.CODE_ID).error("invalid_email").assertEvent();
} finally {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
session.users().getUserByUsername("login-test", appRealm).setEmail(email[0]);
}
});
}
events.expectRequiredAction(EventType.RESET_PASSWORD_ERROR).session((String) null).user(userId).detail(Details.USERNAME, "login-test").removeDetail(Details.CODE_ID).error("invalid_email").assertEvent();
}
@Test
public void resetPasswordWrongSmtp() throws IOException, MessagingException, InterruptedException {
final String[] host = new String[1];
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
Map<String, String> smtpConfig = new HashMap<>();
smtpConfig.putAll(appRealm.getSmtpConfig());
host[0] = smtpConfig.get("host");
smtpConfig.put("host", "invalid_host");
appRealm.setSmtpConfig(smtpConfig);
}
});
try {
loginPage.open();
loginPage.resetPassword();
Map<String, String> smtpConfig = new HashMap<>();
smtpConfig.putAll(testRealm().toRepresentation().getSmtpServer());
host[0] = smtpConfig.get("host");
smtpConfig.put("host", "invalid_host");
RealmRepresentation realmRep = testRealm().toRepresentation();
realmRep.setSmtpServer(smtpConfig);
testRealm().update(realmRep);
resetPasswordPage.assertCurrent();
loginPage.open();
loginPage.resetPassword();
resetPasswordPage.changePassword("login-test");
resetPasswordPage.assertCurrent();
errorPage.assertCurrent();
resetPasswordPage.changePassword("login-test");
assertEquals("Failed to send email, please try again later.", errorPage.getError());
errorPage.assertCurrent();
assertEquals(0, greenMail.getReceivedMessages().length);
assertEquals("Failed to send email, please try again later.", errorPage.getError());
events.expectRequiredAction(EventType.SEND_RESET_PASSWORD_ERROR).user(userId)
.session((String)null)
.detail(Details.USERNAME, "login-test").removeDetail(Details.CODE_ID).error(Errors.EMAIL_SEND_FAILED).assertEvent();
} finally {
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
Map<String, String> smtpConfig = new HashMap<>();
smtpConfig.putAll(appRealm.getSmtpConfig());
smtpConfig.put("host",host[0]);
appRealm.setSmtpConfig(smtpConfig);
}
});
}
assertEquals(0, greenMail.getReceivedMessages().length);
events.expectRequiredAction(EventType.SEND_RESET_PASSWORD_ERROR).user(userId)
.session((String)null)
.detail(Details.USERNAME, "login-test").removeDetail(Details.CODE_ID).error(Errors.EMAIL_SEND_FAILED).assertEvent();
}
private void setPasswordPolicy(String policy) {
RealmRepresentation realmRep = testRealm().toRepresentation();
realmRep.setPasswordPolicy(policy);
testRealm().update(realmRep);
}
@Test
public void resetPasswordWithLengthPasswordPolicy() throws IOException, MessagingException {
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setPasswordPolicy(new PasswordPolicy("length"));
}
});
setPasswordPolicy("length");
loginPage.open();
loginPage.resetPassword();
@ -640,62 +567,51 @@ public class ResetPasswordTest {
@Test
public void resetPasswordWithPasswordHisoryPolicy() throws IOException, MessagingException {
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
//Block passwords that are equal to previous passwords. Default value is 3.
appRealm.setPasswordPolicy(new PasswordPolicy("passwordHistory"));
}
});
//Block passwords that are equal to previous passwords. Default value is 3.
setPasswordPolicy("passwordHistory");
try {
Time.setOffset(2000000);
setTimeOffset(2000000);
resetPassword("login-test", "password1");
resetPasswordInvalidPassword("login-test", "password1", "Invalid password: must not be equal to any of last 3 passwords.");
Time.setOffset(4000000);
setTimeOffset(4000000);
resetPassword("login-test", "password2");
resetPasswordInvalidPassword("login-test", "password1", "Invalid password: must not be equal to any of last 3 passwords.");
resetPasswordInvalidPassword("login-test", "password2", "Invalid password: must not be equal to any of last 3 passwords.");
Time.setOffset(8000000);
setTimeOffset(8000000);
resetPassword("login-test", "password3");
resetPasswordInvalidPassword("login-test", "password1", "Invalid password: must not be equal to any of last 3 passwords.");
resetPasswordInvalidPassword("login-test", "password2", "Invalid password: must not be equal to any of last 3 passwords.");
resetPasswordInvalidPassword("login-test", "password3", "Invalid password: must not be equal to any of last 3 passwords.");
resetPassword("login-test", "password");
} finally {
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
appRealm.setPasswordPolicy(new PasswordPolicy(null));
}
});
Time.setOffset(0);
setTimeOffset(0);
}
}
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 = MailUtil.getLink(textBody);
final String textChangePwdUrl = MailUtils.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 = MailUtil.getLink(htmlBody);
final String htmlChangePwdUrl = MailUtils.getLink(htmlBody);
assertEquals(htmlChangePwdUrl, textChangePwdUrl);
return htmlChangePwdUrl;

View file

@ -16,22 +16,23 @@
*/
package org.keycloak.testsuite.forms;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.events.Details;
import org.keycloak.events.Event;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.TestRealmKeycloakTest;
import org.keycloak.testsuite.drone.Different;
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testsuite.util.OAuthClient;
import org.openqa.selenium.WebDriver;
import static org.junit.Assert.assertEquals;
@ -40,38 +41,35 @@ import static org.junit.Assert.assertTrue;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class SSOTest {
public class SSOTest extends TestRealmKeycloakTest {
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule();
@Drone
@Different
protected WebDriver driver2;
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected OAuthClient oauth;
@WebResource
protected WebDriver driver;
@WebResource
@Page
protected AppPage appPage;
@WebResource
@Page
protected LoginPage loginPage;
@WebResource
@Page
protected AccountUpdateProfilePage profilePage;
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
public AssertEvents events = new AssertEvents(this);
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
}
@Test
public void loginSuccess() {
loginPage.open();
loginPage.login("test-user@localhost", "password");
assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
@ -92,7 +90,7 @@ public class SSOTest {
assertEquals(sessionId, sessionId2);
// Expire session
keycloakRule.removeUserSession(sessionId);
testingClient.testing().removeUserSession("test", sessionId);
oauth.doLogin("test-user@localhost", "password");
@ -110,15 +108,18 @@ public class SSOTest {
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
Event login1 = events.expectLogin().assertEvent();
EventRepresentation login1 = events.expectLogin().assertEvent();
WebDriver driver2 = WebRule.createWebDriver();
try {
OAuthClient oauth2 = new OAuthClient(driver2);
//OAuthClient oauth2 = new OAuthClient(driver2);
OAuthClient oauth2 = new OAuthClient();
oauth2.setDriver(driver2);
oauth2.setAdminClient(adminClient);
oauth2.state("mystate");
oauth2.doLogin("test-user@localhost", "password");
Event login2 = events.expectLogin().assertEvent();
EventRepresentation login2 = events.expectLogin().assertEvent();
Assert.assertEquals(RequestType.AUTH_RESPONSE, RequestType.valueOf(driver2.getTitle()));
Assert.assertNotNull(oauth2.getCurrentQuery().get(OAuth2Constants.CODE));

View file

@ -43,6 +43,11 @@ public class ClientBuilder {
return this;
}
public ClientBuilder name(String name) {
rep.setName(name);
return this;
}
public ClientBuilder clientId(String clientId) {
rep.setClientId(clientId);
return this;

View file

@ -0,0 +1,71 @@
/*
* 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 org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
/**
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class ExecutionBuilder {
private AuthenticationExecutionRepresentation rep = new AuthenticationExecutionRepresentation();
public static ExecutionBuilder create() {
return new ExecutionBuilder();
}
private ExecutionBuilder() {
}
public ExecutionBuilder id(String id) {
rep.setId(id);
return this;
}
public ExecutionBuilder parentFlow(String parentFlow) {
rep.setParentFlow(parentFlow);
return this;
}
public ExecutionBuilder requirement(String requirement) {
rep.setRequirement(requirement);
return this;
}
public ExecutionBuilder authenticator(String authenticator) {
rep.setAuthenticator(authenticator);
return this;
}
public ExecutionBuilder priority(int priority) {
rep.setPriority(priority);
return this;
}
public ExecutionBuilder authenticatorFlow(boolean authenticatorFlow) {
rep.setAutheticatorFlow(authenticatorFlow);
return this;
}
public AuthenticationExecutionRepresentation build() {
return rep;
}
}

View file

@ -0,0 +1,71 @@
/*
* 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 org.keycloak.representations.idm.AuthenticationFlowRepresentation;
/**
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class FlowBuilder {
private AuthenticationFlowRepresentation rep = new AuthenticationFlowRepresentation();
public static FlowBuilder create() {
return new FlowBuilder();
}
private FlowBuilder() {
}
public FlowBuilder id(String id) {
rep.setId(id);
return this;
}
public FlowBuilder alias(String alias) {
rep.setAlias(alias);
return this;
}
public FlowBuilder description(String description) {
rep.setDescription(description);
return this;
}
public FlowBuilder providerId(String providerId) {
rep.setProviderId(providerId);
return this;
}
public FlowBuilder topLevel(boolean topLevel) {
rep.setTopLevel(topLevel);
return this;
}
public FlowBuilder builtIn(boolean builtIn) {
rep.setBuiltIn(builtIn);
return this;
}
public AuthenticationFlowRepresentation build() {
return rep;
}
}

View file

@ -124,20 +124,33 @@ public class UserBuilder {
return this;
}
public UserBuilder totpSecret(String totpSecret) {
public UserBuilder secret(String type, String secret) {
if (rep.getCredentials() == null) {
rep.setCredentials(new LinkedList<CredentialRepresentation>());
}
CredentialRepresentation credential = new CredentialRepresentation();
credential.setType(CredentialRepresentation.TOTP);
credential.setValue(totpSecret);
credential.setType(type);
credential.setValue(secret);
rep.getCredentials().add(credential);
rep.setTotp(true);
return this;
}
public UserBuilder totpSecret(String totpSecret) {
return secret(CredentialRepresentation.TOTP, totpSecret);
}
public UserBuilder hotpSecret(String hotpSecret) {
return secret(CredentialRepresentation.HOTP, hotpSecret);
}
public UserBuilder otpEnabled() {
rep.setTotp(Boolean.TRUE);
return this;
}
public UserRepresentation build() {
return rep;
}

View file

@ -1,248 +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.forms;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.authentication.AuthenticationFlow;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.RefreshToken;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import static org.junit.Assert.assertEquals;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class CustomFlowTest {
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
UserModel user = manager.getSession().users().addUser(appRealm, "login-test");
user.setEmail("login@test.com");
user.setEnabled(true);
userId = user.getId();
AuthenticationFlowModel flow = new AuthenticationFlowModel();
flow.setAlias("dummy");
flow.setDescription("dummy pass through flow");
flow.setProviderId("basic-flow");
flow.setTopLevel(true);
flow.setBuiltIn(false);
flow = appRealm.addAuthenticationFlow(flow);
appRealm.setBrowserFlow(flow);
appRealm.setDirectGrantFlow(flow);
AuthenticationExecutionModel execution;
execution = new AuthenticationExecutionModel();
execution.setParentFlow(flow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator(PassThroughAuthenticator.PROVIDER_ID);
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
appRealm.addAuthenticatorExecution(execution);
flow = new AuthenticationFlowModel();
flow.setAlias("dummy registration");
flow.setDescription("dummy pass through registration");
flow.setProviderId("basic-flow");
flow.setTopLevel(true);
flow.setBuiltIn(false);
flow = appRealm.addAuthenticationFlow(flow);
appRealm.setRegistrationFlow(flow);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(flow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator(PassThroughRegistration.PROVIDER_ID);
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
appRealm.addAuthenticatorExecution(execution);
AuthenticationFlowModel clientFlow = new AuthenticationFlowModel();
clientFlow.setAlias("client-dummy");
clientFlow.setDescription("dummy pass through flow");
clientFlow.setProviderId(AuthenticationFlow.CLIENT_FLOW);
clientFlow.setTopLevel(true);
clientFlow.setBuiltIn(false);
clientFlow = appRealm.addAuthenticationFlow(clientFlow);
appRealm.setClientAuthenticationFlow(clientFlow);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(clientFlow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator(PassThroughClientAuthenticator.PROVIDER_ID);
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
appRealm.addAuthenticatorExecution(execution);
// Set passthrough clientAuthenticator for our clients
ClientModel dummyClient = KeycloakModelUtils.createClient(appRealm, "dummy-client");
dummyClient.setClientAuthenticatorType(PassThroughClientAuthenticator.PROVIDER_ID);
dummyClient.setDirectAccessGrantsEnabled(true);
ClientModel testApp = appRealm.getClientByClientId("test-app");
testApp.setClientAuthenticatorType(PassThroughClientAuthenticator.PROVIDER_ID);
testApp.setDirectAccessGrantsEnabled(true);
}
});
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected OAuthClient oauth;
@WebResource
protected WebDriver driver;
@WebResource
protected AppPage appPage;
@WebResource
protected LoginPage loginPage;
@WebResource
protected ErrorPage errorPage;
@WebResource
protected LoginPasswordUpdatePage updatePasswordPage;
@WebResource
protected RegisterPage registerPage;
private static String userId;
@Test
public void loginSuccess() {
PassThroughAuthenticator.username = "login-test";
oauth.openLoginForm();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent();
}
@Test
public void grantTest() throws Exception {
PassThroughAuthenticator.username = "login-test";
grantAccessToken("test-app", "login-test");
}
@Test
public void clientAuthTest() throws Exception {
PassThroughClientAuthenticator.clientId = "dummy-client";
PassThroughAuthenticator.username = "login-test";
grantAccessToken("dummy-client", "login-test");
PassThroughClientAuthenticator.clientId = "test-app";
grantAccessToken("test-app", "login-test");
PassThroughClientAuthenticator.clientId = "unknown";
OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", "test-user", "password");
assertEquals(400, response.getStatusCode());
assertEquals("unauthorized_client", response.getError());
events.expectLogin()
.client((String) null)
.user((String) null)
.session((String) null)
.removeDetail(Details.CODE_ID)
.removeDetail(Details.REDIRECT_URI)
.removeDetail(Details.CONSENT)
.error(Errors.INVALID_CLIENT_CREDENTIALS)
.assertEvent();
}
private void grantAccessToken(String clientId, String login) throws Exception {
OAuthClient.AccessTokenResponse response = oauth.doGrantAccessTokenRequest("password", login, "password");
assertEquals(200, response.getStatusCode());
AccessToken accessToken = oauth.verifyToken(response.getAccessToken());
RefreshToken refreshToken = oauth.verifyRefreshToken(response.getRefreshToken());
events.expectLogin()
.client(clientId)
.user(userId)
.session(accessToken.getSessionState())
.detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD)
.detail(Details.TOKEN_ID, accessToken.getId())
.detail(Details.REFRESH_TOKEN_ID, refreshToken.getId())
.detail(Details.USERNAME, login)
.detail(Details.CLIENT_AUTH_METHOD, PassThroughClientAuthenticator.PROVIDER_ID)
.removeDetail(Details.CODE_ID)
.removeDetail(Details.REDIRECT_URI)
.removeDetail(Details.CONSENT)
.assertEvent();
assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());
OAuthClient.AccessTokenResponse refreshedResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
AccessToken refreshedAccessToken = oauth.verifyToken(refreshedResponse.getAccessToken());
RefreshToken refreshedRefreshToken = oauth.verifyRefreshToken(refreshedResponse.getRefreshToken());
assertEquals(accessToken.getSessionState(), refreshedAccessToken.getSessionState());
assertEquals(accessToken.getSessionState(), refreshedRefreshToken.getSessionState());
events.expectRefresh(refreshToken.getId(), refreshToken.getSessionState())
.user(userId)
.client(clientId)
.detail(Details.CLIENT_AUTH_METHOD, PassThroughClientAuthenticator.PROVIDER_ID)
.assertEvent();
}
}

View file

@ -1,115 +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.forms;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.RealmModel;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
import static org.junit.Assert.assertEquals;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class CustomRegistrationFlowTest {
@ClassRule
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
AuthenticationFlowModel flow = new AuthenticationFlowModel();
flow.setAlias("dummy registration");
flow.setDescription("dummy pass through registration");
flow.setProviderId("basic-flow");
flow.setTopLevel(true);
flow.setBuiltIn(false);
flow = appRealm.addAuthenticationFlow(flow);
appRealm.setRegistrationFlow(flow);
AuthenticationExecutionModel execution = new AuthenticationExecutionModel();
execution.setParentFlow(flow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator(PassThroughRegistration.PROVIDER_ID);
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
appRealm.addAuthenticatorExecution(execution);
}
});
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
@Rule
public WebRule webRule = new WebRule(this);
@WebResource
protected OAuthClient oauth;
@WebResource
protected WebDriver driver;
@WebResource
protected AppPage appPage;
@WebResource
protected LoginPage loginPage;
@WebResource
protected ErrorPage errorPage;
@WebResource
protected LoginPasswordUpdatePage updatePasswordPage;
@WebResource
protected RegisterPage registerPage;
private static String userId;
@Test
public void registerUserSuccess() {
loginPage.open();
loginPage.clickRegister();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
String userId = events.expectRegister(PassThroughRegistration.username, PassThroughRegistration.email).assertEvent().getUserId();
events.expectLogin().detail("username", PassThroughRegistration.username).user(userId).assertEvent();
}
}