Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.mycompany.myapp.service;
- import com.mycompany.myapp.domain.Authority;
- import com.mycompany.myapp.domain.User;
- import com.mycompany.myapp.repository.AuthorityRepository;
- import com.mycompany.myapp.repository.UserRepository;
- import com.mycompany.myapp.security.AuthoritiesConstants;
- import org.apache.commons.lang3.RandomStringUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.context.SecurityContextHolder;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.crypto.password.PasswordEncoder;
- import org.springframework.social.connect.*;
- import org.springframework.social.facebook.connect.FacebookConnectionFactory;
- import org.springframework.social.google.connect.GoogleConnectionFactory;
- import org.springframework.social.oauth1.OAuthToken;
- import org.springframework.social.oauth2.AccessGrant;
- import org.springframework.social.twitter.connect.TwitterConnectionFactory;
- import org.springframework.stereotype.Service;
- import java.util.*;
- @Service
- public class SocialService {
- private final Logger log = LoggerFactory.getLogger(SocialService.class);
- private final UsersConnectionRepository usersConnectionRepository;
- private final AuthorityRepository authorityRepository;
- private final PasswordEncoder passwordEncoder;
- private final UserRepository userRepository;
- private final UserDetailsService userDetailsService;
- private final ConnectionFactoryLocator connectionFactoryLocator;
- private final MailService mailService;
- public SocialService(UsersConnectionRepository usersConnectionRepository, AuthorityRepository authorityRepository,
- PasswordEncoder passwordEncoder, UserRepository userRepository, UserDetailsService userDetailsService, ConnectionFactoryLocator connectionFactoryLocator, MailService mailService) {
- this.usersConnectionRepository = usersConnectionRepository;
- this.authorityRepository = authorityRepository;
- this.passwordEncoder = passwordEncoder;
- this.userRepository = userRepository;
- this.userDetailsService = userDetailsService;
- this.connectionFactoryLocator = connectionFactoryLocator;
- this.mailService = mailService;
- }
- public void deleteUserSocialConnection(String login) {
- ConnectionRepository connectionRepository = usersConnectionRepository.createConnectionRepository(login);
- connectionRepository.findAllConnections().keySet().stream()
- .forEach(providerId -> {
- connectionRepository.removeConnections(providerId);
- log.debug("Delete user social connection providerId: {}", providerId);
- });
- }
- public User 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();
- String imageUrl = connection.getImageUrl();
- User user = createUserIfNotExist(userProfile, langKey, providerId, imageUrl);
- createSocialConnection(user.getLogin(), connection);
- mailService.sendSocialRegistrationValidationEmail(user, providerId);
- return user;
- }
- private User createUserIfNotExist(UserProfile userProfile, String langKey, String providerId, String imageUrl) {
- String email = userProfile.getEmail();
- String userName = userProfile.getUsername();
- if (!StringUtils.isBlank(userName)) {
- userName = userName.toLowerCase(Locale.ENGLISH);
- }
- 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");
- }
- if (!StringUtils.isBlank(email)) {
- Optional<User> user = userRepository.findOneByEmailIgnoreCase(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(AuthoritiesConstants.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);
- newUser.setImageUrl(imageUrl);
- 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"
- */
- public String getLoginDependingOnProviderId(UserProfile userProfile, String providerId) {
- switch (providerId) {
- case "twitter":
- return userProfile.getUsername().toLowerCase();
- default:
- return userProfile.getFirstName().toLowerCase() + "_" + userProfile.getLastName().toLowerCase();
- }
- }
- private void createSocialConnection(String login, Connection<?> connection) {
- ConnectionRepository connectionRepository = usersConnectionRepository.createConnectionRepository(login);
- connectionRepository.addConnection(connection);
- }
- public void loadConnectionFromToken(String token, String secret, String provider) {
- Connection connection = null;
- UserProfile userProfile = null;
- if ("facebook".equals(provider)) {
- AccessGrant accessGrant = new AccessGrant(token);
- connection = ((FacebookConnectionFactory)connectionFactoryLocator.getConnectionFactory(provider)).createConnection(accessGrant);
- userProfile = connection.fetchUserProfile();
- } else if ("twitter".equals(provider)) {
- OAuthToken oAuthToken = new OAuthToken(token, secret);
- connection = ((TwitterConnectionFactory)connectionFactoryLocator.getConnectionFactory("twitter")).createConnection(oAuthToken);
- userProfile = connection.fetchUserProfile();
- } else if ("google".equals(provider)) {
- AccessGrant accessGrant = new AccessGrant(token);
- connection = ((GoogleConnectionFactory)connectionFactoryLocator.getConnectionFactory(provider)).createConnection(accessGrant);
- userProfile = connection.fetchUserProfile();
- }
- // check if the user exists
- List<String> userIds = usersConnectionRepository.findUserIdsWithConnection(connection);
- String userLogin;
- if (userIds.size() == 0) {
- log.debug("User needs to be created");
- userLogin = createSocialUser(connection, "en").getLogin();
- } else {
- log.debug("User already exists, logging in");
- userLogin = getLoginDependingOnProviderId(userProfile, provider);
- }
- UserDetails user = userDetailsService.loadUserByUsername(userLogin);
- Authentication newAuth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
- SecurityContextHolder.getContext().setAuthentication(newAuth);
- }
- }
Add Comment
Please, Sign In to add comment