com.esofthead.mycollab.module.user.service.mybatis.UserServiceDBImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.esofthead.mycollab.module.user.service.mybatis.UserServiceDBImpl.java

Source

/**
 * This file is part of mycollab-services.
 *
 * mycollab-services is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mycollab-services is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mycollab-services.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.esofthead.mycollab.module.user.service.mybatis;

import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.esofthead.mycollab.cache.CacheUtils;
import com.esofthead.mycollab.configuration.PasswordEncryptHelper;
import com.esofthead.mycollab.configuration.SiteConfiguration;
import com.esofthead.mycollab.core.DeploymentMode;
import com.esofthead.mycollab.core.UserInvalidInputException;
import com.esofthead.mycollab.core.arguments.NumberSearchField;
import com.esofthead.mycollab.core.arguments.SearchRequest;
import com.esofthead.mycollab.core.arguments.SetSearchField;
import com.esofthead.mycollab.core.arguments.StringSearchField;
import com.esofthead.mycollab.core.cache.CacheKey;
import com.esofthead.mycollab.core.persistence.ICrudGenericDAO;
import com.esofthead.mycollab.core.persistence.ISearchableDAO;
import com.esofthead.mycollab.core.persistence.service.DefaultService;
import com.esofthead.mycollab.esb.CamelProxyBuilderUtil;
import com.esofthead.mycollab.module.billing.RegisterStatusConstants;
import com.esofthead.mycollab.module.billing.service.BillingPlanCheckerService;
import com.esofthead.mycollab.module.file.service.UserAvatarService;
import com.esofthead.mycollab.module.user.dao.RolePermissionMapper;
import com.esofthead.mycollab.module.user.dao.UserAccountInvitationMapper;
import com.esofthead.mycollab.module.user.dao.UserAccountMapper;
import com.esofthead.mycollab.module.user.dao.UserMapper;
import com.esofthead.mycollab.module.user.dao.UserMapperExt;
import com.esofthead.mycollab.module.user.domain.RolePermission;
import com.esofthead.mycollab.module.user.domain.RolePermissionExample;
import com.esofthead.mycollab.module.user.domain.SimpleUser;
import com.esofthead.mycollab.module.user.domain.User;
import com.esofthead.mycollab.module.user.domain.UserAccount;
import com.esofthead.mycollab.module.user.domain.UserAccountExample;
import com.esofthead.mycollab.module.user.domain.UserAccountInvitation;
import com.esofthead.mycollab.module.user.domain.UserExample;
import com.esofthead.mycollab.module.user.domain.criteria.UserSearchCriteria;
import com.esofthead.mycollab.module.user.esb.UserEndpoints;
import com.esofthead.mycollab.module.user.esb.UserRemovedCommand;
import com.esofthead.mycollab.module.user.service.UserService;
import com.esofthead.mycollab.security.PermissionMap;

/**
 * 
 * @author MyCollab Ltd.
 * @since 1.0
 * 
 */
@Service
@Transactional
public class UserServiceDBImpl extends DefaultService<String, User, UserSearchCriteria> implements UserService {

    private static final Logger LOG = LoggerFactory.getLogger(UserServiceDBImpl.class);

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserMapperExt userMapperExt;

    @Autowired
    private UserAccountMapper userAccountMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private UserAvatarService userAvatarService;

    @Autowired
    private UserAccountInvitationMapper userAccountInvitationMapper;

    @Autowired
    private BillingPlanCheckerService billingPlanCheckerService;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public ICrudGenericDAO getCrudMapper() {
        return userMapper;
    }

    @Override
    public ISearchableDAO<UserSearchCriteria> getSearchMapper() {
        return userMapperExt;
    }

    @Override
    public void saveUserAccount(SimpleUser record, Integer sAccountId, String inviteUser) {
        billingPlanCheckerService.validateAccountCanCreateNewUser(sAccountId);

        // check if user email has already in this account yet
        UserAccountExample userAccountEx = new UserAccountExample();

        if (SiteConfiguration.getDeploymentMode() == DeploymentMode.site) {
            userAccountEx.createCriteria().andUsernameEqualTo(record.getEmail()).andAccountidEqualTo(sAccountId)
                    .andRegisterstatusIn(Arrays.asList(RegisterStatusConstants.ACTIVE,
                            RegisterStatusConstants.SENT_VERIFICATION_EMAIL, RegisterStatusConstants.VERIFICATING));
        } else {
            userAccountEx.createCriteria().andUsernameEqualTo(record.getEmail())
                    .andRegisterstatusIn(Arrays.asList(RegisterStatusConstants.ACTIVE,
                            RegisterStatusConstants.SENT_VERIFICATION_EMAIL, RegisterStatusConstants.VERIFICATING));
        }

        if (userAccountMapper.countByExample(userAccountEx) > 0) {
            throw new UserInvalidInputException(
                    "There is already user has email " + record.getEmail() + " in your account");
        }

        if (record.getPassword() != null) {
            record.setPassword(PasswordEncryptHelper.encryptSaltPassword(record.getPassword()));
        }

        if (record.getUsername() == null) {
            record.setUsername(record.getEmail());
        }

        if (record.getLastname() == null) {
            String userEmail = record.getEmail();
            int index = userEmail.lastIndexOf("@");
            if (index > 0) {
                record.setLastname(userEmail.substring(0, index));
            } else {
                record.setLastname(userEmail);
            }
        }

        if (record.getFirstname() == null) {
            record.setFirstname("");
        }

        // Check if user has already account in system, if not we will create
        // new user

        UserExample userEx = new UserExample();
        userEx.createCriteria().andUsernameEqualTo(record.getUsername());
        if (userMapper.countByExample(userEx) == 0) {
            record.setRegisterstatus(RegisterStatusConstants.VERIFICATING);
            userMapper.insert(record);

            userAvatarService.uploadDefaultAvatar(record.getUsername());
        }

        // save record in s_user_account table
        UserAccount userAccount = new UserAccount();
        userAccount.setAccountid(record.getAccountId());
        userAccount.setIsaccountowner(
                (record.getIsAccountOwner() == null) ? Boolean.FALSE : record.getIsAccountOwner());

        userAccount.setRoleid(record.getRoleid());
        userAccount.setUsername(record.getUsername());
        userAccount.setRegisteredtime(new GregorianCalendar().getTime());
        userAccount.setLastaccessedtime(new GregorianCalendar().getTime());
        userAccount.setRegisterstatus((record.getRegisterstatus() == null) ? RegisterStatusConstants.VERIFICATING
                : record.getRegisterstatus());

        LOG.debug(
                "Check whether user is already in this account with status different than ACTIVE, then change status of him");
        userAccountEx = new UserAccountExample();
        if (SiteConfiguration.getDeploymentMode() == DeploymentMode.site) {
            userAccountEx.createCriteria().andUsernameEqualTo(record.getEmail()).andAccountidEqualTo(sAccountId);
        } else {
            userAccountEx.createCriteria().andUsernameEqualTo(record.getEmail());
        }

        if (userAccountMapper.countByExample(userAccountEx) > 0) {
            userAccountMapper.updateByExampleSelective(userAccount, userAccountEx);
        } else {
            userAccountMapper.insert(userAccount);
        }

        if (!RegisterStatusConstants.ACTIVE.equals(record.getRegisterstatus())) {
            // save to invitation user
            UserAccountInvitation invitation = new UserAccountInvitation();
            invitation.setAccountid(record.getAccountId());
            invitation.setCreatedtime(new GregorianCalendar().getTime());
            invitation.setUsername(record.getUsername());
            invitation.setInviteuser(inviteUser);
            invitation
                    .setInvitationstatus((record.getRegisterstatus() == null) ? RegisterStatusConstants.VERIFICATING
                            : record.getRegisterstatus());
            userAccountInvitationMapper.insert(invitation);
        }
    }

    @Override
    public int updateWithSession(User record, String username) {
        LOG.debug("Check whether there is exist email in system before");
        if ((record.getEmail()) != null && !record.getUsername().equals(record.getEmail())) {
            UserExample ex = new UserExample();
            ex.createCriteria().andUsernameEqualTo(record.getEmail());
            int numUsers = userMapper.countByExample(ex);
            if (numUsers > 0) {
                throw new UserInvalidInputException("Email " + record.getEmail()
                        + " is already existed in system. Please choose another email.");
            }
        }

        // now we keep username similar than email
        UserExample ex = new UserExample();
        ex.createCriteria().andUsernameEqualTo(record.getUsername());
        record.setUsername(record.getEmail());
        return userMapper.updateByExampleSelective(record, ex);
    }

    @Override
    public void updateUserAccount(SimpleUser record, Integer sAccountId) {
        LOG.debug("Check whether there is exist email in system before");
        if (!record.getUsername().equals(record.getEmail())) {
            UserExample ex = new UserExample();
            ex.createCriteria().andUsernameEqualTo(record.getEmail());
            int numUsers = userMapper.countByExample(ex);
            if (numUsers > 0) {
                throw new UserInvalidInputException("Email " + record.getEmail()
                        + " is already existed in system. Please choose another email.");
            }
        }

        // now we keep username similar than email
        UserExample ex = new UserExample();
        ex.createCriteria().andUsernameEqualTo(record.getUsername());
        record.setUsername(record.getEmail());
        userMapper.updateByExampleSelective(record, ex);

        UserAccountExample userAccountEx = new UserAccountExample();
        userAccountEx.createCriteria().andUsernameEqualTo(record.getUsername()).andAccountidEqualTo(sAccountId);
        List<UserAccount> userAccounts = userAccountMapper.selectByExample(userAccountEx);
        if (userAccounts.size() > 0) {
            UserAccount userAccount = userAccounts.get(0);
            if (record.getRoleid() == -1) {
                userAccount.setRoleid(null);
                userAccount.setIsaccountowner(true);
            } else {
                userAccount.setRoleid(record.getRoleid());
            }

            userAccount.setRegisterstatus(record.getRegisterstatus());
            userAccount.setLastaccessedtime(new GregorianCalendar().getTime());
            userAccountMapper.updateByPrimaryKey(userAccount);
        }
    }

    @Override
    public void massRemoveWithSession(List<String> primaryKeys, String username, int accountId) {
        userMapperExt.removeKeysWithSession(primaryKeys);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public SimpleUser authentication(String username, String password, String subDomain,
            boolean isPasswordEncrypt) {
        UserSearchCriteria criteria = new UserSearchCriteria();
        criteria.setUsername(new StringSearchField(username));
        criteria.setSaccountid(null);

        if (SiteConfiguration.getDeploymentMode() == DeploymentMode.site) {
            criteria.setSubdomain(new StringSearchField(subDomain));
        }

        List<SimpleUser> users = findPagableListByCriteria(new SearchRequest<>(criteria, 0, Integer.MAX_VALUE));
        if (users == null || users.isEmpty()) {
            throw new UserInvalidInputException("User " + username + " is not existed in this domain");
        } else {
            SimpleUser user = users.get(0);
            if (user.getPassword() == null
                    || !PasswordEncryptHelper.checkPassword(password, user.getPassword(), isPasswordEncrypt)) {
                LOG.debug("PASS: " + password + "   " + user.getPassword());
                throw new UserInvalidInputException("Invalid username or password");
            }

            LOG.debug("User " + username + " login to system successfully!");

            if (user.getIsAccountOwner() == null
                    || (user.getIsAccountOwner() != null && !user.getIsAccountOwner())) {
                if (user.getRoleid() != null) {
                    LOG.debug("User " + username + " is not admin. Getting his role");
                    RolePermissionExample ex = new RolePermissionExample();
                    ex.createCriteria().andRoleidEqualTo(user.getRoleid());
                    List roles = rolePermissionMapper.selectByExampleWithBLOBs(ex);
                    if (CollectionUtils.isNotEmpty(roles)) {
                        RolePermission rolePer = (RolePermission) roles.get(0);
                        PermissionMap permissionMap = PermissionMap.fromJsonString(rolePer.getRoleval());
                        user.setPermissionMaps(permissionMap);
                        LOG.debug("Find role match to user " + username);
                    } else {
                        LOG.debug("We can not find any role associate to user " + username);
                    }
                } else {
                    LOG.debug("User " + username + " has no any role");
                }
            }
            user.setPassword(null);
            return user;
        }
    }

    @Override
    public SimpleUser findUserByUserNameInAccount(String username, Integer accountId) {
        UserSearchCriteria criteria = new UserSearchCriteria();
        criteria.setUsername(new StringSearchField(username));
        criteria.setSaccountid(new NumberSearchField(accountId));

        List<SimpleUser> users = userMapperExt.findPagableListByCriteria(criteria,
                new RowBounds(0, Integer.MAX_VALUE));
        if (CollectionUtils.isEmpty(users)) {
            return null;
        } else {
            return users.get(0);
        }
    }

    @Override
    public void pendingUserAccount(String username, Integer accountId) {
        pendingUserAccounts(Arrays.asList(username), accountId);

        // clean cache of related items
        CacheUtils.cleanCaches(accountId, UserService.class);
    }

    private void internalPendingUserAccount(String username, Integer accountId) {
        // check if current user is the unique account owner, then reject
        // deletion
        UserAccountExample userAccountEx = new UserAccountExample();
        userAccountEx.createCriteria().andUsernameEqualTo(username).andAccountidEqualTo(accountId);
        List<UserAccount> accounts = userAccountMapper.selectByExample(userAccountEx);
        if (accounts.size() > 0) {
            UserAccount account = accounts.get(0);
            if (account.getIsaccountowner() != null && account.getIsaccountowner() == Boolean.TRUE) {
                userAccountEx = new UserAccountExample();
                userAccountEx.createCriteria().andAccountidEqualTo(accountId)
                        .andIsaccountownerEqualTo(Boolean.TRUE);
                if (userAccountMapper.countByExample(userAccountEx) == 1) {
                    throw new UserInvalidInputException("Can not delete user " + username + ". The reason is "
                            + username + " is the unique account owner of the current account.");
                }
            }
        }

        userAccountEx = new UserAccountExample();
        userAccountEx.createCriteria().andUsernameEqualTo(username).andAccountidEqualTo(accountId);
        UserAccount userAccount = new UserAccount();
        userAccount.setRegisterstatus(RegisterStatusConstants.DELETE);
        userAccountMapper.updateByExampleSelective(userAccount, userAccountEx);

        // notify users are "deleted"
        UserRemovedCommand userRemovedCommand = CamelProxyBuilderUtil.build(UserEndpoints.USER_REMOVE_ENDPOINT,
                UserRemovedCommand.class);
        userRemovedCommand.userRemoved(username, accountId);
    }

    @Override
    public void pendingUserAccounts(List<String> usernames, Integer accountId) {
        for (String username : usernames) {
            internalPendingUserAccount(username, accountId);
        }

        // clean cache of related items
        CacheUtils.cleanCaches(accountId, UserService.class);
    }

    @Override
    public User findUserByUserName(String username) {
        UserExample ex = new UserExample();
        ex.createCriteria().andUsernameEqualTo(username);
        List<User> users = userMapper.selectByExample(ex);
        if (CollectionUtils.isEmpty(users)) {
            return null;
        } else {
            return users.get(0);
        }
    }

    @Override
    public void updateUserAccountStatus(String username, Integer sAccountId, String registerStatus) {
        // Update status of user account
        UserAccount userAccount = new UserAccount();
        userAccount.setAccountid(sAccountId);
        userAccount.setUsername(username);
        userAccount.setRegisterstatus(registerStatus);

        UserAccountExample ex = new UserAccountExample();
        ex.createCriteria().andAccountidEqualTo(sAccountId).andUsernameEqualTo(username);
        userAccountMapper.updateByExampleSelective(userAccount, ex);
    }

    @Override
    public void updateUserAccountsStatus(List<String> usernames, @CacheKey Integer sAccountId,
            String registerStatus) {
        for (String username : usernames) {
            updateUserAccountStatus(username, sAccountId, registerStatus);
        }

    }

    @Override
    public int getTotalActiveUsersInAccount(@CacheKey Integer accountId) {
        UserSearchCriteria criteria = new UserSearchCriteria();
        criteria.setRegisterStatuses(new SetSearchField<>(new String[] { RegisterStatusConstants.ACTIVE }));
        criteria.setSaccountid(new NumberSearchField(accountId));
        return userMapperExt.getTotalCount(criteria);
    }
}