All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.formkiq.server.service.UserServiceImpl Maven / Gradle / Ivy

package com.formkiq.server.service;

import java.util.Date;
import java.util.UUID;

import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.validator.routines.EmailValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.formkiq.server.config.DateService;
import com.formkiq.server.dao.UserDao;
import com.formkiq.server.domain.User;
import com.formkiq.server.domain.UserClient;
import com.formkiq.server.domain.type.UserDTO;
import com.formkiq.server.domain.type.UserListDTO;
import com.formkiq.server.domain.type.UserRole;
import com.formkiq.server.domain.type.UserStatus;

/**
 * UserService Implementation.
 *
 */
@Service
public class UserServiceImpl implements UserService {

    /** Default User Token expiry time. */
	private static final int DEFAULT_EXPIRY_MINUTES = 24 * 60;

	/** DateService. */
	@Autowired
	private DateService dateservice;

    /** PasswordEncoder. */
    @Autowired
    private PasswordEncoder passwordEncoder;

	/** UserDao. */
	@Autowired
	private UserDao userDao;

	/**
	 * default constructor.
	 */
	public UserServiceImpl() {
	}

	@Override
    public User createUser(final String client, final String email,
            final String password, final UserStatus status,
            final UserRole role) throws PreconditionFailedException {

	    if (!EmailValidator.getInstance().isValid(email)) {
	        throw new PreconditionFailedException("Invalid Email " + email);
	    }

	    if (StringUtils.isEmpty(password)) {
	        throw new PreconditionFailedException("Password required");
	    }

	    if (status == null) {
            throw new PreconditionFailedException("UserStatus required");
        }

	    if (role == null) {
            throw new PreconditionFailedException("UserRole required");
        }

	    if (this.userDao.findUser(email) != null) {
	        throw new PreconditionFailedException("Email already registered");
	    }

		User user = new User();
	    user.setEmail(email);
	    user.setStatus(status);
	    user.setRole(role);
	    setUserPassword(user, password);

		this.userDao.saveUser(user);

		createUserClient(user, client);

		return user;
	}

	/**
	 * Create User Client.
	 * @param client String
	 * @param user String
	 */
    private void createUserClient(final User user, final String client) {
        UserClient uc = new UserClient();
		uc.setClientid(client);
		uc.setUserid(user.getUserid());
		this.userDao.saveUserClient(uc);
    }

	@Override
    public void deleteUser(final String email) {

        if (!StringUtils.isEmpty(email)) {

            User user = this.userDao.findUser(email);
            if (user != null) {

                if (!(UserRole.ROLE_ADMIN.equals(user.getRole())
                        && this.userDao.getAdminUserCount() == 1)) {
                    this.userDao.deleteUser(user);
                } else {
                    throw new PreconditionFailedException(
                            "Cannot delete, only admin");
                }

            } else {
                throw new PreconditionFailedException(
                        "Email " + email + " not found");
            }

        } else {

            throw new PreconditionFailedException("Invalid Email");
        }
    }

	@Override
    public UserDetails findActiveUser(final String email,
            final String password) throws AuthenticationFailureException {

        User user = null;

        if (!StringUtils.isEmpty(email) && !StringUtils.isEmpty(password)) {

            user = findActiveUserByEmail(email);

            boolean matched = isMatch(password, user.getPassword());

            if (!matched) {
                throw new AuthenticationFailureException(email);
            }
        }

        if (user == null) {
            throw new AuthenticationFailureException(email);
        }

        return user;
    }

	@Override
    public UserDetails findActiveUser(final String clientid, final String email,
            final String password) throws AuthenticationFailureException {

		User user = null;

		if (!StringUtils.isEmpty(email) && !StringUtils.isEmpty(password)) {

			user = findActiveUserByEmail(email, clientid);

			boolean matched = isMatch(password, user.getPassword());

			if (!matched) {
				throw new AuthenticationFailureException("Invalid Password");
			}
		}

		if (user == null) {
			throw new AuthenticationFailureException(email);
		}

		return user;
	}

	/**
     * Find Active User.
     * @param email {@link String}
     * @return {@link User}
     */
	private User findActiveUserByEmail(final String email) {
	    return findActiveUserByEmail(email, null);
	}

	/**
	 * Find Active User.
	 * @param email {@link String}
	 * @param clientid {@link String} (optional)
	 * @return {@link User}
	 */
    private User findActiveUserByEmail(final String email,
            final String clientid) {

        User user = this.userDao.findUser(email);

        if (user != null && !StringUtils.isEmpty(clientid)) {

            UserClient uc = this.userDao.findUserClient(user, clientid);

            if (uc == null) {
                throw new BadCredentialsException(
                        "User does not have access to Client");
            }
        }

        if (user != null) {

            if (UserStatus.ACTIVE.equals(user.getStatus())) {
                return user;
            }

            throw new AuthenticationFailureException(
                    "User account is disabled");
        }

		throw new AuthenticationFailureException("Invalid Username / Password");
	}

	@Override
    public UserDTO findUser(final String email)
            throws AuthenticationFailureException {

	    UserDTO user = null;

		if (!StringUtils.isEmpty(email)) {

			user = this.userDao.findUserDTO(email);
		}

		if (user == null) {
			throw new AuthenticationFailureException(email);
		}

		return user;
	}

	@Override
    public UserListDTO findUsers(final String token) {
        return this.userDao.findUsers(token);
    }

	/**
	 * Generate secured Password Hash.
	 * @param password String
	 * @return {@link String}
	 */
	String generatedSecuredPasswordHash(final String password) {

		String securedPasswordHash = this.passwordEncoder.encode(password);
		return securedPasswordHash;
	}

	@Override
	public String generateResetToken(final String email)
			throws AuthenticationFailureException {

		User user = findActiveUserByEmail(email);
		String token = generateSecurityToken(user);
		String securedTokenHash = generatedSecuredPasswordHash(token);

		Date now = this.dateservice.now();

		user.setResetToken(securedTokenHash);
		user.setResetInsertedDate(now);
		user.setUpdatedDate(now);
		this.userDao.saveUser(user);

		return token;
	}

    @Override
	public String generateSecurityToken(final UserDetails user) {

		String securityToken = null;

		if (user != null) {
			securityToken = UUID.randomUUID().toString().replaceAll("-", "");
		}

		return securityToken;
	}

    /**
	 * Gets the User Reset Token expiry in minutes.
	 * @return int
	 */
	protected int getUserTokenExpiryInMinutes() {
		return DEFAULT_EXPIRY_MINUTES;
	}

    /**
     * Checks password match.
     * @param rawPassword String
     * @param encodedPassword String
     * @return boolean
     */
    private boolean isMatch(final String rawPassword,
            final String encodedPassword) {
        return this.passwordEncoder.matches(rawPassword, encodedPassword);
    }

    @Override
    public boolean isUserExists(final String email) {
        return this.userDao.findUser(email) != null;
    }

    @Override
    public User saveUser(final String client, final String email,
            final String password, final UserRole role,
            final UserStatus status) {

        User user = this.userDao.findUser(email);

        if (user != null) {

            if (role != null) {
                user.setRole(role);
            }

            if (status != null) {
                user.setStatus(status);
            }

            setUserPassword(user, password);
            this.userDao.saveUser(user);

            if (client != null) {

                UserClient uc = this.userDao.findUserClient(user, client);

                if (uc == null) {
                    createUserClient(user, client);
                }
            }

        } else {

            user = createUser(client, email, password, status, role);
        }

        return user;
    }

    /**
     * Encrypts the User Password and set it into the object.
     * @param user User
     * @param password unencrypted password
     */
    private void setUserPassword(final User user, final String password) {

        if (!StringUtils.isEmpty(password)) {
            String securedPassHash = generatedSecuredPasswordHash(password);
            user.setPassword(securedPassHash);
        }
    }

    @Override
	public void updatePassword(final String email, final String resettoken,
			final String newPassword) {

        boolean updated = false;

        if (!StringUtils.isEmpty(resettoken)) {

            User user = this.userDao.findUser(email);

            if (user != null) {

                if (isMatch(resettoken, user.getResetToken())) {

        	        Date now = this.dateservice.now();
                    Date date = DateUtils.addMinutes(now,
                            -getUserTokenExpiryInMinutes());

        	        if (user.getResetInsertedDate().after(date)) {

        	            user.setResetInsertedDate(null);
        	            user.setResetToken(null);
        	            setUserPassword(user, newPassword);

        	            this.userDao.saveUser(user);
        	            updated = true;
        	        }
                }
            }
        }

        if (!updated) {
            throw new PreconditionFailedException("Invalid Reset Token");
        }
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy