package org.craftercms.security.authentication.impl; import java.util.UUID; import javax.servlet.http.Cookie; import org.bson.types.ObjectId; import org.craftercms.commons.crypto.impl.NoOpTextEncryptor; import org.craftercms.commons.http.CookieManager; import org.craftercms.commons.http.RequestContext; import org.craftercms.profile.api.PersistentLogin; import org.craftercms.profile.api.Profile; import org.craftercms.profile.api.services.AuthenticationService; import org.craftercms.profile.api.services.ProfileService; import org.craftercms.security.authentication.Authentication; import org.craftercms.security.authentication.AuthenticationManager; import org.craftercms.security.exception.rememberme.CookieTheftException; import org.craftercms.security.exception.rememberme.InvalidCookieException; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.craftercms.security.authentication.impl.RememberMeManagerImpl.*; /** * Unit tests for {@link org.craftercms.security.authentication.impl.RememberMeManagerImpl}. * * @author avasquez */ public class RememberMeManagerImplTest { private static final String LOGIN_ID = UUID.randomUUID().toString(); private static final String LOGIN_TOKEN = UUID.randomUUID().toString(); private static final String LOGIN_TOKEN2 = UUID.randomUUID().toString(); private static final ObjectId PROFILE_ID = ObjectId.get(); private RememberMeManagerImpl rememberMeManager; @Mock private AuthenticationService authenticationService; @Mock private AuthenticationManager authenticationManager; @Mock private ProfileService profileService; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(authenticationService.createPersistentLogin(PROFILE_ID.toString())).thenReturn(getLogin()); when(authenticationService.getPersistentLogin(LOGIN_ID)).thenReturn(getLogin()); when(authenticationService.refreshPersistentLoginToken(LOGIN_ID)).thenReturn(getLogin2()); when(authenticationManager.authenticateUser(getProfile(), true)).thenReturn(getAuthentication()); when(profileService.getProfile(PROFILE_ID.toString(), new String[0])).thenReturn(getProfile()); rememberMeManager = new RememberMeManagerImpl(); rememberMeManager.setAuthenticationService(authenticationService); rememberMeManager.setAuthenticationManager(authenticationManager); rememberMeManager.setProfileService(profileService); rememberMeManager.setEncryptor(new NoOpTextEncryptor()); rememberMeManager.setRememberMeCookieManager(new CookieManager()); } @Test public void testEnableRememberMe() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); RequestContext context = new RequestContext(request, response, null); rememberMeManager.enableRememberMe(getAuthentication(), context); String cookieValue = response.getCookie(REMEMBER_ME_COOKIE_NAME).getValue(); assertEquals(getSerializedLogin(), cookieValue); } @Test public void testDisableRememberMe() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); RequestContext context = new RequestContext(request, response, null); request.setCookies(new Cookie(REMEMBER_ME_COOKIE_NAME, getSerializedLogin())); rememberMeManager.disableRememberMe(context); assertNull(response.getCookie(REMEMBER_ME_COOKIE_NAME).getValue()); verify(authenticationService).deletePersistentLogin(LOGIN_ID); } @Test public void testAutoLogin() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); RequestContext context = new RequestContext(request, response, null); request.setCookies(new Cookie(REMEMBER_ME_COOKIE_NAME, getSerializedLogin())); Authentication auth = rememberMeManager.autoLogin(context); assertNotNull(auth); assertEquals(getProfile(), auth.getProfile()); String cookieValue = response.getCookie(REMEMBER_ME_COOKIE_NAME).getValue(); assertEquals(getSerializedLoginWithRefreshedToken(), cookieValue); } @Test public void testAutoLoginWithInvalidId() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); RequestContext context = new RequestContext(request, response, null); request.setCookies(new Cookie(REMEMBER_ME_COOKIE_NAME, getSerializedLoginWithInvalidId())); Authentication auth = rememberMeManager.autoLogin(context); assertNull(auth); assertNull(response.getCookie(REMEMBER_ME_COOKIE_NAME).getValue()); } @Test(expected = InvalidCookieException.class) public void testAutoLoginWithInvalidProfile() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); RequestContext context = new RequestContext(request, response, null); request.setCookies(new Cookie(REMEMBER_ME_COOKIE_NAME, getSerializedLoginWithInvalidProfile())); rememberMeManager.autoLogin(context); } @Test(expected = CookieTheftException.class) public void testAutoLoginWithInvalidToken() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); RequestContext context = new RequestContext(request, response, null); request.setCookies(new Cookie(REMEMBER_ME_COOKIE_NAME, getSerializedLoginWithInvalidToken())); rememberMeManager.autoLogin(context); } protected String getSerializedLogin() { return serializeLogin(LOGIN_ID, PROFILE_ID.toString(), LOGIN_TOKEN); } protected String getSerializedLoginWithRefreshedToken() { return serializeLogin(LOGIN_ID, PROFILE_ID.toString(), LOGIN_TOKEN2); } protected String getSerializedLoginWithInvalidId() { return serializeLogin(UUID.randomUUID().toString(), PROFILE_ID.toString(), LOGIN_TOKEN); } protected String getSerializedLoginWithInvalidProfile() { return serializeLogin(LOGIN_ID, ObjectId.get().toString(), LOGIN_TOKEN); } protected String getSerializedLoginWithInvalidToken() { return serializeLogin(LOGIN_ID, PROFILE_ID.toString(), UUID.randomUUID().toString()); } protected String serializeLogin(String id, String profileId, String token) { StringBuilder serializedLogin = new StringBuilder(); serializedLogin.append(id).append(SERIALIZED_LOGIN_SEPARATOR); serializedLogin.append(profileId).append(SERIALIZED_LOGIN_SEPARATOR); serializedLogin.append(token); return serializedLogin.toString(); } protected PersistentLogin getLogin() { PersistentLogin login = new PersistentLogin(); login.setId(LOGIN_ID); login.setToken(LOGIN_TOKEN); login.setProfileId(PROFILE_ID.toString()); return login; } protected PersistentLogin getLogin2() { PersistentLogin login = new PersistentLogin(); login.setId(LOGIN_ID); login.setToken(LOGIN_TOKEN2); login.setProfileId(PROFILE_ID.toString()); return login; } protected Profile getProfile() { Profile profile = new Profile(); profile.setId(PROFILE_ID); return profile; } protected Authentication getAuthentication() { return new DefaultAuthentication(null, getProfile(), true); } }