KEYCLOAK-2906 Migrate forms package to new testsuite
This commit is contained in:
parent
5abe06a2b7
commit
c392f6659e
25 changed files with 949 additions and 806 deletions
|
@ -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 {
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ import javax.ws.rs.core.UriBuilder;
|
||||||
public class AppPage extends AbstractPage {
|
public class AppPage extends AbstractPage {
|
||||||
|
|
||||||
public static final String AUTH_SERVER_URL = "http://localhost:8180/auth";
|
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")
|
@FindBy(id = "account")
|
||||||
private WebElement accountLink;
|
private WebElement accountLink;
|
||||||
|
|
|
@ -21,6 +21,8 @@ import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
|
||||||
import java.util.List;
|
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;
|
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 {
|
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) {
|
protected ClientRepresentation findTestApp(RealmRepresentation testRealm) {
|
||||||
for (ClientRepresentation client : testRealm.getClients()) {
|
for (ClientRepresentation client : testRealm.getClients()) {
|
||||||
if (client.getClientId().equals("test-app")) return client;
|
if (client.getClientId().equals("test-app")) return client;
|
||||||
|
|
|
@ -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");
|
"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 " +
|
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");
|
"'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);
|
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.");
|
"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. " +
|
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.");
|
"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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,94 +18,78 @@ package org.keycloak.testsuite.forms;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.ClassRule;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.models.Constants;
|
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.models.utils.TimeBasedOTP;
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.pages.LoginTotpPage;
|
import org.keycloak.testsuite.pages.LoginTotpPage;
|
||||||
import org.keycloak.testsuite.pages.RegisterPage;
|
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.Client;
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import java.net.MalformedURLException;
|
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 <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
|
@Override
|
||||||
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
|
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
|
testRealm.setBruteForceProtected(true);
|
||||||
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
|
testRealm.setFailureFactor(2);
|
||||||
UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
|
|
||||||
|
|
||||||
UserCredentialModel credentials = new UserCredentialModel();
|
findClientInRealmRep(testRealm, "test-app").setDirectAccessGrantsEnabled(true);
|
||||||
credentials.setType(CredentialRepresentation.TOTP);
|
}
|
||||||
credentials.setValue("totpSecret");
|
|
||||||
user.updateCredential(credentials);
|
|
||||||
|
|
||||||
user.setOtpEnabled(true);
|
@Before
|
||||||
appRealm.setEventsListeners(Collections.singleton("dummy"));
|
public void config() {
|
||||||
|
|
||||||
appRealm.setBruteForceProtected(true);
|
}
|
||||||
appRealm.setFailureFactor(2);
|
|
||||||
|
|
||||||
appRealm.getClientByClientId("test-app").setDirectAccessGrantsEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
public AssertEvents events = new AssertEvents(this);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public WebRule webRule = new WebRule(this);
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public GreenMailRule greenMail = new GreenMailRule();
|
public GreenMailRule greenMail = new GreenMailRule();
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected WebDriver driver;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected AppPage appPage;
|
protected AppPage appPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
private RegisterPage registerPage;
|
private RegisterPage registerPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginTotpPage loginTotpPage;
|
protected LoginTotpPage loginTotpPage;
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected OAuthClient oauth;
|
|
||||||
|
|
||||||
private TimeBasedOTP totp = new TimeBasedOTP();
|
private TimeBasedOTP totp = new TimeBasedOTP();
|
||||||
|
|
||||||
private int lifespan;
|
private int lifespan;
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -18,82 +18,58 @@ package org.keycloak.testsuite.forms;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.ClassRule;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.models.OTPPolicy;
|
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.models.utils.HmacOTP;
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.pages.LoginTotpPage;
|
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.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 <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;
|
public static OTPPolicy policy;
|
||||||
@ClassRule
|
|
||||||
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
|
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||||
UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
|
UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost");
|
||||||
policy = appRealm.getOTPPolicy();
|
UserBuilder.edit(user)
|
||||||
policy.setType(UserCredentialModel.HOTP);
|
.hotpSecret("hotpSecret")
|
||||||
policy.setLookAheadWindow(2);
|
.otpEnabled();
|
||||||
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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
public AssertEvents events = new AssertEvents(this);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public WebRule webRule = new WebRule(this);
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public GreenMailRule greenMail = new GreenMailRule();
|
public GreenMailRule greenMail = new GreenMailRule();
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected WebDriver driver;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected AppPage appPage;
|
protected AppPage appPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginTotpPage loginTotpPage;
|
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;
|
private int lifespan;
|
||||||
|
|
||||||
|
@ -101,6 +77,19 @@ public class LoginHotpTest {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() throws MalformedURLException {
|
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());
|
otp = new HmacOTP(policy.getDigits(), policy.getAlgorithm(), policy.getLookAheadWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +98,7 @@ public class LoginHotpTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "password");
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
|
||||||
loginTotpPage.assertCurrent();
|
Assert.assertTrue(loginTotpPage.isCurrent());
|
||||||
|
|
||||||
loginTotpPage.login("123456");
|
loginTotpPage.login("123456");
|
||||||
loginTotpPage.assertCurrent();
|
loginTotpPage.assertCurrent();
|
||||||
|
@ -128,7 +117,7 @@ public class LoginHotpTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "password");
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
|
||||||
loginTotpPage.assertCurrent();
|
Assert.assertTrue(loginTotpPage.isCurrent());
|
||||||
|
|
||||||
loginTotpPage.login(null);
|
loginTotpPage.login(null);
|
||||||
loginTotpPage.assertCurrent();
|
loginTotpPage.assertCurrent();
|
||||||
|
@ -147,7 +136,7 @@ public class LoginHotpTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "password");
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
|
||||||
loginTotpPage.assertCurrent();
|
Assert.assertTrue(loginTotpPage.isCurrent());
|
||||||
|
|
||||||
loginTotpPage.login(otp.generateHOTP("hotpSecret", counter++));
|
loginTotpPage.login(otp.generateHOTP("hotpSecret", counter++));
|
||||||
|
|
||||||
|
@ -161,7 +150,7 @@ public class LoginHotpTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "invalid");
|
loginPage.login("test-user@localhost", "invalid");
|
||||||
|
|
||||||
loginPage.assertCurrent();
|
Assert.assertTrue(loginPage.isCurrent());
|
||||||
|
|
||||||
Assert.assertEquals("Invalid username or password.", loginPage.getError());
|
Assert.assertEquals("Invalid username or password.", loginPage.getError());
|
||||||
|
|
|
@ -18,73 +18,51 @@ package org.keycloak.testsuite.forms;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.ClassRule;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.events.Details;
|
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.models.utils.TimeBasedOTP;
|
||||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.pages.LoginTotpPage;
|
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.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 <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
|
@Override
|
||||||
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
|
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||||
|
UserRepresentation user = findUserInRealmRep(testRealm, "test-user@localhost");
|
||||||
@Override
|
UserBuilder.edit(user)
|
||||||
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
|
.totpSecret("totpSecret")
|
||||||
UserModel user = manager.getSession().users().getUserByUsername("test-user@localhost", appRealm);
|
.otpEnabled();
|
||||||
|
}
|
||||||
UserCredentialModel credentials = new UserCredentialModel();
|
|
||||||
credentials.setType(CredentialRepresentation.TOTP);
|
|
||||||
credentials.setValue("totpSecret");
|
|
||||||
user.updateCredential(credentials);
|
|
||||||
|
|
||||||
user.setOtpEnabled(true);
|
|
||||||
appRealm.setEventsListeners(Collections.singleton("dummy"));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
public AssertEvents events = new AssertEvents(this);
|
||||||
|
|
||||||
@Rule
|
|
||||||
public WebRule webRule = new WebRule(this);
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public GreenMailRule greenMail = new GreenMailRule();
|
public GreenMailRule greenMail = new GreenMailRule();
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected WebDriver driver;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected AppPage appPage;
|
protected AppPage appPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginTotpPage loginTotpPage;
|
protected LoginTotpPage loginTotpPage;
|
||||||
|
|
||||||
private TimeBasedOTP totp = new TimeBasedOTP();
|
private TimeBasedOTP totp = new TimeBasedOTP();
|
||||||
|
@ -101,7 +79,7 @@ public class LoginTotpTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "password");
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
|
||||||
loginTotpPage.assertCurrent();
|
Assert.assertTrue(loginTotpPage.isCurrent());
|
||||||
|
|
||||||
loginTotpPage.login("123456");
|
loginTotpPage.login("123456");
|
||||||
loginTotpPage.assertCurrent();
|
loginTotpPage.assertCurrent();
|
||||||
|
@ -120,7 +98,7 @@ public class LoginTotpTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "password");
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
|
||||||
loginTotpPage.assertCurrent();
|
Assert.assertTrue(loginTotpPage.isCurrent());
|
||||||
|
|
||||||
loginTotpPage.login(null);
|
loginTotpPage.login(null);
|
||||||
loginTotpPage.assertCurrent();
|
loginTotpPage.assertCurrent();
|
||||||
|
@ -139,7 +117,7 @@ public class LoginTotpTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "password");
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
|
||||||
loginTotpPage.assertCurrent();
|
Assert.assertTrue(loginTotpPage.isCurrent());
|
||||||
|
|
||||||
loginTotpPage.login(totp.generateTOTP("totpSecret"));
|
loginTotpPage.login(totp.generateTOTP("totpSecret"));
|
||||||
|
|
||||||
|
@ -153,7 +131,7 @@ public class LoginTotpTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "password");
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
|
||||||
loginTotpPage.assertCurrent();
|
Assert.assertTrue(loginTotpPage.isCurrent());
|
||||||
loginTotpPage.cancel();
|
loginTotpPage.cancel();
|
||||||
loginPage.assertCurrent();
|
loginPage.assertCurrent();
|
||||||
}
|
}
|
||||||
|
@ -163,7 +141,7 @@ public class LoginTotpTest {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "invalid");
|
loginPage.login("test-user@localhost", "invalid");
|
||||||
|
|
||||||
loginPage.assertCurrent();
|
Assert.assertTrue(loginPage.isCurrent());
|
||||||
|
|
||||||
Assert.assertEquals("Invalid username or password.", loginPage.getError());
|
Assert.assertEquals("Invalid username or password.", loginPage.getError());
|
||||||
|
|
|
@ -16,49 +16,39 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.forms;
|
package org.keycloak.testsuite.forms;
|
||||||
|
|
||||||
import org.junit.ClassRule;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
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 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.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||||
*/
|
*/
|
||||||
public class LogoutTest {
|
public class LogoutTest extends TestRealmKeycloakTest {
|
||||||
|
|
||||||
@ClassRule
|
|
||||||
public static KeycloakRule keycloakRule = new KeycloakRule();
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
public AssertEvents events = new AssertEvents(this);
|
||||||
|
|
||||||
@Rule
|
@Page
|
||||||
public WebRule webRule = new WebRule(this);
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected OAuthClient oauth;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected WebDriver driver;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected AppPage appPage;
|
protected AppPage appPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void logoutRedirect() {
|
public void logoutRedirect() {
|
||||||
loginPage.open();
|
loginPage.open();
|
|
@ -16,54 +16,41 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.forms;
|
package org.keycloak.testsuite.forms;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.models.PasswordPolicy;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.services.managers.RealmManager;
|
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
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;
|
||||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.pages.RegisterPage;
|
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;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
|
||||||
*/
|
*/
|
||||||
public class RegisterTest {
|
public class RegisterTest extends TestRealmKeycloakTest {
|
||||||
|
|
||||||
@ClassRule
|
|
||||||
public static KeycloakRule keycloakRule = new KeycloakRule();
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
public AssertEvents events = new AssertEvents(this);
|
||||||
|
|
||||||
@Rule
|
@Page
|
||||||
public WebRule webRule = new WebRule(this);
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected WebDriver driver;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected AppPage appPage;
|
protected AppPage appPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected RegisterPage registerPage;
|
protected RegisterPage registerPage;
|
||||||
|
|
||||||
@WebResource
|
@Override
|
||||||
protected OAuthClient oauth;
|
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerExistingUser() {
|
public void registerExistingUser() {
|
||||||
|
@ -133,12 +120,15 @@ public class RegisterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void registerPasswordPolicy() {
|
public void registerPasswordPolicy() {
|
||||||
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
/*keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
appRealm.setPasswordPolicy(new PasswordPolicy("length"));
|
appRealm.setPasswordPolicy(new PasswordPolicy("length"));
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
|
RealmRepresentation realm = testRealm().toRepresentation();
|
||||||
|
realm.setPasswordPolicy("length");
|
||||||
|
testRealm().update(realm);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
|
@ -162,12 +152,12 @@ public class RegisterTest {
|
||||||
|
|
||||||
events.expectLogin().user(userId).detail(Details.USERNAME, "registerpasswordpolicy").assertEvent();
|
events.expectLogin().user(userId).detail(Details.USERNAME, "registerpasswordpolicy").assertEvent();
|
||||||
} finally {
|
} finally {
|
||||||
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
/*keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
||||||
@Override
|
@Override
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
appRealm.setPasswordPolicy(new PasswordPolicy(null));
|
appRealm.setPasswordPolicy(new PasswordPolicy(null));
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +241,7 @@ public class RegisterTest {
|
||||||
String userId = events.expectRegister("registerUserSuccess", "registerUserSuccess@email").assertEvent().getUserId();
|
String userId = events.expectRegister("registerUserSuccess", "registerUserSuccess@email").assertEvent().getUserId();
|
||||||
events.expectLogin().detail("username", "registerusersuccess").user(userId).assertEvent();
|
events.expectLogin().detail("username", "registerusersuccess").user(userId).assertEvent();
|
||||||
|
|
||||||
UserModel user = getUser(userId);
|
UserRepresentation user = getUser(userId);
|
||||||
Assert.assertNotNull(user);
|
Assert.assertNotNull(user);
|
||||||
Assert.assertNotNull(user.getCreatedTimestamp());
|
Assert.assertNotNull(user.getCreatedTimestamp());
|
||||||
// test that timestamp is current with 10s tollerance
|
// test that timestamp is current with 10s tollerance
|
||||||
|
@ -263,7 +253,7 @@ public class RegisterTest {
|
||||||
assertEquals("lastName", user.getLastName());
|
assertEquals("lastName", user.getLastName());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UserModel getUser(String userId) {
|
/*protected UserModel getUser(String userId) {
|
||||||
KeycloakSession samlServerSession = keycloakRule.startSession();
|
KeycloakSession samlServerSession = keycloakRule.startSession();
|
||||||
try {
|
try {
|
||||||
RealmModel brokerRealm = samlServerSession.realms().getRealm("test");
|
RealmModel brokerRealm = samlServerSession.realms().getRealm("test");
|
||||||
|
@ -271,6 +261,10 @@ public class RegisterTest {
|
||||||
} finally {
|
} finally {
|
||||||
keycloakRule.stopSession(samlServerSession, false);
|
keycloakRule.stopSession(samlServerSession, false);
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
protected UserRepresentation getUser(String userId) {
|
||||||
|
return testRealm().users().get(userId).toRepresentation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -319,7 +313,7 @@ public class RegisterTest {
|
||||||
@Test
|
@Test
|
||||||
public void registerUserSuccess_emailAsUsername() {
|
public void registerUserSuccess_emailAsUsername() {
|
||||||
configureRelamRegistrationEmailAsUsername(true);
|
configureRelamRegistrationEmailAsUsername(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.clickRegister();
|
loginPage.clickRegister();
|
||||||
|
@ -332,7 +326,7 @@ public class RegisterTest {
|
||||||
String userId = events.expectRegister("registerUserSuccessE@email", "registerUserSuccessE@email").assertEvent().getUserId();
|
String userId = events.expectRegister("registerUserSuccessE@email", "registerUserSuccessE@email").assertEvent().getUserId();
|
||||||
events.expectLogin().detail("username", "registerusersuccesse@email").user(userId).assertEvent();
|
events.expectLogin().detail("username", "registerusersuccesse@email").user(userId).assertEvent();
|
||||||
|
|
||||||
UserModel user = getUser(userId);
|
UserRepresentation user = getUser(userId);
|
||||||
Assert.assertNotNull(user);
|
Assert.assertNotNull(user);
|
||||||
Assert.assertNotNull(user.getCreatedTimestamp());
|
Assert.assertNotNull(user.getCreatedTimestamp());
|
||||||
// test that timestamp is current with 10s tollerance
|
// test that timestamp is current with 10s tollerance
|
||||||
|
@ -344,12 +338,9 @@ public class RegisterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void configureRelamRegistrationEmailAsUsername(final boolean value) {
|
protected void configureRelamRegistrationEmailAsUsername(final boolean value) {
|
||||||
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
RealmRepresentation realm = testRealm().toRepresentation();
|
||||||
@Override
|
realm.setRegistrationEmailAsUsername(value);
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
testRealm().update(realm);
|
||||||
appRealm.setRegistrationEmailAsUsername(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,122 +19,96 @@ package org.keycloak.testsuite.forms;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
import org.keycloak.events.Errors;
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.Event;
|
|
||||||
import org.keycloak.events.EventType;
|
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.AssertEvents;
|
||||||
import org.keycloak.testsuite.Constants;
|
//import org.keycloak.testsuite.Constants;
|
||||||
import org.keycloak.testsuite.MailUtil;
|
import org.keycloak.testsuite.util.MailUtils;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
|
||||||
import org.keycloak.testsuite.pages.*;
|
import org.keycloak.testsuite.pages.*;
|
||||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
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.MessagingException;
|
||||||
import javax.mail.Multipart;
|
import javax.mail.Multipart;
|
||||||
import javax.mail.internet.MimeMessage;
|
import javax.mail.internet.MimeMessage;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
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.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @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;
|
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();
|
@Before
|
||||||
creds.setType(CredentialRepresentation.PASSWORD);
|
public void setAccessCodeLifespanUserAction() {
|
||||||
creds.setValue("password");
|
// 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;
|
private static String userId;
|
||||||
|
|
||||||
@Rule
|
|
||||||
public WebRule webRule = new WebRule(this);
|
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public GreenMailRule greenMail = new GreenMailRule();
|
public GreenMailRule greenMail = new GreenMailRule();
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected WebDriver driver;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected OAuthClient oauth;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected AppPage appPage;
|
protected AppPage appPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected ErrorPage errorPage;
|
protected ErrorPage errorPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected InfoPage infoPage;
|
protected InfoPage infoPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected VerifyEmailPage verifyEmailPage;
|
protected VerifyEmailPage verifyEmailPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginPasswordResetPage resetPasswordPage;
|
protected LoginPasswordResetPage resetPasswordPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginPasswordUpdatePage updatePasswordPage;
|
protected LoginPasswordUpdatePage updatePasswordPage;
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
public AssertEvents events = new AssertEvents(this);
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resetPasswordLink() throws IOException, MessagingException {
|
public void resetPasswordLink() throws IOException, MessagingException {
|
||||||
String username = "login-test";
|
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);
|
driver.navigate().to(resetUri);
|
||||||
|
|
||||||
resetPasswordPage.assertCurrent();
|
resetPasswordPage.assertCurrent();
|
||||||
|
@ -146,7 +120,7 @@ public class ResetPasswordTest {
|
||||||
|
|
||||||
events.expectRequiredAction(EventType.SEND_RESET_PASSWORD)
|
events.expectRequiredAction(EventType.SEND_RESET_PASSWORD)
|
||||||
.user(userId)
|
.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")
|
.client("account")
|
||||||
.detail(Details.USERNAME, username)
|
.detail(Details.USERNAME, username)
|
||||||
.detail(Details.EMAIL, "login@test.com")
|
.detail(Details.EMAIL, "login@test.com")
|
||||||
|
@ -166,12 +140,12 @@ public class ResetPasswordTest {
|
||||||
updatePasswordPage.changePassword("resetPassword", "resetPassword");
|
updatePasswordPage.changePassword("resetPassword", "resetPassword");
|
||||||
|
|
||||||
String sessionId = events.expectRequiredAction(EventType.UPDATE_PASSWORD)
|
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")
|
.client("account")
|
||||||
.user(userId).detail(Details.USERNAME, username).assertEvent().getSessionId();
|
.user(userId).detail(Details.USERNAME, username).assertEvent().getSessionId();
|
||||||
|
|
||||||
events.expectLogin().user(userId).detail(Details.USERNAME, username)
|
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")
|
.client("account")
|
||||||
.session(sessionId).assertEvent();
|
.session(sessionId).assertEvent();
|
||||||
|
|
||||||
|
@ -213,7 +187,7 @@ public class ResetPasswordTest {
|
||||||
|
|
||||||
loginPage.login("login@test.com", "password");
|
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");
|
String code = oauth.getCurrentQuery().get("code");
|
||||||
OAuthClient.AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code, "password");
|
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();
|
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
|
@Test
|
||||||
public void resetPasswordMissingUsername() throws IOException, MessagingException, InterruptedException {
|
public void resetPasswordMissingUsername() throws IOException, MessagingException, InterruptedException {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
|
@ -373,9 +347,9 @@ public class ResetPasswordTest {
|
||||||
assertEquals("Please specify username.", resetPasswordPage.getErrorMessage());
|
assertEquals("Please specify username.", resetPasswordPage.getErrorMessage());
|
||||||
|
|
||||||
assertEquals(0, greenMail.getReceivedMessages().length);
|
assertEquals(0, greenMail.getReceivedMessages().length);
|
||||||
|
|
||||||
events.expectRequiredAction(EventType.RESET_PASSWORD).user((String) null).session((String) null).clearDetails().error("username_missing").assertEvent();
|
events.expectRequiredAction(EventType.RESET_PASSWORD).user((String) null).session((String) null).clearDetails().error("username_missing").assertEvent();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -401,7 +375,7 @@ public class ResetPasswordTest {
|
||||||
|
|
||||||
String changePasswordUrl = getPasswordResetEmailLink(message);
|
String changePasswordUrl = getPasswordResetEmailLink(message);
|
||||||
|
|
||||||
Time.setOffset(1800 + 23);
|
setTimeOffset(1800 + 23);
|
||||||
|
|
||||||
driver.navigate().to(changePasswordUrl.trim());
|
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();
|
events.expectRequiredAction(EventType.RESET_PASSWORD).error("expired_code").client("test-app").user((String) null).session((String) null).clearDetails().assertEvent();
|
||||||
} finally {
|
} finally {
|
||||||
Time.setOffset(0);
|
setTimeOffset(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resetPasswordExpiredCodeShort() throws IOException, MessagingException, InterruptedException {
|
public void resetPasswordExpiredCodeShort() throws IOException, MessagingException, InterruptedException {
|
||||||
final AtomicInteger originalValue = new AtomicInteger();
|
final AtomicInteger originalValue = new AtomicInteger();
|
||||||
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
|
||||||
@Override
|
RealmRepresentation realmRep = testRealm().toRepresentation();
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
originalValue.set(realmRep.getAccessCodeLifespan());
|
||||||
originalValue.set(appRealm.getAccessCodeLifespan());
|
realmRep.setAccessCodeLifespanUserAction(60);
|
||||||
appRealm.setAccessCodeLifespanUserAction(60);
|
testRealm().update(realmRep);
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
|
@ -447,7 +419,7 @@ public class ResetPasswordTest {
|
||||||
|
|
||||||
String changePasswordUrl = getPasswordResetEmailLink(message);
|
String changePasswordUrl = getPasswordResetEmailLink(message);
|
||||||
|
|
||||||
Time.setOffset(70);
|
setTimeOffset(70);
|
||||||
|
|
||||||
driver.navigate().to(changePasswordUrl.trim());
|
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();
|
events.expectRequiredAction(EventType.RESET_PASSWORD).error("expired_code").client("test-app").user((String) null).session((String) null).clearDetails().assertEvent();
|
||||||
} finally {
|
} finally {
|
||||||
Time.setOffset(0);
|
setTimeOffset(0);
|
||||||
|
|
||||||
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
|
||||||
@Override
|
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
|
||||||
appRealm.setAccessCodeLifespanUserAction(originalValue.get());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resetPasswordDisabledUser() throws IOException, MessagingException, InterruptedException {
|
public void resetPasswordDisabledUser() throws IOException, MessagingException, InterruptedException {
|
||||||
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
UserRepresentation user = findUser("login-test");
|
||||||
@Override
|
user.setEnabled(false);
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
updateUser(user);
|
||||||
session.users().getUserByUsername("login-test", appRealm).setEnabled(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
loginPage.open();
|
||||||
loginPage.open();
|
loginPage.resetPassword();
|
||||||
loginPage.resetPassword();
|
|
||||||
|
|
||||||
resetPasswordPage.assertCurrent();
|
resetPasswordPage.assertCurrent();
|
||||||
|
|
||||||
resetPasswordPage.changePassword("login-test");
|
resetPasswordPage.changePassword("login-test");
|
||||||
|
|
||||||
loginPage.assertCurrent();
|
loginPage.assertCurrent();
|
||||||
assertEquals("You should receive an email shortly with further instructions.", loginPage.getSuccessMessage());
|
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();
|
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resetPasswordNoEmail() throws IOException, MessagingException, InterruptedException {
|
public void resetPasswordNoEmail() throws IOException, MessagingException, InterruptedException {
|
||||||
final String[] email = new String[1];
|
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.open();
|
loginPage.resetPassword();
|
||||||
loginPage.resetPassword();
|
|
||||||
|
|
||||||
resetPasswordPage.assertCurrent();
|
resetPasswordPage.assertCurrent();
|
||||||
|
|
||||||
resetPasswordPage.changePassword("login-test");
|
resetPasswordPage.changePassword("login-test");
|
||||||
|
|
||||||
loginPage.assertCurrent();
|
loginPage.assertCurrent();
|
||||||
assertEquals("You should receive an email shortly with further instructions.", loginPage.getSuccessMessage());
|
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();
|
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]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resetPasswordWrongSmtp() throws IOException, MessagingException, InterruptedException {
|
public void resetPasswordWrongSmtp() throws IOException, MessagingException, InterruptedException {
|
||||||
final String[] host = new String[1];
|
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 {
|
Map<String, String> smtpConfig = new HashMap<>();
|
||||||
loginPage.open();
|
smtpConfig.putAll(testRealm().toRepresentation().getSmtpServer());
|
||||||
loginPage.resetPassword();
|
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)
|
assertEquals(0, greenMail.getReceivedMessages().length);
|
||||||
.session((String)null)
|
|
||||||
.detail(Details.USERNAME, "login-test").removeDetail(Details.CODE_ID).error(Errors.EMAIL_SEND_FAILED).assertEvent();
|
events.expectRequiredAction(EventType.SEND_RESET_PASSWORD_ERROR).user(userId)
|
||||||
} finally {
|
.session((String)null)
|
||||||
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
.detail(Details.USERNAME, "login-test").removeDetail(Details.CODE_ID).error(Errors.EMAIL_SEND_FAILED).assertEvent();
|
||||||
@Override
|
}
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
|
||||||
Map<String, String> smtpConfig = new HashMap<>();
|
private void setPasswordPolicy(String policy) {
|
||||||
smtpConfig.putAll(appRealm.getSmtpConfig());
|
RealmRepresentation realmRep = testRealm().toRepresentation();
|
||||||
smtpConfig.put("host",host[0]);
|
realmRep.setPasswordPolicy(policy);
|
||||||
appRealm.setSmtpConfig(smtpConfig);
|
testRealm().update(realmRep);
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resetPasswordWithLengthPasswordPolicy() throws IOException, MessagingException {
|
public void resetPasswordWithLengthPasswordPolicy() throws IOException, MessagingException {
|
||||||
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
setPasswordPolicy("length");
|
||||||
@Override
|
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
|
||||||
appRealm.setPasswordPolicy(new PasswordPolicy("length"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.resetPassword();
|
loginPage.resetPassword();
|
||||||
|
@ -640,62 +567,51 @@ public class ResetPasswordTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resetPasswordWithPasswordHisoryPolicy() throws IOException, MessagingException {
|
public void resetPasswordWithPasswordHisoryPolicy() throws IOException, MessagingException {
|
||||||
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
//Block passwords that are equal to previous passwords. Default value is 3.
|
||||||
@Override
|
setPasswordPolicy("passwordHistory");
|
||||||
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"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Time.setOffset(2000000);
|
setTimeOffset(2000000);
|
||||||
resetPassword("login-test", "password1");
|
resetPassword("login-test", "password1");
|
||||||
|
|
||||||
resetPasswordInvalidPassword("login-test", "password1", "Invalid password: must not be equal to any of last 3 passwords.");
|
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");
|
resetPassword("login-test", "password2");
|
||||||
|
|
||||||
resetPasswordInvalidPassword("login-test", "password1", "Invalid password: must not be equal to any of last 3 passwords.");
|
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", "password2", "Invalid password: must not be equal to any of last 3 passwords.");
|
||||||
|
|
||||||
Time.setOffset(8000000);
|
setTimeOffset(8000000);
|
||||||
resetPassword("login-test", "password3");
|
resetPassword("login-test", "password3");
|
||||||
|
|
||||||
resetPasswordInvalidPassword("login-test", "password1", "Invalid password: must not be equal to any of last 3 passwords.");
|
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", "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.");
|
resetPasswordInvalidPassword("login-test", "password3", "Invalid password: must not be equal to any of last 3 passwords.");
|
||||||
|
|
||||||
resetPassword("login-test", "password");
|
resetPassword("login-test", "password");
|
||||||
} finally {
|
} finally {
|
||||||
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
|
setTimeOffset(0);
|
||||||
@Override
|
|
||||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
|
||||||
appRealm.setPasswordPolicy(new PasswordPolicy(null));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Time.setOffset(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPasswordResetEmailLink(MimeMessage message) throws IOException, MessagingException {
|
public static String getPasswordResetEmailLink(MimeMessage message) throws IOException, MessagingException {
|
||||||
Multipart multipart = (Multipart) message.getContent();
|
Multipart multipart = (Multipart) message.getContent();
|
||||||
|
|
||||||
final String textContentType = multipart.getBodyPart(0).getContentType();
|
final String textContentType = multipart.getBodyPart(0).getContentType();
|
||||||
|
|
||||||
assertEquals("text/plain; charset=UTF-8", textContentType);
|
assertEquals("text/plain; charset=UTF-8", textContentType);
|
||||||
|
|
||||||
final String textBody = (String) multipart.getBodyPart(0).getContent();
|
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();
|
final String htmlContentType = multipart.getBodyPart(1).getContentType();
|
||||||
|
|
||||||
assertEquals("text/html; charset=UTF-8", htmlContentType);
|
assertEquals("text/html; charset=UTF-8", htmlContentType);
|
||||||
|
|
||||||
final String htmlBody = (String) multipart.getBodyPart(1).getContent();
|
final String htmlBody = (String) multipart.getBodyPart(1).getContent();
|
||||||
final String htmlChangePwdUrl = MailUtil.getLink(htmlBody);
|
final String htmlChangePwdUrl = MailUtils.getLink(htmlBody);
|
||||||
|
|
||||||
assertEquals(htmlChangePwdUrl, textChangePwdUrl);
|
assertEquals(htmlChangePwdUrl, textChangePwdUrl);
|
||||||
|
|
||||||
return htmlChangePwdUrl;
|
return htmlChangePwdUrl;
|
|
@ -16,22 +16,23 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.testsuite.forms;
|
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.Assert;
|
||||||
import org.junit.ClassRule;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.events.Details;
|
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.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.AccountUpdateProfilePage;
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
import org.keycloak.testsuite.rule.WebResource;
|
|
||||||
import org.keycloak.testsuite.rule.WebRule;
|
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
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 <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
|
@Drone
|
||||||
public static KeycloakRule keycloakRule = new KeycloakRule();
|
@Different
|
||||||
|
protected WebDriver driver2;
|
||||||
|
|
||||||
@Rule
|
@Page
|
||||||
public WebRule webRule = new WebRule(this);
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected OAuthClient oauth;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected WebDriver driver;
|
|
||||||
|
|
||||||
@WebResource
|
|
||||||
protected AppPage appPage;
|
protected AppPage appPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
@WebResource
|
@Page
|
||||||
protected AccountUpdateProfilePage profilePage;
|
protected AccountUpdateProfilePage profilePage;
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
public AssertEvents events = new AssertEvents(this);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void loginSuccess() {
|
public void loginSuccess() {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
loginPage.login("test-user@localhost", "password");
|
loginPage.login("test-user@localhost", "password");
|
||||||
|
|
||||||
assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||||
|
|
||||||
|
@ -92,7 +90,7 @@ public class SSOTest {
|
||||||
assertEquals(sessionId, sessionId2);
|
assertEquals(sessionId, sessionId2);
|
||||||
|
|
||||||
// Expire session
|
// Expire session
|
||||||
keycloakRule.removeUserSession(sessionId);
|
testingClient.testing().removeUserSession("test", sessionId);
|
||||||
|
|
||||||
oauth.doLogin("test-user@localhost", "password");
|
oauth.doLogin("test-user@localhost", "password");
|
||||||
|
|
||||||
|
@ -110,15 +108,18 @@ public class SSOTest {
|
||||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||||
|
|
||||||
Event login1 = events.expectLogin().assertEvent();
|
EventRepresentation login1 = events.expectLogin().assertEvent();
|
||||||
|
|
||||||
WebDriver driver2 = WebRule.createWebDriver();
|
|
||||||
try {
|
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.state("mystate");
|
||||||
oauth2.doLogin("test-user@localhost", "password");
|
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.assertEquals(RequestType.AUTH_RESPONSE, RequestType.valueOf(driver2.getTitle()));
|
||||||
Assert.assertNotNull(oauth2.getCurrentQuery().get(OAuth2Constants.CODE));
|
Assert.assertNotNull(oauth2.getCurrentQuery().get(OAuth2Constants.CODE));
|
|
@ -43,6 +43,11 @@ public class ClientBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClientBuilder name(String name) {
|
||||||
|
rep.setName(name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ClientBuilder clientId(String clientId) {
|
public ClientBuilder clientId(String clientId) {
|
||||||
rep.setClientId(clientId);
|
rep.setClientId(clientId);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -122,20 +122,33 @@ public class UserBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserBuilder totpSecret(String totpSecret) {
|
public UserBuilder secret(String type, String secret) {
|
||||||
if (rep.getCredentials() == null) {
|
if (rep.getCredentials() == null) {
|
||||||
rep.setCredentials(new LinkedList<CredentialRepresentation>());
|
rep.setCredentials(new LinkedList<CredentialRepresentation>());
|
||||||
}
|
}
|
||||||
|
|
||||||
CredentialRepresentation credential = new CredentialRepresentation();
|
CredentialRepresentation credential = new CredentialRepresentation();
|
||||||
credential.setType(CredentialRepresentation.TOTP);
|
credential.setType(type);
|
||||||
credential.setValue(totpSecret);
|
credential.setValue(secret);
|
||||||
|
|
||||||
rep.getCredentials().add(credential);
|
rep.getCredentials().add(credential);
|
||||||
rep.setTotp(true);
|
rep.setTotp(true);
|
||||||
return this;
|
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() {
|
public UserRepresentation build() {
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue