/* * 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.model; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.keycloak.common.util.Time; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserManager; import org.keycloak.models.UserModel; import org.keycloak.services.managers.ClientManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.CommonClientSessionModel; import org.keycloak.testsuite.rule.KeycloakRule; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; /** * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> */ public class AuthenticationSessionProviderTest { @ClassRule public static KeycloakRule kc = new KeycloakRule(); private KeycloakSession session; private RealmModel realm; @Before public void before() { session = kc.startSession(); realm = session.realms().getRealm("test"); session.users().addUser(realm, "user1").setEmail("user1@localhost"); session.users().addUser(realm, "user2").setEmail("user2@localhost"); } @After public void after() { resetSession(); UserModel user1 = session.users().getUserByUsername("user1", realm); UserModel user2 = session.users().getUserByUsername("user2", realm); UserManager um = new UserManager(session); if (user1 != null) { um.removeUser(realm, user1); } if (user2 != null) { um.removeUser(realm, user2); } kc.stopSession(session, true); } private void resetSession() { kc.stopSession(session, true); session = kc.startSession(); realm = session.realms().getRealm("test"); } @Test public void testLoginSessionsCRUD() { ClientModel client1 = realm.getClientByClientId("test-app"); UserModel user1 = session.users().getUserByUsername("user1", realm); AuthenticationSessionModel authSession = session.authenticationSessions().createAuthenticationSession(realm, client1); authSession.setAction("foo"); authSession.setTimestamp(100); resetSession(); // Ensure session is here authSession = session.authenticationSessions().getAuthenticationSession(realm, authSession.getId()); testAuthenticationSession(authSession, client1.getId(), null, "foo"); Assert.assertEquals(100, authSession.getTimestamp()); // Update and commit authSession.setAction("foo-updated"); authSession.setTimestamp(200); authSession.setAuthenticatedUser(session.users().getUserByUsername("user1", realm)); resetSession(); // Ensure session was updated authSession = session.authenticationSessions().getAuthenticationSession(realm, authSession.getId()); testAuthenticationSession(authSession, client1.getId(), user1.getId(), "foo-updated"); Assert.assertEquals(200, authSession.getTimestamp()); // Remove and commit session.authenticationSessions().removeAuthenticationSession(realm, authSession); resetSession(); // Ensure session was removed Assert.assertNull(session.authenticationSessions().getAuthenticationSession(realm, authSession.getId())); } @Test public void testAuthenticationSessionRestart() { ClientModel client1 = realm.getClientByClientId("test-app"); UserModel user1 = session.users().getUserByUsername("user1", realm); AuthenticationSessionModel authSession = session.authenticationSessions().createAuthenticationSession(realm, client1); authSession.setAction("foo"); authSession.setTimestamp(100); authSession.setAuthenticatedUser(user1); authSession.setAuthNote("foo", "bar"); authSession.setClientNote("foo2", "bar2"); authSession.setExecutionStatus("123", CommonClientSessionModel.ExecutionStatus.SUCCESS); resetSession(); client1 = realm.getClientByClientId("test-app"); authSession = session.authenticationSessions().getAuthenticationSession(realm, authSession.getId()); authSession.restartSession(realm, client1); resetSession(); authSession = session.authenticationSessions().getAuthenticationSession(realm, authSession.getId()); testAuthenticationSession(authSession, client1.getId(), null, null); Assert.assertTrue(authSession.getTimestamp() > 0); Assert.assertTrue(authSession.getClientNotes().isEmpty()); Assert.assertNull(authSession.getAuthNote("foo2")); Assert.assertTrue(authSession.getExecutionStatus().isEmpty()); } @Test public void testExpiredAuthSessions() { try { realm.setAccessCodeLifespan(10); realm.setAccessCodeLifespanUserAction(10); realm.setAccessCodeLifespanLogin(30); // Login lifespan is largest String authSessionId = session.authenticationSessions().createAuthenticationSession(realm, realm.getClientByClientId("test-app")).getId(); resetSession(); Time.setOffset(25); session.authenticationSessions().removeExpired(realm); resetSession(); assertNotNull(session.authenticationSessions().getAuthenticationSession(realm, authSessionId)); Time.setOffset(35); session.authenticationSessions().removeExpired(realm); resetSession(); assertNull(session.authenticationSessions().getAuthenticationSession(realm, authSessionId)); // User action is largest realm.setAccessCodeLifespanUserAction(40); Time.setOffset(0); authSessionId = session.authenticationSessions().createAuthenticationSession(realm, realm.getClientByClientId("test-app")).getId(); resetSession(); Time.setOffset(35); session.authenticationSessions().removeExpired(realm); resetSession(); assertNotNull(session.authenticationSessions().getAuthenticationSession(realm, authSessionId)); Time.setOffset(45); session.authenticationSessions().removeExpired(realm); resetSession(); assertNull(session.authenticationSessions().getAuthenticationSession(realm, authSessionId)); // Access code is largest realm.setAccessCodeLifespan(50); Time.setOffset(0); authSessionId = session.authenticationSessions().createAuthenticationSession(realm, realm.getClientByClientId("test-app")).getId(); resetSession(); Time.setOffset(45); session.authenticationSessions().removeExpired(realm); resetSession(); assertNotNull(session.authenticationSessions().getAuthenticationSession(realm, authSessionId)); Time.setOffset(55); session.authenticationSessions().removeExpired(realm); resetSession(); assertNull(session.authenticationSessions().getAuthenticationSession(realm, authSessionId)); } finally { Time.setOffset(0); realm.setAccessCodeLifespan(60); realm.setAccessCodeLifespanUserAction(300); realm.setAccessCodeLifespanLogin(1800); } } @Test public void testOnRealmRemoved() { RealmModel fooRealm = session.realms().createRealm("foo-realm"); ClientModel fooClient = fooRealm.addClient("foo-client"); String authSessionId = session.authenticationSessions().createAuthenticationSession(realm, realm.getClientByClientId("test-app")).getId(); String authSessionId2 = session.authenticationSessions().createAuthenticationSession(fooRealm, fooClient).getId(); resetSession(); new RealmManager(session).removeRealm(session.realms().getRealmByName("foo-realm")); resetSession(); AuthenticationSessionModel authSession = session.authenticationSessions().getAuthenticationSession(realm, authSessionId); testAuthenticationSession(authSession, realm.getClientByClientId("test-app").getId(), null, null); Assert.assertNull(session.authenticationSessions().getAuthenticationSession(realm, authSessionId2)); } @Test public void testOnClientRemoved() { String authSessionId = session.authenticationSessions().createAuthenticationSession(realm, realm.getClientByClientId("test-app")).getId(); String authSessionId2 = session.authenticationSessions().createAuthenticationSession(realm, realm.getClientByClientId("third-party")).getId(); String testAppClientUUID = realm.getClientByClientId("test-app").getId(); resetSession(); new ClientManager(new RealmManager(session)).removeClient(realm, realm.getClientByClientId("third-party")); resetSession(); AuthenticationSessionModel authSession = session.authenticationSessions().getAuthenticationSession(realm, authSessionId); testAuthenticationSession(authSession, testAppClientUUID, null, null); Assert.assertNull(session.authenticationSessions().getAuthenticationSession(realm, authSessionId2)); // Revert client realm.addClient("third-party"); } private void testAuthenticationSession(AuthenticationSessionModel authSession, String expectedClientId, String expectedUserId, String expectedAction) { Assert.assertEquals(expectedClientId, authSession.getClient().getId()); if (expectedUserId == null) { Assert.assertNull(authSession.getAuthenticatedUser()); } else { Assert.assertEquals(expectedUserId, authSession.getAuthenticatedUser().getId()); } if (expectedAction == null) { Assert.assertNull(authSession.getAction()); } else { Assert.assertEquals(expectedAction, authSession.getAction()); } } }