com.sshdemo.common.security.manage.service.UserService.java Source code

Java tutorial

Introduction

Here is the source code for com.sshdemo.common.security.manage.service.UserService.java

Source

/**
 * Copyright (c)2010-2011 Enterprise Website Content Management System(EWCMS), All rights reserved.
 * EWCMS PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * http://www.ewcms.com
 */

package com.sshdemo.common.security.manage.service;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.sshdemo.common.security.manage.model.Authority;
import com.sshdemo.common.security.manage.model.Group;
import com.sshdemo.common.security.manage.model.User;
import com.sshdemo.common.security.manage.model.UserInfo;

@Service
public class UserService extends AbstractService implements UserServiceable {

    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    private String defaultPassword = "666666";

    @Autowired(required = false)
    private AuthenticationManager authenticationManager;

    @Autowired(required = false)
    private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder();

    @Autowired(required = false)
    private SaltSource saltSource;

    @Override
    public String addUser(final String username, final String password, final boolean enabled,
            final Date accountStart, final Date accountEnd, final UserInfo userInfo) throws UserServiceException {

        if (accountStart != null && accountEnd != null) {
            Assert.isTrue(accountEnd.getTime() > accountStart.getTime(), "account date start > end");
        }

        if (hasUsername(username)) {
            throw new UserServiceException(
                    messages.getMessage("UserService.usernameExist", "username already exist"));
        }

        User user = new User(username, enabled, accountStart, accountEnd);
        UserInfo info = (userInfo != null ? userInfo : new UserInfo());
        info.setUsername(username);
        if (info.getName() == null) {
            info.setName(username);
        }

        user.setUserInfo(info);

        //??
        String newPassword = StringUtils.isBlank(password) ? defaultPassword : password;
        user.setPassword(newPassword); //UserDetails password?
        UserDetails userDetails = createUserDetails(user);
        user.setPassword(passwordEncoder(userDetails, newPassword));

        userDao.persist(user);

        return username;
    }

    /**
     * 
     * 
     * ?
     * 
     * @param username ??
     * @return  
     * @throws UserServiceException
     */
    private User getExistUser(final String username) throws UserServiceException {
        User user = userDao.get(username);
        if (user == null) {
            throw new UserServiceException(messages.getMessage("GroupService.groupNotFound",
                    new Object[] { username }, "Can't found  " + username + " username"));
        }
        return user;
    }

    @Override
    public String updateUser(final String username, final boolean enabled, final Date accountStart,
            final Date accountEnd, final UserInfo userInfo) throws UserServiceException {

        if (accountStart != null && accountEnd != null) {
            Assert.isTrue(accountEnd.getTime() > accountStart.getTime(), "account date start > end");
        }

        User user = getExistUser(username);
        user.setEnabled(enabled);
        user.setAccountStart(accountStart);
        user.setAccountEnd(accountEnd);
        user.getUserInfo().setBirthday(userInfo.getBirthday());
        user.getUserInfo().setEmail(userInfo.getEmail());
        user.getUserInfo().setIdentification(userInfo.getIdentification());
        user.getUserInfo().setMphone(userInfo.getMphone());
        user.getUserInfo().setName(userInfo.getName());
        user.getUserInfo().setPhone(userInfo.getPhone());

        userDao.persist(user);

        return username;
    }

    @Override
    public User getUser(final String username) {
        return userDao.get(username);
    }

    @Override
    public void removeUser(final String username) {
        userDao.removeByPK(username);
        userCache.removeUserFromCache(username);
    }

    @Override
    public void activeUser(final String username) throws UserServiceException {
        User user = getExistUser(username);
        user.setEnabled(true);
    }

    @Override
    public void inactiveUser(final String username) throws UserServiceException {
        User user = getExistUser(username);
        user.setEnabled(false);
        userDao.persist(user);
        removeExpiredUserByUsername(username);
    }

    @Override
    public Set<Authority> addAuthoritiesToUser(String username, Set<String> names) throws UserServiceException {
        User user = getExistUser(username);
        Set<Authority> newAuths = new HashSet<Authority>();
        for (String name : names) {
            Authority newAuth = getAuthorityByName(name);
            if (!user.getAuthorities().contains(newAuth)) {
                newAuths.add(newAuth);
            }
        }
        user.getAuthorities().addAll(newAuths);
        userDao.persist(user);

        removeExpiredUserByUsername(username);

        return newAuths;
    }

    @Override
    public void removeAuthoritiesInUser(String username, Set<String> names) throws UserServiceException {
        User user = getExistUser(username);

        Set<Authority> auths = new HashSet<Authority>();
        for (Authority auth : user.getAuthorities()) {
            if (!names.contains(auth.getName())) {
                auths.add(auth);
            }
        }
        user.setAuthorities(auths);
        userDao.persist(user);

        removeExpiredUserByUsername(username);
    }

    @Override
    public Set<Group> addGroupsToUser(String username, Set<String> names) {
        User user = getExistUser(username);

        Set<Group> newGroups = new HashSet<Group>();
        for (String name : names) {
            Group newGroup = getGroupByName(name);
            if (!user.getGroups().contains(newGroup)) {
                newGroups.add(newGroup);
            }
        }
        user.getGroups().addAll(newGroups);
        userDao.persist(user);

        removeExpiredUserByUsername(username);

        return newGroups;
    }

    @Override
    public void removeGroupsInUser(String username, Set<String> names) {
        User user = getExistUser(username);

        Set<Group> groups = new HashSet<Group>();
        for (Group group : user.getGroups()) {
            if (!names.contains(group.getName())) {
                groups.add(group);
            }
        }
        user.setGroups(groups);
        userDao.persist(user);

        removeExpiredUserByUsername(username);
    }

    @Override
    public UserInfo getCurrentUserInfo() throws AuthenticationException {
        Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
        if (currentUser == null) {
            throw new AccessDeniedException(
                    "Can't change user info as no Authentication object found in context for current user.");
        }

        final String username = currentUser.getName();

        User user = userDao.get(username);
        return user == null ? null : user.getUserInfo();
    }

    @Override
    public void updateUserInfo(final UserInfo userInfo) throws AuthenticationException {
        Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
        if (currentUser == null) {
            throw new AccessDeniedException(
                    "Can't change user info as no Authentication object found in context for current user.");
        }

        final String username = currentUser.getName();

        User user = userDao.get(username);
        if (user == null) {
            if (logger.isDebugEnabled()) {
                logger.debug("{} user is null", username);
            }
            return;
        }

        user.getUserInfo().setBirthday(userInfo.getBirthday());
        user.getUserInfo().setEmail(userInfo.getEmail());
        user.getUserInfo().setIdentification(userInfo.getIdentification());
        user.getUserInfo().setMphone(userInfo.getMphone());
        user.getUserInfo().setName(userInfo.getName());
        user.getUserInfo().setPhone(userInfo.getPhone());

        userDao.persist(user);
    }

    @Override
    public void changePassword(final String oldPassword, final String newPassword) throws AuthenticationException {
        Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
        if (currentUser == null) {
            throw new AccessDeniedException(
                    "Can't change password as no Authentication object found in context for current user.");
        }

        final String username = currentUser.getName();

        if (this.authenticationManager != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Reauthenticating user '{}' for password change request.", username);
            }
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, oldPassword));
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("No authentication manage set.Password won't be re-checked");
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Changing password for user {}'", username);
        }
        UserDetails userDetails = loadUserByUsername(username);
        String encoder = passwordEncoder(userDetails, newPassword);
        userDao.updatePassword(username, encoder);

        SecurityContextHolder.getContext().setAuthentication(createNewAuthentication(userDetails, encoder));

        userCache.removeUserFromCache(username);
    }

    protected String passwordEncoder(UserDetails userDetails, String password) {
        Object salt = (saltSource == null ? null : saltSource.getSalt(userDetails));
        return passwordEncoder.encodePassword(password, salt);
    }

    protected Authentication createNewAuthentication(UserDetails userDetails, String newPassword) {
        UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(userDetails,
                userDetails.getPassword(), userDetails.getAuthorities());
        newAuthentication.setDetails(userDetails);
        return newAuthentication;
    }

    @Override
    public void initPassword(final String username, final String password) throws AuthenticationException {
        UserDetails userDetails = this.loadUserByUsername(username);
        String encoder = passwordEncoder(userDetails, password);
        userDao.updatePassword(username, encoder);
        userCache.removeUserFromCache(username);
    }

    @Override
    public boolean hasUsername(String username) {
        User user = userDao.get(username);
        return user != null;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {

        UserDetails userDetails = userCache.getUserFromCache(username);
        if (userDetails != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("userDetails has cache");
            }
            return userDetails;
        }
        if (logger.isDebugEnabled()) {
            logger.debug("userDetails has not cache");
        }

        User user = userDao.get(username);
        if (user == null) {
            throw new UsernameNotFoundException("not fonund " + username);
        }

        userDetails = createUserDetails(user);
        userCache.putUserInCache(userDetails);
        return userDetails;
    }

    /**
     * PO User?Spring Security UserDetails
     * 
     * @param user
     * @return UserDetails
     */
    private UserDetails createUserDetails(final User user) {
        Assert.notNull(user, "user is null");

        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();

        Set<Authority> auths = user.getAuthorities();
        if (auths != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("loadding user authorities");
            }
            for (Authority auth : auths) {
                authorities.add(new GrantedAuthorityImpl(auth.getName()));
            }
        }

        Set<Group> groups = user.getGroups();
        if (groups != null) {
            for (Group group : groups) {
                if (logger.isDebugEnabled()) {
                    logger.debug("lodding {} of group authorities", group.getName());
                }
                authorities.addAll(groupAuthorities(group));
            }
        }

        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                user.isEnabled(), noExpired(user.getAccountStart(), user.getAccountEnd()), true, true, authorities);
    }

    /**
     * 
     * 
     * start=nullend=null,?
     * 
     * @param start 
     * @param end   ?
     * @return  true ? false 
     */
    protected boolean noExpired(final Date start, final Date end) {

        if (start == null && end == null) {
            return true;
        }

        boolean nonExpired = true;
        long now = System.currentTimeMillis();
        if (start != null) {
            nonExpired = nonExpired && start.getTime() <= now;
        }
        if (end != null) {
            nonExpired = nonExpired && end.getTime() >= now;
        }

        return nonExpired;
    }

    /**
     * ??
     * 
     * ????ACL
     * 
     * @param group 
     * @return ??
     */
    protected Set<GrantedAuthority> groupAuthorities(final Group group) {
        Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();

        Set<Authority> auths = group.getAuthorities();
        if (auths != null) {
            for (Authority auth : auths) {
                authorities.add(new GrantedAuthorityImpl(auth.getName()));
            }
        }
        authorities.add(new GrantedAuthorityImpl(group.getName()));

        return authorities;
    }

    public void setDefaultPassword(String defaultPassword) {
        this.defaultPassword = defaultPassword;
    }

    @Override
    public String getDefaultPassword() {
        return this.defaultPassword;
    }

    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    public void setSaltSource(SaltSource saltSource) {
        this.saltSource = saltSource;
    }
}