/*
* 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.Rule;
import org.junit.Test;
import org.keycloak.events.Details;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.LoginPage;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import org.keycloak.testsuite.auth.page.account.AccountManagement;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
* @author Stan Silvert ssilvert@redhat.com (C) 2016 Red Hat Inc.
*/
public class LogoutTest extends AbstractTestRealmKeycloakTest {
@Rule
public AssertEvents events = new AssertEvents(this);
@Page
protected AppPage appPage;
@Page
protected LoginPage loginPage;
@Page
protected AccountManagement accountManagementPage;
@Override
public void configureTestRealm(RealmRepresentation testRealm) {
}
@Test
public void logoutRedirect() {
loginPage.open();
loginPage.login("test-user@localhost", "password");
assertTrue(appPage.isCurrent());
String sessionId = events.expectLogin().assertEvent().getSessionId();
String redirectUri = AppPage.baseUrl + "?logout";
String logoutUrl = oauth.getLogoutUrl().redirectUri(redirectUri).build();
driver.navigate().to(logoutUrl);
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
assertEquals(redirectUri, driver.getCurrentUrl());
loginPage.open();
loginPage.login("test-user@localhost", "password");
assertTrue(appPage.isCurrent());
String sessionId2 = events.expectLogin().assertEvent().getSessionId();
assertNotEquals(sessionId, sessionId2);
driver.navigate().to(logoutUrl);
events.expectLogout(sessionId2).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
}
@Test
public void logoutSession() {
loginPage.open();
loginPage.login("test-user@localhost", "password");
assertTrue(appPage.isCurrent());
String sessionId = events.expectLogin().assertEvent().getSessionId();
String logoutUrl = oauth.getLogoutUrl().sessionState(sessionId).build();
driver.navigate().to(logoutUrl);
events.expectLogout(sessionId).removeDetail(Details.REDIRECT_URI).assertEvent();
assertEquals(logoutUrl, driver.getCurrentUrl());
loginPage.open();
loginPage.login("test-user@localhost", "password");
assertTrue(appPage.isCurrent());
String sessionId2 = events.expectLogin().assertEvent().getSessionId();
assertNotEquals(sessionId, sessionId2);
}
@Test
public void logoutMultipleSessions() throws IOException {
// Login session 1
loginPage.open();
loginPage.login("test-user@localhost", "password");
assertTrue(appPage.isCurrent());
String sessionId = events.expectLogin().assertEvent().getSessionId();
// Check session 1 logged-in
oauth.openLoginForm();
events.expectLogin().session(sessionId).removeDetail(Details.USERNAME).assertEvent();
// Logout session 1 by redirect
driver.navigate().to(oauth.getLogoutUrl().redirectUri(AppPage.baseUrl).build());
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, AppPage.baseUrl).assertEvent();
// Check session 1 not logged-in
oauth.openLoginForm();
loginPage.assertCurrent();
// Login session 3
oauth.doLogin("test-user@localhost", "password");
String sessionId3 = events.expectLogin().assertEvent().getSessionId();
assertNotEquals(sessionId, sessionId3);
// Check session 3 logged-in
oauth.openLoginForm();
events.expectLogin().session(sessionId3).removeDetail(Details.USERNAME).assertEvent();
// Logout session 3 by redirect
driver.navigate().to(oauth.getLogoutUrl().redirectUri(AppPage.baseUrl).build());
events.expectLogout(sessionId3).detail(Details.REDIRECT_URI, AppPage.baseUrl).assertEvent();
}
//KEYCLOAK-2741
@Test
public void logoutWithRememberMe() {
setRememberMe(true);
try {
loginPage.open();
assertFalse(loginPage.isRememberMeChecked());
loginPage.setRememberMe(true);
assertTrue(loginPage.isRememberMeChecked());
loginPage.login("test-user@localhost", "password");
String sessionId = events.expectLogin().assertEvent().getSessionId();
// Expire session
testingClient.testing().removeUserSession("test", sessionId);
// Assert rememberMe checked and username/email prefilled
loginPage.open();
assertTrue(loginPage.isRememberMeChecked());
assertEquals("test-user@localhost", loginPage.getUsername());
loginPage.login("test-user@localhost", "password");
//log out
appPage.openAccount();
accountManagementPage.signOut();
// Assert rememberMe not checked nor username/email prefilled
assertTrue(loginPage.isCurrent());
assertFalse(loginPage.isRememberMeChecked());
assertNotEquals("test-user@localhost", loginPage.getUsername());
} finally {
setRememberMe(false);
}
}
private void setRememberMe(boolean enabled) {
RealmRepresentation rep = adminClient.realm("test").toRepresentation();
rep.setRememberMe(enabled);
adminClient.realm("test").update(rep);
}
@Test
public void logoutSessionWhenLoggedOutByAdmin() {
loginPage.open();
loginPage.login("test-user@localhost", "password");
assertTrue(appPage.isCurrent());
String sessionId = events.expectLogin().assertEvent().getSessionId();
adminClient.realm("test").logoutAll();
String logoutUrl = oauth.getLogoutUrl().sessionState(sessionId).build();
driver.navigate().to(logoutUrl);
assertEquals(logoutUrl, driver.getCurrentUrl());
loginPage.open();
loginPage.login("test-user@localhost", "password");
assertTrue(appPage.isCurrent());
String sessionId2 = events.expectLogin().assertEvent().getSessionId();
assertNotEquals(sessionId, sessionId2);
driver.navigate().to(logoutUrl);
events.expectLogout(sessionId2).removeDetail(Details.REDIRECT_URI).assertEvent();
}
}