package be.mentoringsystems.merke.service.impl; import be.mentoringsystems.merke.helper.DTOHelper; import be.mentoringsystems.merke.model.QueryParams; import be.mentoringsystems.merke.model.db.Login; import be.mentoringsystems.merke.model.db.Vendor; import be.mentoringsystems.merke.model.dto.LoginDTO; import be.mentoringsystems.merke.model.dto.PagedListDTO; import be.mentoringsystems.merke.persistence.LoginDAO; import be.mentoringsystems.merke.service.ContextService; import be.mentoringsystems.merke.service.LoginService; import be.mentoringsystems.merke.service.VendorService; import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.switchuser.SwitchUserGrantedAuthority; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; /** * * @author anthonyarents */ @Service @Transactional(propagation = Propagation.SUPPORTS) public class LoginServiceImpl implements LoginService { @Autowired private transient LoginDAO loginDAO; @Autowired private transient ContextService contextService; @Autowired private transient VendorService vendorService; @Autowired private transient PasswordEncoder passwordEncoder; private static final Logger LOGGER = LogManager.getLogger(LoginServiceImpl.class); @Override @Transactional(propagation = Propagation.REQUIRED) public void save(final Login login) { loginDAO.save(login); } @Override @Transactional(propagation = Propagation.REQUIRED) public Login save(final LoginDTO dto) { final Login login = this.getCurrentLogin(); Login obj; boolean createVendor = false; if (dto.getId() == null) { obj = new Login(); createVendor = true; LOGGER.info("Creating a new Login"); } else { obj = getById(dto.getId()); LOGGER.info("Updating existing Login({})", dto.getId()); LOGGER.info("ContextId for this login:" + dto.getContextId()); if (login.getContextId() != null && !login.getContextId().equals(obj.getContextId()) && !login.isMSAdmin()) { obj = null; LOGGER.info("Access not allowed"); } } if (obj != null) { // save password if it exists String dtoPassword = dto.getPassword(); dto.setPassword(null); // copy non null DTOHelper.copyNonNull(dto, obj); // if password was not null : if (StringUtils.hasText(dtoPassword)) { obj.setPassword(encryptPassword(dtoPassword)); } if (dto.getContextId() != null) { obj.setContextId(dto.getContextId()); obj.setContext(contextService.getById(dto.getContextId())); } else { //Add context of current login if (login != null && login.getContextId() != null) { obj.setContextId(login.getContextId()); obj.setContext(contextService.getById(obj.getContextId())); } } LOGGER.info("Context before saving:" + obj.getContextId()); save(obj); LOGGER.info("Login({}) saved", obj.getId() + " context: " + obj.getContextId()); if (createVendor && obj.getGroup() == 2) { LOGGER.info("Creating a new Vendor"); final Vendor vendor = new Vendor(); vendor.setFirstname(obj.getFirstname()); vendor.setLastname(obj.getLastname()); vendor.setEmail(obj.getEmail()); vendor.setLoginId(obj.getId()); vendor.setFlag(0); vendor.setActive(true); vendorService.save(vendor); LOGGER.info("Vendor({}) saved", vendor.getId()); } else if (obj.getGroup() == 2) { LOGGER.info("Updating Vendor"); Vendor vendor = vendorService.getByLoginId(obj.getId()); vendor.setFirstname(obj.getFirstname()); vendor.setLastname(obj.getLastname()); vendor.setEmail(obj.getEmail()); vendorService.save(vendor); LOGGER.info("Vendor({}) saved", vendor.getId()); } } return obj; } @Override @Transactional(propagation = Propagation.REQUIRED) public void delete(final Login login) { login.setDeleted(true); save(login); LOGGER.info("Login({}) deleted", login.getId()); } @Override @Transactional(propagation = Propagation.REQUIRED) public void delete(final UUID id) { final Login login = getById(id); delete(login); } @Override @Transactional(readOnly = true) public Login getById(final UUID id) { return loginDAO.getById(id); } @Override @Transactional(readOnly = true) public Login getByUsername(final String username) { return loginDAO.getByUsername(username); } @Override @Transactional(readOnly = true) public List getAll(final QueryParams queryParams) { return loginDAO.getAll(queryParams); } @Override @Transactional(readOnly = true) public Long getCount(final QueryParams queryParams) { return loginDAO.getCount(queryParams); } @Override @Transactional(readOnly = true) public PagedListDTO getAllDTO(final QueryParams queryParams) { final Login login = this.getCurrentLogin(); if (login.getContextId() != null && !login.isMSAdmin()) { queryParams.addFilter("contextId", login.getContextId()); } final PagedListDTO pagedListDTO = new PagedListDTO(); pagedListDTO.setData(getAll(queryParams)); pagedListDTO.setTotal(getCount(queryParams)); return pagedListDTO; } @Override @Transactional(propagation = Propagation.REQUIRED) public void changePassword(final String password) { final Login login = getCurrentLogin(); changePassword(login, password); } @Override @Transactional(propagation = Propagation.REQUIRED) public void changePassword(final Login login, final String password) { login.setPassword(encryptPassword(password)); save(login); LOGGER.info("Login({}) password changed", login.getId()); } public String encryptPassword(final String password) { return passwordEncoder.encode(password); } @Override @Transactional(readOnly = true) public UserDetails loadUserByUsername(final String loginName) throws UsernameNotFoundException { final Login login = getByUsername(loginName); if (login == null) { throw new UsernameNotFoundException(loginName); } else { login.setAuthorities(getAuthorities(login)); return login; } } public List getAuthorities(final Login login) { final List authorities = new ArrayList<>(); if (login.isMSAdmin()) { authorities.add(new SimpleGrantedAuthority("ROLE_MSADMIN")); authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); } if (login.isAdmin()) { authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); } if (login.isFireman()) { authorities.add(new SimpleGrantedAuthority("ROLE_FIREMAN")); } authorities.add(new SimpleGrantedAuthority("ROLE_USER")); return authorities; } @Override public Login getCurrentLogin() { if (SecurityContextHolder.getContext() != null && SecurityContextHolder.getContext().getAuthentication() != null) { Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (principal instanceof Login) { return (Login) principal; } } return null; } @Override public Login getSourceLogin() { final Login current = getCurrentLogin(); Login original = null; for (GrantedAuthority auth : current.getAuthorities()) { if (auth instanceof SwitchUserGrantedAuthority) { Authentication authSource = ((SwitchUserGrantedAuthority) auth).getSource(); if (authSource instanceof Login) { original = (Login) authSource; } } } return original; } @Override @Transactional(readOnly = true) public Login getByUsernameAndPassword(final String username, final String password) { final Login login = getByUsername(username); if (login == null) { return null; } else { if (passwordEncoder.matches(password, login.getPassword())) { return login; } else { return null; } } } }