|  | @@ -2,6 +2,8 @@ package com.hichina.main.back.hichinamainback.config;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import com.hichina.main.back.hichinamainback.mapper.UserMapper;
 | 
	
		
			
				|  |  |  import com.hichina.main.back.hichinamainback.model.User;
 | 
	
		
			
				|  |  | +import com.hichina.main.back.hichinamainback.utils.FacebookAccessTokenValidator;
 | 
	
		
			
				|  |  | +import com.hichina.main.back.hichinamainback.utils.UserUtil;
 | 
	
		
			
				|  |  |  import org.apache.commons.lang3.RandomStringUtils;
 | 
	
		
			
				|  |  |  import org.apache.commons.lang3.StringUtils;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Autowired;
 | 
	
	
		
			
				|  | @@ -18,6 +20,7 @@ import java.security.MessageDigest;
 | 
	
		
			
				|  |  |  import java.security.NoSuchAlgorithmException;
 | 
	
		
			
				|  |  |  import java.security.spec.InvalidKeySpecException;
 | 
	
		
			
				|  |  |  import java.util.ArrayList;
 | 
	
		
			
				|  |  | +import java.util.Date;
 | 
	
		
			
				|  |  |  import java.util.List;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  @Component
 | 
	
	
		
			
				|  | @@ -25,23 +28,33 @@ public class CustomAuthenticationProvider implements AuthenticationProvider {
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private UserMapper userMapper;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private FacebookAccessTokenValidator facebookAccessTokenValidator;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * the assumption for this method is, register already happens for this user, otherwise login fails
 | 
	
		
			
				|  |  | +     * @param authentication the authentication request object.
 | 
	
		
			
				|  |  | +     * @return
 | 
	
		
			
				|  |  | +     * @throws AuthenticationException
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public Authentication authenticate(Authentication authentication)
 | 
	
		
			
				|  |  |              throws AuthenticationException {
 | 
	
		
			
				|  |  | +        // this name here is actually the login identity, which is email by default
 | 
	
		
			
				|  |  |          String name = authentication.getName();
 | 
	
		
			
				|  |  | +        // this password is password for normal login, and accesstoken string for facebook login
 | 
	
		
			
				|  |  |          String password = authentication.getCredentials().toString();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if(name.contains(",") || StringUtils.isEmpty(password)){
 | 
	
		
			
				|  |  | -            return null;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  | -            List<User> users = userMapper.findByUsernameOrEmail(name);
 | 
	
		
			
				|  |  | -            if(users.isEmpty()){
 | 
	
		
			
				|  |  | +            User user = UserUtil.getUserByEmail(userMapper, name);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // user not exist for this email, login fail
 | 
	
		
			
				|  |  | +            if(user==null){
 | 
	
		
			
				|  |  |                  return null;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            User user = users.get(0);
 | 
	
		
			
				|  |  | -            if(correctUserNameAndPassword(user, password)){
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if(correctUserNameAndPassword(user, password, user.getLoginType())){
 | 
	
		
			
				|  |  |                  return new UsernamePasswordAuthenticationToken(user.getUsername()+"["+user.getEmail()+"]", password, new ArrayList<>());
 | 
	
		
			
				|  |  |              }else{
 | 
	
		
			
				|  |  |                  return null;
 | 
	
	
		
			
				|  | @@ -53,26 +66,57 @@ public class CustomAuthenticationProvider implements AuthenticationProvider {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private Boolean correctUserNameAndPassword(User user, String password) throws NoSuchAlgorithmException, InvalidKeySpecException {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        String storedPassord = user.getPassword();
 | 
	
		
			
				|  |  | -        Integer pwdCode = user.getPwdCode();
 | 
	
		
			
				|  |  | -        if(pwdCode!=null && pwdCode==-1){
 | 
	
		
			
				|  |  | -            return newLoginLogicCheck(user, password);
 | 
	
		
			
				|  |  | +    private User generateOrUpdateUser(String fbId, String name, String email, String profileImageUrl){
 | 
	
		
			
				|  |  | +        User user = UserUtil.getUserByEmail(userMapper, email);
 | 
	
		
			
				|  |  | +        if(user==null){
 | 
	
		
			
				|  |  | +            //register new user
 | 
	
		
			
				|  |  | +            user = new User();
 | 
	
		
			
				|  |  | +            user.setCreatedTime(new Date());
 | 
	
		
			
				|  |  | +            user.setSalt(CustomAuthenticationProvider.generateSalt());
 | 
	
		
			
				|  |  | +            user.setUsername(name);
 | 
	
		
			
				|  |  | +            user.setPassword("");
 | 
	
		
			
				|  |  | +            user.setEmail(email);
 | 
	
		
			
				|  |  | +            user.setFacebookId(fbId);
 | 
	
		
			
				|  |  | +            user.setProfileImageUrl(profileImageUrl);
 | 
	
		
			
				|  |  | +            user.setPwdCode(-1);
 | 
	
		
			
				|  |  | +            user.setUserId(java.util.UUID.randomUUID().toString());
 | 
	
		
			
				|  |  | +            userMapper.insert(user);
 | 
	
		
			
				|  |  |          }else{
 | 
	
		
			
				|  |  | -            // old logic, allow old logic only once here
 | 
	
		
			
				|  |  | -            if(validatePasswordTheOldWay(password,storedPassord, pwdCode )){
 | 
	
		
			
				|  |  | -                // update pwdcode -1,  generate random salt, use the salt and new logic to generate encrypted password
 | 
	
		
			
				|  |  | -                String salt = generateSalt();
 | 
	
		
			
				|  |  | -                user.setSalt(salt);
 | 
	
		
			
				|  |  | -                user.setPwdCode(-1);
 | 
	
		
			
				|  |  | -                user.setPassword(generateStrongPasswordHash(password, salt));
 | 
	
		
			
				|  |  | -                userMapper.update(user);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                return true;
 | 
	
		
			
				|  |  | +            // update user with facebook info
 | 
	
		
			
				|  |  | +            user.setFacebookId(fbId);
 | 
	
		
			
				|  |  | +            user.setUsername(name);
 | 
	
		
			
				|  |  | +            user.setProfileImageUrl(profileImageUrl);
 | 
	
		
			
				|  |  | +            userMapper.update(user);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return user;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private Boolean correctUserNameAndPassword(User user, String password, String loginType) throws NoSuchAlgorithmException, InvalidKeySpecException {
 | 
	
		
			
				|  |  | +        if(StringUtils.isEmpty(loginType) || Constants.REGULAR_LOGIN.equals(loginType)){
 | 
	
		
			
				|  |  | +            String storedPassord = user.getPassword();
 | 
	
		
			
				|  |  | +            Integer pwdCode = user.getPwdCode();
 | 
	
		
			
				|  |  | +            if(pwdCode!=null && pwdCode==-1){
 | 
	
		
			
				|  |  | +                return newLoginLogicCheck(user, password);
 | 
	
		
			
				|  |  |              }else{
 | 
	
		
			
				|  |  | -                return false;
 | 
	
		
			
				|  |  | +                // old logic, allow old logic only once here
 | 
	
		
			
				|  |  | +                if(validatePasswordTheOldWay(password,storedPassord, pwdCode )){
 | 
	
		
			
				|  |  | +                    // update pwdcode -1,  generate random salt, use the salt and new logic to generate encrypted password
 | 
	
		
			
				|  |  | +                    String salt = generateSalt();
 | 
	
		
			
				|  |  | +                    user.setSalt(salt);
 | 
	
		
			
				|  |  | +                    user.setPwdCode(-1);
 | 
	
		
			
				|  |  | +                    user.setPassword(generateStrongPasswordHash(password, salt));
 | 
	
		
			
				|  |  | +                    userMapper.update(user);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    return true;
 | 
	
		
			
				|  |  | +                }else{
 | 
	
		
			
				|  |  | +                    return false;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +        }else if(Constants.FACEBOOK_LOGIN.equals(loginType)){
 | 
	
		
			
				|  |  | +            return facebookAccessTokenValidator.validateAccessToken(password);
 | 
	
		
			
				|  |  | +        }else{
 | 
	
		
			
				|  |  | +            return false;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 |