package org.synyx.urlaubsverwaltung.security;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.synyx.urlaubsverwaltung.core.department.DepartmentService;
import org.synyx.urlaubsverwaltung.core.person.Person;
import org.synyx.urlaubsverwaltung.core.person.PersonService;
import org.synyx.urlaubsverwaltung.core.person.Role;
import org.synyx.urlaubsverwaltung.test.TestDataCreator;
import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;
/**
* @author Aljona Murygina - murygina@synyx.de
*/
public class SessionServiceTest {
private static final String USER_NAME = "username";
private SessionService sessionService;
private PersonService personService;
private DepartmentService departmentService;
private SecurityContext securityContext;
@Before
public void setUp() {
personService = Mockito.mock(PersonService.class);
departmentService = Mockito.mock(DepartmentService.class);
sessionService = new SessionService(personService, departmentService);
// Mock authentication
Authentication authentication = Mockito.mock(Authentication.class);
Mockito.when(authentication.getName()).thenReturn(USER_NAME);
securityContext = Mockito.mock(SecurityContext.class);
Mockito.when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);
// Mock department head
Mockito.when(departmentService.isDepartmentHeadOfPerson(Mockito.any(Person.class), Mockito.any(Person.class)))
.thenReturn(false);
}
// Get signed in user ----------------------------------------------------------------------------------------------
@Test(expected = IllegalStateException.class)
public void ensureThrowsIfNoPersonCanBeFoundForTheCurrentlySignedInUser() {
Mockito.when(personService.getPersonByLogin(Mockito.anyString())).thenReturn(Optional.empty());
sessionService.getSignedInUser();
}
@Test
public void ensureReturnsPersonForCurrentlySignedInUser() {
Person person = TestDataCreator.createPerson();
Mockito.when(personService.getPersonByLogin(Mockito.anyString())).thenReturn(Optional.of(person));
Person signedInUser = sessionService.getSignedInUser();
Mockito.verify(personService).getPersonByLogin(USER_NAME);
Assert.assertEquals("Wrong person", person, signedInUser);
}
@Test(expected = IllegalStateException.class)
public void ensureThrowsIllegalOnNullAuthentication() {
Mockito.when(securityContext.getAuthentication()).thenReturn(null);
sessionService.getSignedInUser();
}
// Access person data ----------------------------------------------------------------------------------------------
@Test
public void ensureSignedInOfficeUserCanAccessPersonData() throws IllegalAccessException {
Person person = TestDataCreator.createPerson(23, "person");
person.setPermissions(Collections.singletonList(Role.USER));
Person office = TestDataCreator.createPerson(42, "office");
office.setPermissions(Arrays.asList(Role.USER, Role.OFFICE));
boolean isAllowed = sessionService.isSignedInUserAllowedToAccessPersonData(office, person);
Assert.assertTrue("Office should be able to access any person data", isAllowed);
}
@Test
public void ensureSignedInBossUserCanAccessPersonData() throws IllegalAccessException {
Person person = TestDataCreator.createPerson(23, "person");
person.setPermissions(Collections.singletonList(Role.USER));
Person boss = TestDataCreator.createPerson(42, "boss");
boss.setPermissions(Arrays.asList(Role.USER, Role.BOSS));
boolean isAllowed = sessionService.isSignedInUserAllowedToAccessPersonData(boss, person);
Assert.assertTrue("Boss should be able to access any person data", isAllowed);
}
@Test
public void ensureSignedInDepartmentHeadOfPersonCanAccessPersonData() throws IllegalAccessException {
Person person = TestDataCreator.createPerson(23, "person");
person.setPermissions(Collections.singletonList(Role.USER));
Person departmentHead = TestDataCreator.createPerson(42, "departmentHead");
departmentHead.setPermissions(Arrays.asList(Role.USER, Role.DEPARTMENT_HEAD));
Mockito.when(departmentService.isDepartmentHeadOfPerson(departmentHead, person)).thenReturn(true);
boolean isAllowed = sessionService.isSignedInUserAllowedToAccessPersonData(departmentHead, person);
Mockito.verify(departmentService).isDepartmentHeadOfPerson(departmentHead, person);
Assert.assertTrue("Department head of person should be able to access the person's data", isAllowed);
}
@Test
public void ensureSignedInDepartmentHeadThatIsNotDepartmentHeadOfPersonCanNotAccessPersonData()
throws IllegalAccessException {
Person person = TestDataCreator.createPerson(23, "person");
person.setPermissions(Collections.singletonList(Role.USER));
Person departmentHead = TestDataCreator.createPerson(42, "departmentHead");
departmentHead.setPermissions(Arrays.asList(Role.USER, Role.DEPARTMENT_HEAD));
Mockito.when(departmentService.isDepartmentHeadOfPerson(departmentHead, person)).thenReturn(false);
boolean isAllowed = sessionService.isSignedInUserAllowedToAccessPersonData(departmentHead, person);
Mockito.verify(departmentService).isDepartmentHeadOfPerson(departmentHead, person);
Assert.assertFalse("Department head - but not of person - should not be able to access the person's data",
isAllowed);
}
@Test
public void ensureSignedInDepartmentHeadCanNotAccessSecondStageAuthorityPersonData()
throws IllegalAccessException {
Person secondStageAuthority = TestDataCreator.createPerson(23, "secondStageAuthority");
secondStageAuthority.setPermissions(Arrays.asList(Role.USER, Role.SECOND_STAGE_AUTHORITY));
Person departmentHead = TestDataCreator.createPerson(42, "departmentHead");
departmentHead.setPermissions(Arrays.asList(Role.USER, Role.DEPARTMENT_HEAD));
Mockito.when(departmentService.isDepartmentHeadOfPerson(departmentHead, secondStageAuthority)).thenReturn(true);
boolean isAllowed = sessionService.isSignedInUserAllowedToAccessPersonData(departmentHead, secondStageAuthority);
Mockito.verify(departmentService).isDepartmentHeadOfPerson(departmentHead, secondStageAuthority);
Assert.assertFalse("Department head - but not of secondStageAuthority - should not be able to access the secondStageAuthority's data",
isAllowed);
}
@Test
public void ensureSignedInSecondStageAuthorityCanAccessDepartmentHeadPersonData()
throws IllegalAccessException {
Person secondStageAuthority = TestDataCreator.createPerson(23, "secondStageAuthority");
secondStageAuthority.setPermissions(Arrays.asList(Role.USER, Role.SECOND_STAGE_AUTHORITY));
Person departmentHead = TestDataCreator.createPerson(42, "departmentHead");
departmentHead.setPermissions(Arrays.asList(Role.USER, Role.DEPARTMENT_HEAD));
Mockito.when(departmentService.isSecondStageAuthorityOfPerson(secondStageAuthority, departmentHead)).thenReturn(true);
boolean isAllowed = sessionService.isSignedInUserAllowedToAccessPersonData(secondStageAuthority, departmentHead);
Mockito.verify(departmentService).isSecondStageAuthorityOfPerson(secondStageAuthority, departmentHead);
Assert.assertTrue("secondStageAuthority should be able to access the departmentHeads's data",
isAllowed);
}
@Test
public void ensureNotPrivilegedUserCanNotAccessPersonData() throws IllegalAccessException {
Person person = TestDataCreator.createPerson(23, "person");
person.setPermissions(Collections.singletonList(Role.USER));
Person user = TestDataCreator.createPerson(42, "user");
user.setPermissions(Collections.singletonList(Role.USER));
Mockito.when(departmentService.isDepartmentHeadOfPerson(user, person)).thenReturn(false);
boolean isAllowed = sessionService.isSignedInUserAllowedToAccessPersonData(user, person);
Assert.assertFalse("User should not be able to access the data of other person", isAllowed);
}
@Test
public void ensureNotPrivilegedUserCanAccessOwnPersonData() throws IllegalAccessException {
Person user = TestDataCreator.createPerson(42, "user");
user.setPermissions(Collections.singletonList(Role.USER));
boolean isAllowed = sessionService.isSignedInUserAllowedToAccessPersonData(user, user);
Assert.assertTrue("User should be able to access own data", isAllowed);
}
}