/* * Copyright (C) 2007-2014 Crafter Software Corporation. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.craftercms.profile.services.impl; import java.util.Date; import java.util.UUID; import org.bson.types.ObjectId; import org.craftercms.commons.crypto.CipherUtils; import org.craftercms.commons.security.permissions.PermissionEvaluator; import org.craftercms.profile.api.AccessToken; import org.craftercms.profile.api.PersistentLogin; import org.craftercms.profile.api.Profile; import org.craftercms.profile.api.ProfileConstants; import org.craftercms.profile.api.Ticket; import org.craftercms.profile.api.services.ProfileService; import org.craftercms.profile.exceptions.BadCredentialsException; import org.craftercms.profile.exceptions.DisabledProfileException; import org.craftercms.profile.exceptions.NoSuchProfileException; import org.craftercms.profile.repositories.PersistentLoginRepository; import org.craftercms.profile.repositories.ProfileRepository; import org.craftercms.profile.repositories.TicketRepository; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * Unit tests for {@link org.craftercms.profile.services.impl.AuthenticationServiceImpl}. * * @author avasquez */ public class AuthenticationServiceImplTest { private static final String TENANT_NAME = "tenant1"; private static final ObjectId PROFILE1_ID = new ObjectId(); private static final ObjectId PROFILE2_ID = new ObjectId(); private static final String USERNAME1 = "user1"; private static final String USERNAME2 = "user2"; private static final String PASSWORD = "12345"; private static final String TICKET_ID = UUID.randomUUID().toString(); private static final String PERSISTENT_LOGIN_ID = UUID.randomUUID().toString(); private static final String PERSISTENT_LOGIN_TOKEN = UUID.randomUUID().toString(); private AuthenticationServiceImpl authenticationService; @Mock private PermissionEvaluator<AccessToken, String> permissionEvaluator; @Mock private TicketRepository ticketRepository; @Mock private PersistentLoginRepository persistentLoginRepository; @Mock private ProfileService profileService; @Mock private ProfileRepository profileRepository; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(permissionEvaluator.isAllowed(anyString(), anyString())).thenReturn(true); when(ticketRepository.findByStringId(TICKET_ID)).thenReturn(getTicket()); when(persistentLoginRepository.findByStringId(PERSISTENT_LOGIN_ID)).thenReturn(getPersistentLogin()); when(profileService.getProfileByUsername(TENANT_NAME, USERNAME1, ProfileConstants.NO_ATTRIBUTE)) .thenReturn(getProfile1()); when(profileService.getProfileByUsername(TENANT_NAME, USERNAME2, ProfileConstants.NO_ATTRIBUTE)) .thenReturn(getProfile2()); when(profileService.getProfile(PROFILE1_ID.toString(), ProfileConstants.NO_ATTRIBUTE)) .thenReturn(getProfile1()); when(profileService.getProfile(PROFILE2_ID.toString(), ProfileConstants.NO_ATTRIBUTE)) .thenReturn(getProfile2()); authenticationService = new AuthenticationServiceImpl(); authenticationService.setPermissionEvaluator(permissionEvaluator); authenticationService.setTicketRepository(ticketRepository); authenticationService.setPersistentLoginRepository(persistentLoginRepository); authenticationService.setProfileService(profileService); authenticationService.setFailedLoginAttemptsBeforeDelay(2); authenticationService.setLockTime(5); authenticationService.setFailedLoginAttemptsBeforeLock(8); } @Test public void testAuthenticate() throws Exception { Ticket ticket = authenticationService.authenticate(TENANT_NAME, USERNAME1, PASSWORD); assertNotNull(ticket); assertEquals(PROFILE1_ID, ticket.getProfileId()); assertNotNull(ticket.getLastRequestTime()); verify(profileService).getProfileByUsername(TENANT_NAME, USERNAME1, ProfileConstants.NO_ATTRIBUTE); verify(ticketRepository).insert(ticket); } @Test(expected = BadCredentialsException.class) public void testAuthenticateInvalidUsername() throws Exception { authenticationService.authenticate(TENANT_NAME, "user3", PASSWORD); fail("Expected " + BadCredentialsException.class.getName() + " exception"); } @Test(expected = BadCredentialsException.class) public void testAuthenticateInvalidPassword() throws Exception { authenticationService.authenticate(TENANT_NAME, USERNAME1, "54321"); fail("Expected " + BadCredentialsException.class.getName() + " exception"); } @Test(expected = DisabledProfileException.class) public void testAuthenticateDisabledProfile() throws Exception { authenticationService.authenticate(TENANT_NAME, USERNAME2, PASSWORD); fail("Expected " + DisabledProfileException.class.getName() + " exception"); } @Test public void testCreateTicket() throws Exception { Ticket ticket = authenticationService.createTicket(PROFILE1_ID.toString()); assertNotNull(ticket); assertEquals(PROFILE1_ID.toString(), ticket.getProfileId()); assertNotNull(ticket.getLastRequestTime()); verify(profileService).getProfile(PROFILE1_ID.toString(), ProfileConstants.NO_ATTRIBUTE); verify(ticketRepository).insert(ticket); } @Test(expected = NoSuchProfileException.class) public void testCreateTicketWithInvalidProfile() throws Exception { authenticationService.createTicket("1234"); fail("Expected " + NoSuchProfileException.class.getName() + " exception"); } @Test public void testGetTicket() throws Exception { Ticket ticket = authenticationService.getTicket(TICKET_ID); assertNotNull(ticket); assertEquals(TICKET_ID, ticket.getId()); assertEquals(PROFILE1_ID.toString(), ticket.getProfileId()); assertNotNull(ticket.getLastRequestTime()); verify(ticketRepository).findByStringId(TICKET_ID); verify(ticketRepository).save(ticket); } @Test public void testInvalidateTicket() throws Exception { authenticationService.invalidateTicket(TICKET_ID); verify(ticketRepository).removeByStringId(TICKET_ID); } @Test public void testCreatePersistentLogin() throws Exception { PersistentLogin login = authenticationService.createPersistentLogin(PROFILE1_ID.toString()); assertNotNull(login); assertNotNull(login.getId()); assertEquals(TENANT_NAME, login.getTenant()); assertEquals(PROFILE1_ID.toString(), login.getProfileId()); assertNotNull(login.getToken()); assertNotNull(login.getTimestamp()); verify(profileService).getProfile(PROFILE1_ID.toString(), ProfileConstants.NO_ATTRIBUTE); verify(persistentLoginRepository).insert(login); } @Test(expected = NoSuchProfileException.class) public void testCreatePersistentLoginWithInvalidProfile() throws Exception { authenticationService.createPersistentLogin("1234"); } @Test(expected = DisabledProfileException.class) public void testCreatePersistentLoginWithDisabledProfile() throws Exception { authenticationService.createPersistentLogin(PROFILE2_ID.toString()); } @Test public void testGetPersistentLogin() throws Exception { PersistentLogin login = authenticationService.getPersistentLogin(PERSISTENT_LOGIN_ID); assertNotNull(login); assertEquals(PERSISTENT_LOGIN_ID, login.getId()); assertEquals(TENANT_NAME, login.getTenant()); assertEquals(PROFILE1_ID.toString(), login.getProfileId()); assertEquals(PERSISTENT_LOGIN_TOKEN, login.getToken()); assertNotNull(login.getTimestamp()); verify(persistentLoginRepository).findByStringId(PERSISTENT_LOGIN_ID); } private Profile getProfile1() { Profile profile = new Profile(); profile.setId(PROFILE1_ID); profile.setUsername(USERNAME1); profile.setPassword(CipherUtils.hashPassword(PASSWORD)); profile.setEnabled(true); profile.setTenant(TENANT_NAME); return profile; } private Profile getProfile2() { Profile profile = new Profile(); profile.setId(PROFILE2_ID); profile.setUsername(USERNAME2); profile.setPassword(CipherUtils.hashPassword(PASSWORD)); profile.setEnabled(false); profile.setTenant(TENANT_NAME); return profile; } private Ticket getTicket() { Ticket ticket = new Ticket(); ticket.setId(TICKET_ID); ticket.setProfileId(PROFILE1_ID.toString()); ticket.setLastRequestTime(new Date()); return ticket; } private PersistentLogin getPersistentLogin() { PersistentLogin login = new PersistentLogin(); login.setId(PERSISTENT_LOGIN_ID); login.setTenant(TENANT_NAME); login.setProfileId(PROFILE1_ID.toString()); login.setToken(PERSISTENT_LOGIN_TOKEN); login.setTimestamp(new Date()); return login; } }