ClientSession everywhere refactor phase1

This commit is contained in:
Bill Burke committed 2014-09-26 17:44:33 -04:00
1 parent 0bf6c36ca7
commit 524b423733
55 files changed
+1330 -667

No files matched your search

@@ -124,6 +124,15 @@ public class AssertEvents implements TestRule, EventListenerProviderFactory {
.session(isUUID());
}
public ExpectedEvent expectSocialLogin() {
return expect(EventType.SOCIAL_LOGIN)
.detail(Details.CODE_ID, isCodeId())
.detail(Details.USERNAME, DEFAULT_USERNAME)
.detail(Details.AUTH_METHOD, "form")
.detail(Details.REDIRECT_URI, DEFAULT_REDIRECT_URI)
.session(isUUID());
}
public ExpectedEvent expectCodeToToken(String codeId, String sessionId) {
return expect(EventType.CODE_TO_TOKEN)
.detail(Details.CODE_ID, codeId)
@@ -277,6 +286,11 @@ public class AssertEvents implements TestRule, EventListenerProviderFactory {
return this;
}
public ExpectedEvent clearDetails() {
if (details != null) details.clear();
return this;
}
public ExpectedEvent error(String error) {
expected.setError(error);
return this;
@@ -1,6 +1,7 @@
package org.keycloak.testsuite;
import org.keycloak.OAuth2Constants;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.social.AuthCallback;
import org.keycloak.social.AuthRequest;
import org.keycloak.social.SocialAccessDeniedException;
@@ -19,7 +20,7 @@ public class DummySocial implements SocialProvider {
}
@Override
public AuthRequest getAuthUrl(SocialProviderConfig config, String state) throws SocialProviderException {
public AuthRequest getAuthUrl(ClientSessionModel clientSession, SocialProviderConfig config, String state) throws SocialProviderException {
return AuthRequest.create(AUTH_PATH)
.setQueryParam(OAuth2Constants.RESPONSE_TYPE, "token")
.setQueryParam(OAuth2Constants.REDIRECT_URI, config.getCallbackUrl())
@@ -32,7 +33,7 @@ public class DummySocial implements SocialProvider {
}
@Override
public SocialUser processCallback(SocialProviderConfig config, AuthCallback callback) throws SocialProviderException {
public SocialUser processCallback(ClientSessionModel clientSession, SocialProviderConfig config, AuthCallback callback) throws SocialProviderException {
String error = callback.getQueryParam(OAuth2Constants.ERROR);
if (error != null) {
throw new SocialAccessDeniedException();
@@ -75,7 +75,7 @@ public class OAuthClient {
private String redirectUri = "http://localhost:8081/app/auth";
private String state;
private String state = "mystate";
private PublicKey realmPublicKey;
@@ -140,6 +140,7 @@ public class AccountTest {
@Before
public void before() {
oauth.state("mystate"); // keycloak enforces that a state param has been sent by client
userId = keycloakRule.getUser("test", "test-user@localhost").getId();
}
@@ -159,6 +160,16 @@ public class AccountTest {
});
}
@Test
@Ignore
public void runit() throws Exception {
Thread.sleep(10000000);
}
@Test
public void returnToAppFromQueryParam() {
driver.navigate().to(AccountUpdateProfilePage.PATH + "?referrer=test-app");
@@ -446,6 +457,7 @@ public class AccountTest {
// Create second session
WebDriver driver2 = WebRule.createWebDriver();
OAuthClient oauth2 = new OAuthClient(driver2);
oauth2.state("mystate");
oauth2.doLogin("view-sessions", "password");
Event login2Event = events.expectLogin().user(userId).detail(Details.USERNAME, "view-sessions").assertEvent();
@@ -88,6 +88,7 @@ public class RequiredActionEmailVerificationTest {
@Before
public void before() {
oauth.state("mystate"); // have to set this as keycloak validates that state is sent
keycloakRule.configure(new KeycloakSetup() {
@Override
@@ -115,7 +116,8 @@ public class RequiredActionEmailVerificationTest {
String body = (String) message.getContent();
String verificationUrl = MailUtil.getLink(body);
Event sendEvent = events.expectRequiredAction(EventType.SEND_VERIFY_EMAIL).detail("email", "test-user@localhost").assertEvent();
AssertEvents.ExpectedEvent emailEvent = events.expectRequiredAction(EventType.SEND_VERIFY_EMAIL).detail("email", "test-user@localhost");
Event sendEvent = emailEvent.assertEvent();
String sessionId = sendEvent.getSessionId();
String mailCodeId = sendEvent.getDetails().get(Details.CODE_ID);
@@ -22,6 +22,7 @@
package org.keycloak.testsuite.actions;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
@@ -86,6 +87,12 @@ public class RequiredActionResetPasswordTest {
@WebResource
protected LoginPasswordUpdatePage changePasswordPage;
@Before
public void before() {
oauth.state("mystate"); // have to set this as keycloak validates that state is sent
}
@Test
public void tempPassword() throws Exception {
loginPage.open();
@@ -145,6 +145,10 @@ public class LoginTotpTest {
@Test
public void loginWithTotpExpiredPasswordToken() throws Exception {
try {
loginPage.open();
loginPage.login("test-user@localhost", "password");
keycloakRule.configure(new KeycloakSetup() {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
@@ -153,9 +157,6 @@ public class LoginTotpTest {
}
});
loginPage.open();
loginPage.login("test-user@localhost", "password");
loginTotpPage.assertCurrent();
Thread.sleep(2000);
@@ -165,7 +166,11 @@ public class LoginTotpTest {
loginPage.assertCurrent();
Assert.assertEquals("Invalid username or password.", loginPage.getError());
events.expectLogin().error("invalid_user_credentials").removeDetail(Details.CODE_ID).session((String) null).assertEvent();
AssertEvents.ExpectedEvent expectedEvent = events.expectLogin().error("invalid_user_credentials")
.user((String)null)
.clearDetails()
.session((String) null);
expectedEvent.assertEvent();
} finally {
keycloakRule.configure(new KeycloakSetup() {
@Override
@@ -10,6 +10,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.services.protocol.OpenIdConnectProtocol;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.util.Time;
@@ -73,7 +74,7 @@ public class UserSessionProviderTest {
assertEquals(realm.findClient("test-app").getClientId(), session.getClient().getClientId());
assertEquals(sessions[0].getId(), session.getUserSession().getId());
assertEquals("http://redirect", session.getRedirectUri());
assertEquals("state", session.getState());
assertEquals("state", session.getNote(OpenIdConnectProtocol.STATE_PARAM));
assertEquals(2, session.getRoles().size());
assertTrue(session.getRoles().contains("one"));
assertTrue(session.getRoles().contains("two"));
@@ -245,7 +246,11 @@ public class UserSessionProviderTest {
for (int i = 0; i < 25; i++) {
UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0." + i, "form", false);
userSession.setStarted(Time.currentTime() + i);
session.sessions().createClientSession(realm, realm.findClient("test-app"), userSession, "http://redirect", "state", new HashSet<String>());
ClientSessionModel clientSession = session.sessions().createClientSession(realm, realm.findClient("test-app"));
clientSession.setUserSession(userSession);
clientSession.setRedirectUri("http://redirect");
clientSession.setRoles(new HashSet<String>());
clientSession.setNote(OpenIdConnectProtocol.STATE_PARAM, "state");
}
resetSession();
@@ -280,6 +285,15 @@ public class UserSessionProviderTest {
assertEquals(1, session.sessions().getActiveUserSessions(realm, realm.findClient("third-party")));
}
private ClientSessionModel createClientSession(ClientModel client, UserSessionModel userSession, String redirect, String state, Set<String> roles) {
ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
if (userSession != null) clientSession.setUserSession(userSession);
clientSession.setRedirectUri(redirect);
if (state != null) clientSession.setNote(OpenIdConnectProtocol.STATE_PARAM, state);
if (roles != null) clientSession.setRoles(roles);
return clientSession;
}
private UserSessionModel[] createSessions() {
UserSessionModel[] sessions = new UserSessionModel[3];
sessions[0] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.1", "form", true);
@@ -288,14 +302,14 @@ public class UserSessionProviderTest {
roles.add("one");
roles.add("two");
session.sessions().createClientSession(realm, realm.findClient("test-app"), sessions[0], "http://redirect", "state", roles);
session.sessions().createClientSession(realm, realm.findClient("third-party"), sessions[0], "http://redirect", "state", new HashSet<String>());
createClientSession(realm.findClient("test-app"), sessions[0], "http://redirect", "state", roles);
createClientSession(realm.findClient("third-party"), sessions[0], "http://redirect", "state", new HashSet<String>());
sessions[1] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user1", realm), "user1", "127.0.0.2", "form", true);
session.sessions().createClientSession(realm, realm.findClient("test-app"), sessions[1], "http://redirect", "state", new HashSet<String>());
createClientSession(realm.findClient("test-app"), sessions[1], "http://redirect", "state", new HashSet<String>());
sessions[2] = session.sessions().createUserSession(realm, session.users().getUserByUsername("user2", realm), "user2", "127.0.0.3", "form", true);
session.sessions().createClientSession(realm, realm.findClient("test-app"), sessions[2], "http://redirect", "state", new HashSet<String>());
createClientSession(realm.findClient("test-app"), sessions[2], "http://redirect", "state", new HashSet<String>());
resetSession();
@@ -135,7 +135,8 @@ public class AccessTokenTest {
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "invalid");
Assert.assertEquals(400, response.getStatusCode());
events.expectCodeToToken(codeId, loginEvent.getSessionId()).error("invalid_client_credentials").removeDetail(Details.TOKEN_ID).removeDetail(Details.REFRESH_TOKEN_ID).assertEvent();
AssertEvents.ExpectedEvent expectedEvent = events.expectCodeToToken(codeId, loginEvent.getSessionId()).error("invalid_client_credentials").removeDetail(Details.TOKEN_ID).removeDetail(Details.REFRESH_TOKEN_ID);
expectedEvent.assertEvent();
}
@Test
@@ -22,18 +22,23 @@
package org.keycloak.testsuite.oauth;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventType;
import org.keycloak.models.Constants;
import org.keycloak.models.RealmModel;
import org.keycloak.services.managers.AccessCode;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.OAuthClient;
import org.keycloak.testsuite.OAuthClient.AuthorizationCodeResponse;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebResource;
@@ -65,6 +70,9 @@ public class AuthorizationCodeTest {
@WebResource
protected LoginPage loginPage;
@WebResource
protected ErrorPage errorPage;
@Rule
public AssertEvents events = new AssertEvents(keycloakRule);
@@ -103,7 +111,7 @@ public class AuthorizationCodeTest {
String code = driver.findElement(By.id(OAuth2Constants.CODE)).getText();
keycloakRule.verifyCode(code);
String codeId = events.expectLogin().detail(Details.REDIRECT_URI, Constants.INSTALLED_APP_URN).assertEvent().getDetails().get(Details.CODE_ID);
String codeId = events.expectLogin().detail(Details.REDIRECT_URI, "http://localhost:8081/auth/realms/test/tokens/oauth/oob").assertEvent().getDetails().get(Details.CODE_ID);
assertCode(codeId, code);
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@@ -133,7 +141,10 @@ public class AuthorizationCodeTest {
String error = driver.findElement(By.id(OAuth2Constants.ERROR)).getText();
assertEquals("access_denied", error);
events.expectLogin().error("rejected_by_user").user((String) null).session((String) null).removeDetail(Details.USERNAME).removeDetail(Details.CODE_ID).detail(Details.REDIRECT_URI, Constants.INSTALLED_APP_URN).assertEvent().getDetails().get(Details.CODE_ID);
events.expectLogin().error("rejected_by_user").user((String) null).session((String) null)
.removeDetail(Details.USERNAME).removeDetail(Details.CODE_ID)
.detail(Details.REDIRECT_URI, "http://localhost:8081/auth/realms/test/tokens/oauth/oob")
.assertEvent().getDetails().get(Details.CODE_ID);
keycloakRule.update(new KeycloakRule.KeycloakSetup() {
@Override
@@ -167,22 +178,22 @@ public class AuthorizationCodeTest {
@Test
public void authorizationRequestNoState() throws IOException {
AuthorizationCodeResponse response = oauth.doLogin("test-user@localhost", "password");
oauth.state(null);
oauth.openLoginForm();
Assert.assertTrue(errorPage.isCurrent());
Assert.assertTrue(response.isRedirected());
Assert.assertNotNull(response.getCode());
Assert.assertNull(response.getState());
Assert.assertNull(response.getError());
keycloakRule.verifyCode(response.getCode());
String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID);
assertCode(codeId, response.getCode());
events.expect(EventType.LOGIN_ERROR)
.error(Errors.STATE_PARAM_NOT_FOUND)
.detail(Details.RESPONSE_TYPE, "code")
.detail(Details.REDIRECT_URI, oauth.getRedirectUri())
.user((String)null)
.assertEvent();
//assertCode(codeId, response.getCode());
}
private void assertCode(String expectedCodeId, String actualCode) {
AccessCode code = keycloakRule.verifyCode(actualCode);
assertEquals(expectedCodeId, code.getCodeId());
ClientSessionCode code = keycloakRule.verifyCode(actualCode);
assertEquals(expectedCodeId, code.getClientSession().getId());
}
}
@@ -55,6 +55,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@@ -163,21 +165,24 @@ public class AccessTokenPerfTest {
return b.build(realm).toString();
}
static Pattern actionParser = Pattern.compile("action=\"([^\"]+)\"");
@Override
public void run() {
//this.client = new ResteasyClientBuilder().build();
String state = "42";
Response response = client.target(getLoginFormUrl(state)).request().get();
URI uri = null;
if (200 == response.getStatus()) {
response.close();
Form form = new Form();
form.param("username", "test-user@localhost");
form.param("password", "password");
response = client.target(getProcessLoginUrl(state)).request().post(Entity.form(form));
String loginFormUrl = getLoginFormUrl(state);
String html = client.target(loginFormUrl).request().get(String.class);
Matcher matcher = actionParser.matcher(html);
matcher.find();
String actionUrl = matcher.group(1);
if (!actionUrl.startsWith("http")) {
actionUrl = UriBuilder.fromUri(actionUrl).scheme("http").host("localhost").port(8081).build().toString();
}
Form form = new Form();
form.param("username", "test-user@localhost");
form.param("password", "password");
Response response = client.target(actionUrl).request().post(Entity.form(form));
URI uri = null;
Assert.assertEquals(302, response.getStatus());
uri = response.getLocation();
for (String header : response.getHeaders().keySet()) {
@@ -191,7 +196,7 @@ public class AccessTokenPerfTest {
String code = getCode(uri);
Assert.assertNotNull(code);
Form form = new Form();
form = new Form();
form.param(OAuth2Constants.GRANT_TYPE, grantType)
.param(OAuth2Constants.CODE, code)
.param(OAuth2Constants.REDIRECT_URI, redirectUri);
@@ -27,6 +27,7 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.services.managers.AccessCode;
import org.keycloak.services.managers.ClientSessionCode;
import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.ApplicationServlet;
@@ -109,12 +110,12 @@ public class KeycloakRule extends AbstractKeycloakRule {
stopSession(session, true);
}
public AccessCode verifyCode(String code) {
public ClientSessionCode verifyCode(String code) {
KeycloakSession session = startSession();
try {
RealmModel realm = session.realms().getRealm("test");
try {
AccessCode accessCode = AccessCode.parse(code, session, realm);
ClientSessionCode accessCode = ClientSessionCode.parse(code, session, realm);
if (accessCode == null) {
Assert.fail("Invalid code");
}
@@ -114,14 +114,17 @@ public class SocialLoginTest {
String userId = events.expect(EventType.REGISTER)
.user(AssertEvents.isUUID())
.detail(Details.EMAIL, "bob@builder.com")
.detail(Details.RESPONSE_TYPE, "code")
.detail(Details.REGISTER_METHOD, "social@dummy")
.detail(Details.REDIRECT_URI, AssertEvents.DEFAULT_REDIRECT_URI)
.detail(Details.USERNAME, "1@dummy")
.session((String) null)
.assertEvent().getUserId();
Event loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "1@dummy").detail(Details.AUTH_METHOD, "social@dummy").assertEvent();
Event loginEvent = events.expectSocialLogin()
.user(userId)
.detail(Details.USERNAME, "1@dummy")
.detail(Details.AUTH_METHOD, "social@dummy")
.assertEvent();
String sessionId = loginEvent.getSessionId();
String codeId = loginEvent.getDetails().get(Details.CODE_ID);
@@ -153,7 +156,7 @@ public class SocialLoginTest {
driver.findElement(By.id("username")).sendKeys("dummy-user1");
driver.findElement(By.id("login")).click();
events.expectLogin().user(userId).detail(Details.USERNAME, "1@dummy").detail(Details.AUTH_METHOD, "social@dummy").assertEvent();
events.expectSocialLogin().user(userId).detail(Details.USERNAME, "1@dummy").detail(Details.AUTH_METHOD, "social@dummy").assertEvent();
}
@Test
@@ -199,8 +202,9 @@ public class SocialLoginTest {
Assert.assertTrue(loginPage.isCurrent());
Assert.assertEquals("Access denied", loginPage.getWarning());
events.expectLogin().error("rejected_by_user").user((String) null).session((String) null).detail(Details.AUTH_METHOD, "social@dummy").removeDetail(Details.USERNAME).removeDetail(Details.CODE_ID).assertEvent();
events.expectSocialLogin().error("rejected_by_user").user((String) null).session((String) null).detail(Details.AUTH_METHOD, "social@dummy").removeDetail(Details.USERNAME).removeDetail(Details.CODE_ID).assertEvent();
String src = driver.getPageSource();
loginPage.login("test-user@localhost", "password");
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
@@ -238,7 +242,6 @@ public class SocialLoginTest {
String userId = events.expect(EventType.REGISTER)
.user(AssertEvents.isUUID())
.detail(Details.EMAIL, "bob@builder.com")
.detail(Details.RESPONSE_TYPE, "code")
.detail(Details.REGISTER_METHOD, "social@dummy")
.detail(Details.REDIRECT_URI, AssertEvents.DEFAULT_REDIRECT_URI)
.detail(Details.USERNAME, "2@dummy")