fr.paris.lutece.plugins.mylutece.modules.database.authentication.service.ImportDatabaseUserService.java Source code

Java tutorial

Introduction

Here is the source code for fr.paris.lutece.plugins.mylutece.modules.database.authentication.service.ImportDatabaseUserService.java

Source

/*
 * Copyright (c) 2002-2014, Mairie de Paris
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice
 *     and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright notice
 *     and the following disclaimer in the documentation and/or other materials
 *     provided with the distribution.
 *
 *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * License 1.0
 */
package fr.paris.lutece.plugins.mylutece.modules.database.authentication.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import fr.paris.lutece.plugins.mylutece.business.attribute.AttributeHome;
import fr.paris.lutece.plugins.mylutece.business.attribute.IAttribute;
import fr.paris.lutece.plugins.mylutece.business.attribute.MyLuteceUserField;
import fr.paris.lutece.plugins.mylutece.business.attribute.MyLuteceUserFieldHome;
import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseHome;
import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseUser;
import fr.paris.lutece.plugins.mylutece.modules.database.authentication.business.DatabaseUserHome;
import fr.paris.lutece.plugins.mylutece.modules.database.authentication.service.parameter.DatabaseUserParameterService;
import fr.paris.lutece.plugins.mylutece.service.MyLutecePlugin;
import fr.paris.lutece.plugins.mylutece.service.attribute.MyLuteceUserFieldListenerService;
import fr.paris.lutece.plugins.mylutece.service.attribute.MyLuteceUserFieldService;
import fr.paris.lutece.plugins.mylutece.util.SecurityUtils;
import fr.paris.lutece.portal.service.csv.CSVMessageDescriptor;
import fr.paris.lutece.portal.service.csv.CSVMessageLevel;
import fr.paris.lutece.portal.service.csv.CSVReaderService;
import fr.paris.lutece.portal.service.i18n.I18nService;
import fr.paris.lutece.portal.service.mail.MailService;
import fr.paris.lutece.portal.service.plugin.Plugin;
import fr.paris.lutece.portal.service.plugin.PluginService;
import fr.paris.lutece.portal.service.spring.SpringContextService;
import fr.paris.lutece.portal.service.template.AppTemplateService;
import fr.paris.lutece.portal.service.util.AppLogService;
import fr.paris.lutece.portal.service.util.AppPathService;
import fr.paris.lutece.portal.service.util.AppPropertiesService;
import fr.paris.lutece.util.html.HtmlTemplate;

/**
 * Import database users from a CSV file
 */
public class ImportDatabaseUserService extends CSVReaderService {
    private static final String MESSAGE_NO_STATUS = "module.mylutece.database.import_users_from_file.importNoStatus";
    private static final String MESSAGE_ACCESS_CODE_ALREADY_USED = "module.mylutece.database.message.user_exist";
    private static final String MESSAGE_EMAIL_ALREADY_USED = "module.mylutece.database.message.user_exist";
    private static final String MESSAGE_USERS_IMPORTED = "module.mylutece.database.import_users_from_file.usersImported";
    private static final String MESSAGE_ERROR_MIN_NUMBER_COLUMNS = "module.mylutece.database.import_users_from_file.messageErrorMinColumnNumber";
    private static final String MESSAGE_ACCOUNT_IMPORTED_MAIL_SUBJECT = "module.mylutece.database.import_users_from_file.email.mailSubject";
    private static final String MESSAGE_ERROR_IMPORTING_ATTRIBUTES = "module.mylutece.database.import_users_from_file.errorImportingAttributes";
    private static final String PROPERTY_NO_REPLY_EMAIL = "mail.noreply.email";
    private static final String PROPERTY_IMPORT_EXPORT_USER_SEPARATOR = "lutece.importExportUser.defaultSeparator";
    private static final String PROPERTY_SITE_NAME = "lutece.name";
    private static final String TEMPLATE_MAIL_USER_IMPORTED = "admin/plugins/mylutece/modules/database/mail_user_imported.html";
    private static final String MARK_SITE_NAME = "site_name";
    private static final String MARK_USER = "user";
    private static final String MARK_SITE_LINK = "site_link";
    private static final String MARK_PASSWORD = "password";
    private static final String CONSTANT_DEFAULT_IMPORT_EXPORT_USER_SEPARATOR = ":";
    private static final String CONSTANT_ROLE = "role";
    private static final String CONSTANT_GROUP = "group";
    private static final int CONSTANT_MINIMUM_COLUMNS_PER_LINE = 7;
    private Character _strAttributesSeparator;
    private boolean _bUpdateExistingUsers;
    private DatabaseUserParameterService _userParamService = DatabaseUserParameterService.getService();

    /**
     * {@inheritDoc}
     */
    @Override
    protected List<CSVMessageDescriptor> readLineOfCSVFile(String[] strLineDataArray, int nLineNumber,
            Locale locale, String strBaseUrl) {
        Plugin databasePlugin = PluginService.getPlugin(DatabasePlugin.PLUGIN_NAME);
        Plugin mylutecePlugin = PluginService.getPlugin(MyLutecePlugin.PLUGIN_NAME);
        List<CSVMessageDescriptor> listMessages = new ArrayList<CSVMessageDescriptor>();
        int nIndex = 0;

        String strAccessCode = strLineDataArray[nIndex++];
        String strLastName = strLineDataArray[nIndex++];
        String strFirstName = strLineDataArray[nIndex++];
        String strEmail = strLineDataArray[nIndex++];

        boolean bUpdateUser = getUpdateExistingUsers();
        int nUserId = 0;

        if (bUpdateUser) {
            int nAccessCodeUserId = DatabaseUserHome.findDatabaseUserIdFromLogin(strAccessCode, databasePlugin);

            if (nAccessCodeUserId > 0) {
                nUserId = nAccessCodeUserId;
            }

            bUpdateUser = nUserId > 0;
        }

        String strStatus = strLineDataArray[nIndex++];
        int nStatus = 0;

        if (StringUtils.isNotEmpty(strStatus) && StringUtils.isNumeric(strStatus)) {
            nStatus = Integer.parseInt(strStatus);
        } else {
            Object[] args = { strLastName, strFirstName, nStatus };
            String strMessage = I18nService.getLocalizedString(MESSAGE_NO_STATUS, args, locale);
            CSVMessageDescriptor message = new CSVMessageDescriptor(CSVMessageLevel.INFO, nLineNumber, strMessage);
            listMessages.add(message);
        }

        // We ignore the password max valid date attribute because we changed the password.
        // String strPasswordMaxValidDate = strLineDataArray[nIndex++];
        nIndex++;
        // We ignore the account max valid date attribute
        // String strAccountMaxValidDate = strLineDataArray[nIndex++];
        nIndex++;

        DatabaseUser user = new DatabaseUser();

        user.setLogin(strAccessCode);
        user.setLastName(strLastName);
        user.setFirstName(strFirstName);
        user.setEmail(strEmail);
        user.setStatus(nStatus);

        if (bUpdateUser) {
            user.setUserId(nUserId);
            // We update the user
            DatabaseService.getService().doUpdateUser(user, databasePlugin);
        } else {
            // We create the user
            String strPassword = SecurityUtils.makePassword(_userParamService, databasePlugin);
            DatabaseService.getService().doCreateUser(user, strPassword, databasePlugin);
            notifyUserAccountCreated(user, strPassword, locale, AppPathService.getProdUrl(strBaseUrl));
        }

        // We remove old roles, groups and attributes of the user
        DatabaseHome.removeRolesForUser(user.getUserId(), databasePlugin);
        DatabaseHome.removeGroupsForUser(user.getUserId(), databasePlugin);
        MyLuteceUserFieldService.doRemoveUserFields(user.getUserId(), locale);

        // We get every attributes, roles and groups of the user
        Map<Integer, List<String>> mapAttributesValues = new HashMap<Integer, List<String>>();
        List<String> listRoles = new ArrayList<String>();
        List<String> listGroups = new ArrayList<String>();

        while (nIndex < strLineDataArray.length) {
            String strValue = strLineDataArray[nIndex];

            if (StringUtils.isNotBlank(strValue) && (strValue.indexOf(getAttributesSeparator()) > 0)) {
                int nSeparatorIndex = strValue.indexOf(getAttributesSeparator());
                String strLineId = strValue.substring(0, nSeparatorIndex);

                if (StringUtils.isNotBlank(strLineId)) {
                    if (StringUtils.equalsIgnoreCase(strLineId, CONSTANT_ROLE)) {
                        listRoles.add(strValue.substring(nSeparatorIndex + 1));
                    } else if (StringUtils.equalsIgnoreCase(strLineId, CONSTANT_GROUP)) {
                        listGroups.add(strValue.substring(nSeparatorIndex + 1));
                    } else {
                        int nAttributeId = Integer.parseInt(strLineId);

                        String strAttributeValue = strValue.substring(nSeparatorIndex + 1);
                        List<String> listValues = mapAttributesValues.get(nAttributeId);

                        if (listValues == null) {
                            listValues = new ArrayList<String>();
                        }

                        listValues.add(strAttributeValue);
                        mapAttributesValues.put(nAttributeId, listValues);
                    }
                }
            }

            nIndex++;
        }

        // We create roles
        for (String strRole : listRoles) {
            DatabaseHome.addRoleForUser(user.getUserId(), strRole, databasePlugin);
        }

        // We create groups
        for (String strGoup : listGroups) {
            DatabaseHome.addGroupForUser(user.getUserId(), strGoup, databasePlugin);
        }

        // We save the attributes found
        List<IAttribute> listAttributes = AttributeHome.findAll(locale, mylutecePlugin);

        for (IAttribute attribute : listAttributes) {
            List<String> listValues = mapAttributesValues.get(attribute.getIdAttribute());

            if ((listValues != null) && (listValues.size() > 0)) {
                int nIdField = 0;
                boolean bMyLuteceAttribute = (attribute.getPlugin() == null)
                        || StringUtils.equals(attribute.getPlugin().getName(), MyLutecePlugin.PLUGIN_NAME);

                for (String strValue : listValues) {
                    int nSeparatorIndex = strValue.indexOf(getAttributesSeparator());

                    if (nSeparatorIndex >= 0) {
                        nIdField = 0;

                        try {
                            nIdField = Integer.parseInt(strValue.substring(0, nSeparatorIndex));
                        } catch (NumberFormatException e) {
                            nIdField = 0;
                        }

                        strValue = strValue.substring(nSeparatorIndex + 1);
                    } else {
                        nIdField = 0;
                    }

                    String[] strValues = { strValue };

                    try {
                        List<MyLuteceUserField> listUserFields = attribute.getUserFieldsData(strValues,
                                user.getUserId());

                        for (MyLuteceUserField userField : listUserFields) {
                            if (userField != null) {
                                userField.getAttributeField().setIdField(nIdField);
                                MyLuteceUserFieldHome.create(userField, mylutecePlugin);
                            }
                        }

                        if (!bMyLuteceAttribute) {
                            for (MyLuteceUserFieldListenerService myLuteceUserFieldListenerService : SpringContextService
                                    .getBeansOfType(MyLuteceUserFieldListenerService.class)) {
                                myLuteceUserFieldListenerService.doCreateUserFields(user.getUserId(),
                                        listUserFields, locale);
                            }
                        }
                    } catch (Exception e) {
                        AppLogService.error(e.getMessage(), e);

                        String strErrorMessage = I18nService.getLocalizedString(MESSAGE_ERROR_IMPORTING_ATTRIBUTES,
                                locale);
                        CSVMessageDescriptor error = new CSVMessageDescriptor(CSVMessageLevel.ERROR, nLineNumber,
                                strErrorMessage);
                        listMessages.add(error);
                    }
                }
            }
        }

        return listMessages;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected List<CSVMessageDescriptor> checkLineOfCSVFile(String[] strLineDataArray, int nLineNumber,
            Locale locale) {
        int nMinColumnNumber = CONSTANT_MINIMUM_COLUMNS_PER_LINE;
        Plugin databasePlugin = PluginService.getPlugin(DatabasePlugin.PLUGIN_NAME);
        List<CSVMessageDescriptor> listMessages = new ArrayList<CSVMessageDescriptor>();

        if ((strLineDataArray == null) || (strLineDataArray.length < nMinColumnNumber)) {
            int nNbCol;

            if (strLineDataArray == null) {
                nNbCol = 0;
            } else {
                nNbCol = strLineDataArray.length;
            }

            Object[] args = { nNbCol, nMinColumnNumber };
            String strErrorMessage = I18nService.getLocalizedString(MESSAGE_ERROR_MIN_NUMBER_COLUMNS, args, locale);
            CSVMessageDescriptor error = new CSVMessageDescriptor(CSVMessageLevel.ERROR, nLineNumber,
                    strErrorMessage);
            listMessages.add(error);

            return listMessages;
        }

        if (!getUpdateExistingUsers()) {
            String strAccessCode = strLineDataArray[0];
            String strEmail = strLineDataArray[3];

            if (DatabaseUserHome.findDatabaseUserIdFromLogin(strAccessCode, databasePlugin) > 0) {
                String strMessage = I18nService.getLocalizedString(MESSAGE_ACCESS_CODE_ALREADY_USED, locale);
                CSVMessageDescriptor error = new CSVMessageDescriptor(CSVMessageLevel.ERROR, nLineNumber,
                        strMessage);
                listMessages.add(error);
            } else {
                Collection<DatabaseUser> listUsers = DatabaseUserHome.findDatabaseUsersListForEmail(strEmail,
                        databasePlugin);

                if ((listUsers != null) && (listUsers.size() > 0)) {
                    String strMessage = I18nService.getLocalizedString(MESSAGE_EMAIL_ALREADY_USED, locale);
                    CSVMessageDescriptor error = new CSVMessageDescriptor(CSVMessageLevel.ERROR, nLineNumber,
                            strMessage);
                    listMessages.add(error);
                }
            }
        }

        return listMessages;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected List<CSVMessageDescriptor> getEndOfProcessMessages(int nNbLineParses, int nNbLinesWithoutErrors,
            Locale locale) {
        List<CSVMessageDescriptor> listMessages = new ArrayList<CSVMessageDescriptor>();
        Object[] args = { nNbLineParses, nNbLinesWithoutErrors };
        String strMessageContent = I18nService.getLocalizedString(MESSAGE_USERS_IMPORTED, args, locale);
        CSVMessageDescriptor message = new CSVMessageDescriptor(CSVMessageLevel.INFO, 0, strMessageContent);
        listMessages.add(message);

        return listMessages;
    }

    /**
     * Notify a user of the creation of his account and give him his credentials
     * @param user the user to notify
     * @param strPassword The password of the user
     * @param locale The locale
     * @param strProdUrl The prod URL
     */
    private void notifyUserAccountCreated(DatabaseUser user, String strPassword, Locale locale, String strProdUrl) {
        String strSenderEmail = AppPropertiesService.getProperty(PROPERTY_NO_REPLY_EMAIL);
        String strSiteName = AppPropertiesService.getProperty(PROPERTY_SITE_NAME);

        String strEmailSubject = I18nService.getLocalizedString(MESSAGE_ACCOUNT_IMPORTED_MAIL_SUBJECT,
                new String[] { strSiteName }, locale);
        String strBaseURL = strProdUrl;
        Map<String, Object> model = new HashMap<String, Object>();
        model.put(MARK_USER, user);
        model.put(MARK_SITE_NAME, strSiteName);
        model.put(MARK_SITE_LINK, MailService.getSiteLink(strBaseURL, true));
        model.put(MARK_PASSWORD, strPassword);

        HtmlTemplate template = AppTemplateService.getTemplate(TEMPLATE_MAIL_USER_IMPORTED, locale, model);

        MailService.sendMailHtml(user.getEmail(), strSenderEmail, strSenderEmail, strEmailSubject,
                template.getHtml());
    }

    /**
     * Get the separator used for attributes of admin users.
     * @return The separator
     */
    public Character getAttributesSeparator() {
        if (_strAttributesSeparator == null) {
            _strAttributesSeparator = AppPropertiesService.getProperty(PROPERTY_IMPORT_EXPORT_USER_SEPARATOR,
                    CONSTANT_DEFAULT_IMPORT_EXPORT_USER_SEPARATOR).charAt(0);
        }

        return _strAttributesSeparator;
    }

    /**
     * Get the update users flag
     * @return True if existing users should be updated, false if they should be
     *         ignored.
     */
    public boolean getUpdateExistingUsers() {
        return _bUpdateExistingUsers;
    }

    /**
     * Set the update users flag
     * @param bUpdateExistingUsers True if existing users should be updated,
     *            false if they should be ignored.
     */
    public void setUpdateExistingUsers(boolean bUpdateExistingUsers) {
        this._bUpdateExistingUsers = bUpdateExistingUsers;
    }
}