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

Java tutorial

Introduction

Here is the source code for com.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.mycollab.module.user.service.mybatis;

import com.google.common.eventbus.AsyncEventBus;
import com.mycollab.configuration.EnDecryptHelper;
import com.mycollab.configuration.IDeploymentMode;
import com.mycollab.core.UserInvalidInputException;
import com.mycollab.db.arguments.BasicSearchRequest;
import com.mycollab.db.arguments.NumberSearchField;
import com.mycollab.db.arguments.SetSearchField;
import com.mycollab.db.arguments.StringSearchField;
import com.mycollab.db.persistence.ICrudGenericDAO;
import com.mycollab.db.persistence.ISearchableDAO;
import com.mycollab.db.persistence.service.DefaultService;
import com.mycollab.module.billing.RegisterStatusConstants;
import com.mycollab.module.billing.service.BillingPlanCheckerService;
import com.mycollab.module.file.service.UserAvatarService;
import com.mycollab.module.user.dao.RolePermissionMapper;
import com.mycollab.module.user.dao.UserAccountMapper;
import com.mycollab.module.user.dao.UserMapper;
import com.mycollab.module.user.dao.UserMapperExt;
import com.mycollab.module.user.domain.*;
import com.mycollab.module.user.domain.criteria.UserSearchCriteria;
import com.mycollab.module.user.esb.DeleteUserEvent;
import com.mycollab.module.user.esb.NewUserJoinEvent;
import com.mycollab.module.user.esb.RequestToResetPasswordEvent;
import com.mycollab.module.user.esb.SendUserInvitationEvent;
import com.mycollab.module.user.service.UserService;
import com.mycollab.security.PermissionMap;
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 java.util.ArrayList;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * @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 BillingPlanCheckerService billingPlanCheckerService;

    @Autowired
    private AsyncEventBus asyncEventBus;

    @Autowired
    private IDeploymentMode deploymentMode;

    @Override
    public ICrudGenericDAO getCrudMapper() {
        return userMapper;
    }

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

    @Override
    public void saveUserAccount(User record, Integer roleId, String subDomain, Integer sAccountId,
            String inviteUser, boolean isSendInvitationEmail) {
        billingPlanCheckerService.validateAccountCanCreateNewUser(sAccountId);

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

        if (deploymentMode.isDemandEdition()) {
            userAccountEx.createCriteria().andUsernameEqualTo(record.getEmail()).andAccountidEqualTo(sAccountId)
                    .andRegisterstatusEqualTo(RegisterStatusConstants.ACTIVE);
        } else {
            userAccountEx.createCriteria().andUsernameEqualTo(record.getEmail())
                    .andRegisterstatusEqualTo(RegisterStatusConstants.ACTIVE);
        }

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

        String password = record.getPassword();
        if (password != null) {
            record.setPassword(EnDecryptHelper.encryptSaltPassword(password));
        }

        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) {
            userMapper.insert(record);
            userAvatarService.uploadDefaultAvatar(record.getUsername());
        }

        // save record in s_user_account table
        UserAccount userAccount = new UserAccount();
        userAccount.setAccountid(sAccountId);

        if (roleId != null && roleId > 0) {
            userAccount.setRoleid(roleId);
            userAccount.setIsaccountowner(false);
        } else {
            userAccount.setRoleid(null);
            userAccount.setIsaccountowner(true);
        }

        userAccount.setUsername(record.getUsername());
        userAccount.setRegisteredtime(new GregorianCalendar().getTime());
        userAccount.setLastaccessedtime(new GregorianCalendar().getTime());
        userAccount.setRegisterstatus(RegisterStatusConstants.NOT_LOG_IN_YET);
        userAccount.setInviteuser(inviteUser);

        userAccountEx = new UserAccountExample();
        if (deploymentMode.isDemandEdition()) {
            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 (isSendInvitationEmail) {
            SendUserInvitationEvent invitationEvent = new SendUserInvitationEvent(record.getUsername(), password,
                    inviteUser, subDomain, sAccountId);
            asyncEventBus.post(invitationEvent);
        }
    }

    @Override
    public Integer 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());
            Long numUsers = userMapper.countByExample(ex);
            if (numUsers > 0) {
                throw new UserInvalidInputException(String.format(
                        "Email %s is already existed in system. Please choose another email.", record.getEmail()));
            }
        }

        // 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) {
        SimpleUser oldUser = findUserByUserNameInAccount(record.getUsername(), sAccountId);
        if (oldUser != null) {
            if (Boolean.TRUE.equals(oldUser.getIsAccountOwner())
                    && Boolean.FALSE.equals(record.getIsAccountOwner())) {
                UserAccountExample userAccountEx = new UserAccountExample();
                userAccountEx.createCriteria().andAccountidEqualTo(sAccountId)
                        .andIsaccountownerEqualTo(Boolean.TRUE)
                        .andRegisterstatusEqualTo(RegisterStatusConstants.ACTIVE);
                if (userAccountMapper.countByExample(userAccountEx) <= 1) {
                    throw new UserInvalidInputException(String.format(
                            "Can not change role of user %s. The reason is "
                                    + "%s is the unique account owner of the current account.",
                            record.getUsername(), record.getUsername()));
                }
            }
        }

        if (!record.getUsername().equals(record.getEmail())) {
            UserExample ex = new UserExample();
            ex.createCriteria().andUsernameEqualTo(record.getEmail());
            Long numUsers = userMapper.countByExample(ex);
            if (numUsers > 0) {
                throw new UserInvalidInputException(String.format(
                        "Email %s is already existed in system. Please choose another email.", record.getEmail()));
            }
        }

        // 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.setIsaccountowner(false);
            }

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

    @Override
    public void massRemoveWithSession(List<User> users, String username, Integer accountId) {
        List<String> keys = new ArrayList<>();
        for (User user : users) {
            keys.add(user.getUsername());
        }
        userMapperExt.removeKeysWithSession(keys);
    }

    @Override
    public SimpleUser authentication(String username, String password, String subDomain,
            boolean isPasswordEncrypt) {
        UserSearchCriteria criteria = new UserSearchCriteria();
        criteria.setUsername(StringSearchField.and(username));
        criteria.setRegisterStatuses(
                new SetSearchField<>(RegisterStatusConstants.ACTIVE, RegisterStatusConstants.NOT_LOG_IN_YET));
        criteria.setSaccountid(null);

        if (deploymentMode.isDemandEdition()) {
            criteria.setSubdomain(StringSearchField.and(subDomain));
        }

        List<SimpleUser> users = findPageableListByCriteria(new BasicSearchRequest<>(criteria));
        if (CollectionUtils.isEmpty(users)) {
            throw new UserInvalidInputException(
                    String.format("User %s is not existed in this domain %s", username, subDomain));
        } else {
            SimpleUser user = null;
            if (deploymentMode.isDemandEdition()) {
                for (SimpleUser testUser : users) {
                    if (subDomain.equals(testUser.getSubdomain())) {
                        user = testUser;
                        break;
                    }
                }
                if (user == null) {
                    throw new UserInvalidInputException("Invalid username or password");
                }
            } else {
                user = users.get(0);
            }

            if (user.getPassword() == null
                    || !EnDecryptHelper.checkPassword(password, user.getPassword(), isPasswordEncrypt)) {
                throw new UserInvalidInputException("Invalid username or password");
            }

            if (RegisterStatusConstants.NOT_LOG_IN_YET.equals(user.getRegisterstatus())) {
                updateUserAccountStatus(user.getUsername(), user.getAccountId(), RegisterStatusConstants.ACTIVE);
                asyncEventBus.post(new NewUserJoinEvent(user.getUsername(), user.getAccountId()));
            }
            LOG.debug(String.format("User %s login to system successfully!", username));

            if (user.getIsAccountOwner() == null
                    || (user.getIsAccountOwner() != null && !user.getIsAccountOwner())) {
                if (user.getRoleid() != null) {
                    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(String.format("Find role match to user %s", username));
                    } else {
                        LOG.debug(String.format("We can not find any role associate to user %s", username));
                    }
                } else {
                    LOG.debug(String.format("User %s has no any role", username));
                }
            }
            user.setPassword(null);
            return user;
        }
    }

    @Override
    public SimpleUser findUserByUserNameInAccount(String username, Integer accountId) {
        return findUserInAccount(username, accountId);
    }

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

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

    @Override
    public void pendingUserAccount(String username, Integer accountId) {
        pendingUserAccounts(Collections.singletonList(username), accountId);
    }

    @Override
    public void pendingUserAccounts(List<String> usernames, Integer accountId) {
        // check if current user is the unique account owner, then reject deletion
        UserAccountExample userAccountEx = new UserAccountExample();
        userAccountEx.createCriteria().andUsernameNotIn(usernames).andAccountidEqualTo(accountId)
                .andIsaccountownerEqualTo(true).andRegisterstatusEqualTo(RegisterStatusConstants.ACTIVE);
        if (userAccountMapper.countByExample(userAccountEx) == 0) {
            throw new UserInvalidInputException(
                    "Can not delete users. The reason is there is no account owner in the rest users");
        }

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

        // notify users are "deleted"
        for (String username : usernames) {
            DeleteUserEvent event = new DeleteUserEvent(username, accountId);
            asyncEventBus.post(event);
        }
    }

    @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 int getTotalActiveUsersInAccount(Integer accountId) {
        UserSearchCriteria criteria = new UserSearchCriteria();
        criteria.setRegisterStatuses(new SetSearchField<>(RegisterStatusConstants.ACTIVE));
        criteria.setSaccountid(new NumberSearchField(accountId));
        return userMapperExt.getTotalCount(criteria);
    }

    @Override
    public void requestToResetPassword(String username) {
        asyncEventBus.post(new RequestToResetPasswordEvent(username));
    }
}