package org.kalipo.security; import org.kalipo.domain.Authority; import org.kalipo.domain.Ban; import org.kalipo.domain.Privilege; import org.kalipo.domain.User; import org.kalipo.repository.BanRepository; import org.kalipo.repository.PrivilegeRepository; import org.kalipo.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import javax.inject.Inject; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * Authenticate a user from the database. */ @Component("userDetailsService") public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService { private final Logger log = LoggerFactory.getLogger(UserDetailsService.class); @Inject private UserRepository userRepository; @Inject private BanRepository banRepository; @Inject private PrivilegeRepository privilegeRepository; @Override @Transactional public UserDetails loadUserByUsername(final String login) { log.info("Authenticating {}", login); String lowercaseLogin = login.toLowerCase(); User userFromDatabase = userRepository.findOne(lowercaseLogin); if (userFromDatabase == null) { throw new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the database"); } else if (!userFromDatabase.getActivated()) { throw new UserNotActivatedException("User " + lowercaseLogin + " was not activated"); } List<Ban> bans = banRepository.findByUserId(userFromDatabase.getLogin()); for (Ban ban : bans) { if (ban.getValidUntil().isAfterNow()) { throw new UserDeniedAuthorizationException(String.format("User %s is banned until %s", ban.getUserId(), ban.getValidUntil())); } } Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>(); for (Authority authority : userFromDatabase.getAuthorities()) { grantedAuthorities.add(new SimpleGrantedAuthority(authority.getName())); } // append privileges according to reputation // todo negative reputation cannot be lower than 0, now List<Privilege> privileges = privilegeRepository.findByReputationLowerThanOrEqual(Math.max(0, userFromDatabase.getReputation())); for (Privilege privilege : privileges) { grantedAuthorities.add(new SimpleGrantedAuthority(privilege.getName())); } return new org.springframework.security.core.userdetails.User(lowercaseLogin, userFromDatabase.getPassword(), grantedAuthorities); } }