package com.worktajm.service;
import com.worktajm.domain.Authority;
import com.worktajm.domain.User;
import com.worktajm.repository.AuthorityRepository;
import com.worktajm.repository.UserRepository;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.social.connect.Connection;
import org.springframework.social.connect.ConnectionRepository;
import org.springframework.social.connect.UserProfile;
import org.springframework.social.connect.UsersConnectionRepository;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
@Service
public class SocialService {
private final Logger log = LoggerFactory.getLogger(SocialService.class);
@Inject
private UsersConnectionRepository usersConnectionRepository;
@Inject
private AuthorityRepository authorityRepository;
@Inject
private PasswordEncoder passwordEncoder;
@Inject
private UserRepository userRepository;
@Inject
private MailService mailService;
public void createSocialUser(Connection<?> connection, String langKey) {
if (connection == null) {
log.error("Cannot create social user because connection is null");
throw new IllegalArgumentException("Connection cannot be null");
}
UserProfile userProfile = connection.fetchUserProfile();
String providerId = connection.getKey().getProviderId();
User user = createUserIfNotExist(userProfile, langKey, providerId);
createSocialConnection(user.getLogin(), connection);
mailService.sendSocialRegistrationValidationEmail(user, providerId);
}
private User createUserIfNotExist(UserProfile userProfile, String langKey, String providerId) {
String email = userProfile.getEmail();
String userName = userProfile.getUsername();
if (StringUtils.isBlank(email) && StringUtils.isBlank(userName)) {
log.error("Cannot create social user because email and login are null");
throw new IllegalArgumentException("Email and login cannot be null");
}
if (StringUtils.isBlank(email) && userRepository.findOneByLogin(userName).isPresent()) {
log.error("Cannot create social user because email is null and login already exist, login -> {}", userName);
throw new IllegalArgumentException("Email cannot be null with an existing login");
}
Optional<User> user = userRepository.findOneByEmail(email);
if (user.isPresent()) {
log.info("User already exist associate the connection to this account");
return user.get();
}
String login = getLoginDependingOnProviderId(userProfile, providerId);
String encryptedPassword = passwordEncoder.encode(RandomStringUtils.random(10));
Set<Authority> authorities = new HashSet<>(1);
authorities.add(authorityRepository.findOne("ROLE_USER"));
User newUser = new User();
newUser.setLogin(login);
newUser.setPassword(encryptedPassword);
newUser.setFirstName(userProfile.getFirstName());
newUser.setLastName(userProfile.getLastName());
newUser.setEmail(email);
newUser.setActivated(true);
newUser.setAuthorities(authorities);
newUser.setLangKey(langKey);
return userRepository.save(newUser);
}
/**
* @return login if provider manage a login like Twitter or Github otherwise email address.
* Because provider like Google or Facebook didn't provide login or login like "12099388847393"
*/
private String getLoginDependingOnProviderId(UserProfile userProfile, String providerId) {
switch (providerId) {
case "twitter":
return userProfile.getUsername();
default:
return userProfile.getEmail();
}
}
private void createSocialConnection(String login, Connection<?> connection) {
ConnectionRepository connectionRepository = usersConnectionRepository.createConnectionRepository(login);
connectionRepository.addConnection(connection);
}
}