236 lines
7.1 KiB
Java
236 lines
7.1 KiB
Java
/**
|
|
*
|
|
*/
|
|
package de.bstly.board.businesslogic;
|
|
|
|
import java.util.List;
|
|
|
|
import org.apache.commons.lang3.RandomStringUtils;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.beans.factory.SmartInitializingSingleton;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
import org.springframework.security.core.Authentication;
|
|
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.UserDetailsService;
|
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.util.StringUtils;
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import de.bstly.board.model.Entry;
|
|
import de.bstly.board.model.LocalUser;
|
|
import de.bstly.board.model.QEntry;
|
|
import de.bstly.board.model.QLocalUser;
|
|
import de.bstly.board.repository.EntryRepository;
|
|
import de.bstly.board.repository.LocalUserRepository;
|
|
import de.bstly.board.security.LocalUserDetails;
|
|
|
|
/**
|
|
* The Class UserManager.
|
|
*/
|
|
@Service
|
|
public class UserManager implements UserDetailsService, SmartInitializingSingleton {
|
|
|
|
private Logger logger = LoggerFactory.getLogger(UserManager.class);
|
|
|
|
@Autowired
|
|
private LocalUserRepository localUserRepository;
|
|
@Autowired
|
|
private PasswordEncoder passwordEncoder;
|
|
@Autowired
|
|
private EntryManager entryManager;
|
|
@Autowired
|
|
private EntryRepository entryRepository;
|
|
private QLocalUser qLocalUser = QLocalUser.localUser;
|
|
private QEntry qEntry = QEntry.entry;
|
|
|
|
@Value("${admin.password:}")
|
|
private String adminPassword;
|
|
|
|
/*
|
|
* @see org.springframework.security.core.userdetails.UserDetailsService#
|
|
* loadUserByUsername(java.lang.String)
|
|
*/
|
|
@Override
|
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
|
LocalUser localUser = getByUsername(username);
|
|
|
|
if (localUser == null) {
|
|
throw new UsernameNotFoundException(username);
|
|
}
|
|
|
|
List<GrantedAuthority> authorities = Lists.newArrayList();
|
|
if (localUser.getRoles() != null) {
|
|
for (String role : localUser.getRoles()) {
|
|
authorities.add(new SimpleGrantedAuthority(role));
|
|
}
|
|
}
|
|
|
|
String passwordHash = localUser.getPasswordHash();
|
|
|
|
if (passwordHash == null) {
|
|
passwordHash = "";
|
|
}
|
|
|
|
LocalUserDetails userDetails = new LocalUserDetails(username, passwordHash, authorities);
|
|
return userDetails;
|
|
}
|
|
|
|
/*
|
|
* @see org.springframework.beans.factory.SmartInitializingSingleton#
|
|
* afterSingletonsInstantiated()
|
|
*/
|
|
@Override
|
|
public void afterSingletonsInstantiated() {
|
|
if (!localUserRepository.exists(qLocalUser.roles.contains("ROLE_ADMIN"))) {
|
|
if (!StringUtils.hasText(adminPassword)) {
|
|
adminPassword = RandomStringUtils.random(24, true, true);
|
|
logger.error("password for 'admin': " + adminPassword);
|
|
}
|
|
LocalUser admin = new LocalUser();
|
|
admin.setUsername("admin");
|
|
admin.setRoles(Lists.newArrayList("ROLE_ADMIN"));
|
|
admin.setPasswordHash(passwordEncoder.encode(adminPassword));
|
|
admin.setLocale("en");
|
|
localUserRepository.save(admin);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the by username.
|
|
*
|
|
* @param username the username
|
|
* @return the by username
|
|
*/
|
|
public LocalUser getByUsername(String username) {
|
|
return localUserRepository.findOne(qLocalUser.username.equalsIgnoreCase(username)).orElse(null);
|
|
}
|
|
|
|
/**
|
|
* Gets the by external id.
|
|
*
|
|
* @param externalId the external id
|
|
* @return the by external id
|
|
*/
|
|
public LocalUser getByExternalId(String externalId) {
|
|
return localUserRepository.findOne(qLocalUser.externalId.eq(externalId)).orElse(null);
|
|
}
|
|
|
|
/**
|
|
* Gets the by auth.
|
|
*
|
|
* @param authentication the authentication
|
|
* @return the by auth
|
|
*/
|
|
public LocalUser getByAuth(Authentication authentication) {
|
|
if (authentication != null) {
|
|
if (authentication instanceof UsernamePasswordAuthenticationToken) {
|
|
UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
|
|
return getByUsername(token.getName());
|
|
} else if (authentication instanceof OAuth2AuthenticationToken) {
|
|
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
|
|
String externalId = token.getAuthorizedClientRegistrationId() + "-" + token.getName();
|
|
LocalUser localUser = getByExternalId(externalId);
|
|
if (localUser == null) {
|
|
localUser = new LocalUser();
|
|
localUser.setExternalId(externalId);
|
|
String tmpUsername = token.getPrincipal().getAttribute("preferred_username");
|
|
if (!StringUtils.hasText(tmpUsername)) {
|
|
tmpUsername = token.getPrincipal().getAttribute("username");
|
|
}
|
|
if (!StringUtils.hasText(tmpUsername)) {
|
|
tmpUsername = token.getPrincipal().getAttribute("name");
|
|
}
|
|
if (!StringUtils.hasText(tmpUsername)) {
|
|
tmpUsername = token.getName();
|
|
}
|
|
int count = 1;
|
|
String username = tmpUsername;
|
|
while (localUserRepository.exists(qLocalUser.username.equalsIgnoreCase(username))) {
|
|
username = tmpUsername + "-" + count;
|
|
count++;
|
|
}
|
|
|
|
localUser.setUsername(username);
|
|
localUser.setEmail(token.getPrincipal().getAttribute("email"));
|
|
|
|
String locale = token.getPrincipal().getAttribute("locale");
|
|
if (!StringUtils.hasText(locale)) {
|
|
locale = "de";
|
|
}
|
|
localUser.setLocale(locale);
|
|
|
|
String darkTheme = token.getPrincipal().getAttribute("darkTheme");
|
|
if (!StringUtils.hasText(darkTheme)) {
|
|
darkTheme = "false";
|
|
}
|
|
localUser.setDarkTheme(Boolean.valueOf(darkTheme));
|
|
|
|
localUser = localUserRepository.save(localUser);
|
|
}
|
|
return localUser;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Apply metadata.
|
|
*
|
|
* @param username the username
|
|
* @param user the user
|
|
*/
|
|
public void applyMetadata(String username, LocalUser user) {
|
|
if (user.getUsername().equalsIgnoreCase(username) && !user.getMetadata().containsKey("self")) {
|
|
user.getMetadata().put("self", true);
|
|
}
|
|
|
|
if (!user.getMetadata().containsKey("points")) {
|
|
user.getMetadata().put("points", getKarma(user.getUsername()));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the karma.
|
|
*
|
|
* @param username the username
|
|
* @return the karma
|
|
*/
|
|
public long getKarma(String username) {
|
|
long karma = 0;
|
|
for (Entry entry : entryRepository.findAll(qEntry.author.equalsIgnoreCase(username))) {
|
|
karma += entryManager.getUserPoints(entry.getId(), username);
|
|
}
|
|
return karma;
|
|
}
|
|
|
|
/**
|
|
* Save.
|
|
*
|
|
* @param localUser the local user
|
|
* @return the local user
|
|
*/
|
|
public LocalUser save(LocalUser localUser) {
|
|
return localUserRepository.save(localUser);
|
|
}
|
|
|
|
/**
|
|
* Exists.
|
|
*
|
|
* @param username the username
|
|
* @return true, if successful
|
|
*/
|
|
public boolean exists(String username) {
|
|
return localUserRepository.exists(qLocalUser.username.equalsIgnoreCase(username));
|
|
}
|
|
|
|
}
|