package org.synyx.urlaubsverwaltung.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
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 java.util.Optional;
/**
* @author Aljona Murygina - murygina@synyx.de
*/
@Service
public class SessionService {
private final PersonService personService;
private final DepartmentService departmentService;
@Autowired
public SessionService(PersonService personService, DepartmentService departmentService) {
this.personService = personService;
this.departmentService = departmentService;
}
/**
* This method allows to get the signed in user.
*
* @return user that is signed in
*/
public Person getSignedInUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
throw new IllegalStateException("No authentication found in context.");
}
String user = authentication.getName();
Optional<Person> person = personService.getPersonByLogin(user);
if (!person.isPresent()) {
throw new IllegalStateException("Can not get the person for the signed in user with username = " + user);
}
return person.get();
}
/**
* Check if the given signed in user is allowed to access the data of the given person.
*
* @param signedInUser to check the permissions
* @param person which data should be accessed
*
* @return {@code true} if the given user may access the data of the given person, else {@code false}
*/
public boolean isSignedInUserAllowedToAccessPersonData(Person signedInUser, Person person) {
boolean isOwnData = person.getId().equals(signedInUser.getId());
boolean isBossOrOffice = signedInUser.hasRole(Role.OFFICE) || signedInUser.hasRole(Role.BOSS);
boolean isDepartmentHeadOfPerson = departmentService.isDepartmentHeadOfPerson(signedInUser, person);
boolean isSecondStageAuthorityOfPerson = departmentService.isSecondStageAuthorityOfPerson(signedInUser, person);
boolean isPrivilegedUser = isBossOrOffice || isDepartmentHeadOfPerson || isSecondStageAuthorityOfPerson;
// Note:
// signedInUser has role DEPARTMENT_HEAD
// person has role SECOND_STAGE_AUTHORITY
// signedInUser and person are in the same department
// signedInUser is not allowed to access persons data cause of lower level role
// (DEPARTMENT_HEAD < SECOND_STAGE_AUTHORITY)
boolean isDepartmentHeadOfSecondStageAuthority =
person.hasRole(Role.SECOND_STAGE_AUTHORITY) && signedInUser.hasRole(Role.DEPARTMENT_HEAD);
return isOwnData || (isPrivilegedUser && !isDepartmentHeadOfSecondStageAuthority);
}
}