/* * Copyright (c) JForum Team. All rights reserved. * * The software in this package is published under the terms of the LGPL * license a copy of which has been included with this distribution in the * license.txt file. * * The JForum Project * http://www.jforum.net */ package net.jforum.core; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.List; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import net.jforum.core.exceptions.ForumException; import net.jforum.entities.Group; import net.jforum.entities.Role; import net.jforum.entities.Session; import net.jforum.entities.User; import net.jforum.entities.UserSession; import net.jforum.repository.SessionRepository; import net.jforum.repository.UserRepository; import net.jforum.security.RoleManager; import net.jforum.util.ConfigKeys; import net.jforum.util.JForumConfig; import net.jforum.util.MD5; import net.jforum.util.SecurityConstants; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; /** * @author Rafael Steil, Jonatan Cloutier */ @RunWith(MockitoJUnitRunner.class) public class SessionManagerTestCase { @Mock private JForumConfig config; @Mock private SessionRepository sessionRepository; @Mock private UserRepository userRepository; @Mock private HttpServletRequest request; @Mock private HttpServletResponse response; @Mock private HttpSession httpSession; @InjectMocks private SessionManager manager; Cookie[] goodCookie; @Before public void setup() { goodCookie = new Cookie[] { new Cookie("cookieNameData", "2"), new Cookie("cookieUserHash", MD5.hash("123")), new Cookie("cookieAutoLogin", "1") }; when(config.getInt(ConfigKeys.ANONYMOUS_USER_ID)).thenReturn(1); when(config.getValue(ConfigKeys.ANONYMOUS_USER_ID)).thenReturn("1"); when(config.getValue(ConfigKeys.COOKIE_USER_ID)).thenReturn("cookieNameData"); when(config.getValue(ConfigKeys.COOKIE_USER_HASH)).thenReturn("cookieUserHash"); when(config.getValue(ConfigKeys.COOKIE_AUTO_LOGIN)).thenReturn("cookieAutoLogin"); when(config.getValue(ConfigKeys.AUTHENTICATION_TYPE)).thenReturn("x"); when(request.getSession()).thenReturn(httpSession); } @After public void tearDown() { // FIXME: that shouldn't be needed... manager.reinitialiseAllSessions(); } @Test public void loginAfterTimeoutShouldFetchFromSessionRepositoryExpectLastVisitCorrect() { UserSession us = this.newUserSession("123"); us.getUser().setId(2); us.setCreationTime(1); us.setLastAccessedTime(2); us.setLastVisit(3); Session session = new Session(); session.setLastVisit(new Date(7)); when(sessionRepository.get(2)).thenReturn(session); manager.add(us); assertEquals(7, us.getLastVisit()); } @Test public void loginBackBeforeExpireExpectLastVisitCorrect() { UserSession us = this.newUserSession("123"); us.getUser().setId(2); us.setCreationTime(1); us.setLastVisit(9); manager.add(us); assertEquals(1, manager.getTotalUsers()); UserSession us2 = this.newUserSession("456"); us2.getUser().setId(2); us2.setCreationTime(1); us2.setLastVisit(5); manager.add(us2); assertEquals(9, us2.getLastVisit()); assertEquals(1, manager.getTotalUsers()); } @Test public void storeSessionNotRegisteredShouldIgnore() { manager.storeSession("invalid"); } @Test public void storeSessionExpectSuccess() { when(httpSession.getId()).thenReturn("123"); UserSession us = new UserSession(); us.setSessionId("123"); us.setRequest(request); us.setResponse(response); us.getUser().setId(2); manager.add(us); manager.storeSession("123"); verify(sessionRepository).add(notNull(Session.class)); } @Test public void storeSessionIsAnonymousShouldIgnore() { when(httpSession.getId()).thenReturn("123"); UserSession us = new UserSession(); us.setSessionId("123"); us.getUser().setId(1); manager.add(us); manager.storeSession("123"); } @Test public void autoLoginAllInformationIsGoodShouldAccept() { commonAutoLoginMockAction(); User user = new User(); user.setId(2); user.setSecurityHash("123"); UserSession userSession = new UserSession(); userSession.setRequest(request); userSession.setResponse(response); when(request.getCookies()).thenReturn(goodCookie); when(userRepository.get(2)).thenReturn(user); manager.refreshSession(userSession); verify(httpSession).setAttribute(ConfigKeys.LOGGED, "1"); } @Test public void autoLoginValidUserInvalidSecurityHashShouldDeny() { this.commonAutoLoginMockAction(); User user = new User(); user.setId(2); user.setSecurityHash("abc"); UserSession userSession = new UserSession(); userSession.setRequest(request); userSession.setResponse(response); when(request.getCookies()).thenReturn(goodCookie); when(userRepository.get(2)).thenReturn(user); when(userRepository.get(1)).thenReturn(new User()); manager.refreshSession(userSession); } @Test public void autoLoginValidUserEmptySecurityHashShouldDeny() { this.commonAutoLoginMockAction(); User user = new User(); user.setId(2); user.setSecurityHash(null); UserSession userSession = new UserSession(); userSession.setRequest(request); userSession.setResponse(response); when(request.getCookies()).thenReturn(goodCookie); when(userRepository.get(2)).thenReturn(user); when(userRepository.get(1)).thenReturn(new User()); manager.refreshSession(userSession); } @Test public void autoLoginValidUserHasDeletedFlagShouldDeny() { this.commonAutoLoginMockAction(); User user = new User(); user.setId(2); user.setDeleted(true); when(request.getCookies()).thenReturn(goodCookie); when(userRepository.get(2)).thenReturn(user); when(userRepository.get(1)).thenReturn(new User()); UserSession userSession = new UserSession(); userSession.setRequest(request); userSession.setResponse(response); manager.refreshSession(userSession); } @Test public void autoLoginValidUserNotfoundInRepositoryShouldDeny() { this.commonAutoLoginMockAction(); UserSession userSession = new UserSession(); userSession.setRequest(request); userSession.setResponse(response); when(request.getCookies()).thenReturn(goodCookie); when(userRepository.get(2)).thenReturn(null); when(userRepository.get(1)).thenReturn(new User()); manager.refreshSession(userSession); } @Test public void autoLoginValidUserCookieValueNot1ShouldDeny() { this.commonAutoLoginMockAction(); Cookie[] cookies = new Cookie[] { new Cookie("cookieNameData", "2"), new Cookie("cookieUserHash", "a"), new Cookie("cookieAutoLogin", "0") }; when(request.getCookies()).thenReturn(cookies); when(userRepository.get(1)).thenReturn(new User()); UserSession userSession = new UserSession(); userSession.setRequest(request); userSession.setResponse(response); manager.refreshSession(userSession); } @Test public void autoLoginAnonymousUserShouldDeny() { this.commonAutoLoginMockAction(); Cookie[] cookies = new Cookie[] { new Cookie("cookieNameData", "1"), new Cookie("cookieUserHash", "a"), new Cookie("cookieAutoLogin", "1") }; when(request.getCookies()).thenReturn(cookies); when(userRepository.get(1)).thenReturn(new User()); UserSession userSession = new UserSession(); userSession.setRequest(request); userSession.setResponse(response); manager.refreshSession(userSession); } @Test public void autoLoginDoestNotHaveCookiesShouldDeny() { this.commonAutoLoginMockAction(); UserSession userSession = new UserSession(); userSession.setRequest(request); userSession.setResponse(response); when(userRepository.get(1)).thenReturn(new User()); manager.refreshSession(userSession); } @Test public void refreshExistingSessionShouldFetchUserAndRoleManager() { User user = new User(); user.setId(1); UserSession us = this.newUserSession("123"); us.setRequest(request); us.setResponse(response); us.setUser(user); when(httpSession.getId()).thenReturn("123"); when(userRepository.get(user.getId())).thenReturn(user); manager.add(us); manager.refreshSession(us); assertNotNull(us.getRoleManager()); } @Test public void refreshSessionIsNewShouldCreateAutoLoginDisabledUsingAnonymousUser() { User anonymousUser = new User(); anonymousUser.setId(1); UserSession userSession = new UserSession(); userSession.setRequest(request); userSession.setResponse(response); when(httpSession.getId()).thenReturn("123"); when(config.getBoolean(ConfigKeys.AUTO_LOGIN_ENABLED)).thenReturn(false); when(userRepository.get(1)).thenReturn(anonymousUser); when(config.getValue(ConfigKeys.SSO_LOGOUT)).thenReturn("x"); UserSession us = manager.refreshSession(userSession); assertNotNull(us); assertEquals(anonymousUser, us.getUser()); assertNotNull(us.getRoleManager()); assertEquals("123", us.getSessionId()); verify(request).setAttribute("sso", false); verify(request).setAttribute("ssoLogout", "x"); } @Test public void isUserInSessionExpectNull() { assertNull(manager.isUserInSession(10)); } @Test public void isUserInSessionExpectMatch() { UserSession us1 = this.newUserSession("1"); us1.getUser().setId(2); manager.add(us1); UserSession expected = manager.isUserInSession(2); assertNotNull(expected); assertEquals("1", expected.getSessionId()); } @Test public void getUserSessionShouldAlwaysFind() { UserSession us1 = this.newUserSession("1"); us1.getUser().setId(2); manager.add(us1); UserSession us2 = this.newUserSession("2"); us2.getUser().setId(3); manager.add(us2); UserSession us3 = this.newUserSession("3"); manager.add(us3); assertNotNull(manager.getUserSession("1")); assertNotNull(manager.getUserSession("2")); assertNotNull(manager.getUserSession("3")); assertNull(manager.getUserSession("4")); } @Test public void getLoggedSessions() { UserSession us1 = this.newUserSession("1"); us1.getUser().setId(2); manager.add(us1); UserSession us2 = this.newUserSession("2"); us2.getUser().setId(3); manager.add(us2); UserSession us3 = this.newUserSession("3"); manager.add(us3); Collection<UserSession> sessions = manager.getLoggedSessions(); assertTrue(sessions.contains(us1)); assertTrue(sessions.contains(us2)); assertFalse(sessions.contains(us3)); } @Test public void getAllSessions() { UserSession us1 = this.newUserSession("1"); manager.add(us1); UserSession us2 = this.newUserSession("2"); manager.add(us2); List<UserSession> sessions = manager.getAllSessions(); assertEquals(2, sessions.size()); assertTrue(sessions.contains(us1)); assertTrue(sessions.contains(us2)); } @Test public void getTotalAnonymousUsers() { manager.add(this.newUserSession("1")); manager.add(this.newUserSession("2")); manager.add(this.newUserSession("3")); assertEquals(3, manager.getTotalAnonymousUsers()); assertEquals(0, manager.getTotalLoggedUsers()); } @Test public void getTotalLoggedUsers() { UserSession us1 = this.newUserSession("1"); us1.getUser().setId(3); manager.add(us1); UserSession us2 = this.newUserSession("2"); us2.getUser().setId(4); manager.add(us2); assertEquals(2, manager.getTotalLoggedUsers()); assertEquals(0, manager.getTotalAnonymousUsers()); } @Test public void getTotalUsers() { manager.add(this.newUserSession("1")); manager.add(this.newUserSession("2")); UserSession us3 = this.newUserSession("3"); us3.getUser().setId(3); manager.add(us3); assertEquals(2, manager.getTotalAnonymousUsers()); assertEquals(1, manager.getTotalLoggedUsers()); assertEquals(3, manager.getTotalUsers()); } @Test public void removeAnonymousUser() { UserSession us = this.newUserSession("1"); manager.add(us); manager.remove(us.getSessionId()); assertEquals(0, manager.getTotalAnonymousUsers()); assertEquals(0, manager.getTotalLoggedUsers()); } @Test public void removeLoggedUser() { UserSession us = this.newUserSession("1"); us.getUser().setId(2); manager.add(us); assertEquals(1, manager.getTotalLoggedUsers()); when(httpSession.getAttribute(ConfigKeys.LOGGED)).thenReturn("1"); manager.remove(us.getSessionId()); assertEquals(0, manager.getTotalLoggedUsers()); assertEquals(0, manager.getTotalAnonymousUsers()); } @Test public void addDuplicatedSessionIdShouldReplace() { // First session UserSession session1 = this.newUserSession("1"); session1.getUser().setUsername("user1"); manager.add(session1); assertEquals(1, manager.getTotalAnonymousUsers()); assertEquals("user1", manager.getUserSession("1").getUser().getUsername()); // Duplicated session UserSession session2 = this.newUserSession("1"); session2.getUser().setUsername("user2"); manager.add(session2); assertEquals(1, manager.getTotalAnonymousUsers()); assertEquals("user2", manager.getUserSession("1").getUser().getUsername()); } @Test public void addModeratorShouldIncrementTotalModeratorsOnline() { UserSession us = this.newUserSession("1"); Group g = new Group(); Role role = new Role(); role.setName(SecurityConstants.MODERATOR); g.addRole(role); us.getUser().addGroup(g); us.getUser().setId(2); assertFalse(manager.isModeratorOnline()); manager.add(us); assertTrue(manager.isModeratorOnline()); } @Test public void removeModeratorShouldDecrementModeratorsOnline() { UserSession us = this.newUserSession("1"); Group g = new Group(); Role role = new Role(); role.setName(SecurityConstants.MODERATOR); g.addRole(role); us.getUser().addGroup(g); us.getUser().setId(2); RoleManager roleManager = new RoleManager(); roleManager.setGroups(Arrays.asList(g)); us.setRoleManager(roleManager); manager.add(us); assertTrue(manager.isModeratorOnline()); manager.remove(us.getSessionId()); assertFalse(manager.isModeratorOnline()); } @Test public void addBotShouldIgnore() { UserSession us = mock(UserSession.class); when(us.isBot()).thenReturn(true); when(us.getSessionId()).thenReturn("123"); assertEquals(0, manager.getTotalUsers()); manager.add(us); assertEquals(0, manager.getTotalUsers()); } @Test public void addLoggedUser() { UserSession us = this.newUserSession("1"); us.getUser().setId(2); manager.add(us); assertEquals(1, manager.getTotalLoggedUsers()); } @Test public void addAnonymousUser() { UserSession us = this.newUserSession("1"); manager.add(us); assertEquals(1, manager.getTotalAnonymousUsers()); } @Test(expected = ForumException.class) public void addUsingEmptySessionIdExpectException() { manager.add(this.newUserSession("")); } @Test(expected = ForumException.class) public void addUsingNullSessionIdExpectException() { manager.add(this.newUserSession(null)); } private void commonAutoLoginMockAction() { when(httpSession.getId()).thenReturn("123"); when(config.getBoolean(ConfigKeys.AUTO_LOGIN_ENABLED)).thenReturn(true); } private UserSession newUserSession(String sessionId) { UserSession us = new UserSession(); us.setSessionId(sessionId); us.getUser().setId(1); return us; } }