it.geosolutions.geostore.init.GeoStoreInit.java Source code

Java tutorial

Introduction

Here is the source code for it.geosolutions.geostore.init.GeoStoreInit.java

Source

/*
 *  Copyright (C) 2007 - 2012 GeoSolutions S.A.S.
 *  http://www.geo-solutions.it
 * 
 *  GPLv3 + Classpath exception
 * 
 *  This program 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.
 * 
 *  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package it.geosolutions.geostore.init;

import it.geosolutions.geostore.core.model.Category;
import it.geosolutions.geostore.core.model.User;
import it.geosolutions.geostore.core.model.UserGroup;
import it.geosolutions.geostore.core.security.password.GeoStoreAESEncoder;
import it.geosolutions.geostore.core.security.password.GeoStorePasswordEncoder;
import it.geosolutions.geostore.core.security.password.PwEncoder;
import it.geosolutions.geostore.init.model.InitUserList;
import it.geosolutions.geostore.services.CategoryService;
import it.geosolutions.geostore.services.UserGroupService;
import it.geosolutions.geostore.services.UserService;
import it.geosolutions.geostore.services.exception.BadRequestServiceEx;
import it.geosolutions.geostore.services.exception.NotFoundServiceEx;
import it.geosolutions.geostore.services.exception.ReservedUserGroupNameEx;
import it.geosolutions.geostore.services.rest.model.CategoryList;
import it.geosolutions.geostore.services.rest.model.RESTUserGroup;
import it.geosolutions.geostore.services.rest.model.UserGroupList;
import it.geosolutions.geostore.services.rest.utils.GeoStoreJAXBContext;

import java.io.File;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;

/**
 * 
 * @author ETj (etj at geo-solutions.it)
 */
public class GeoStoreInit implements InitializingBean {

    private final static Logger LOGGER = Logger.getLogger(GeoStoreInit.class);

    protected UserService userService;

    protected CategoryService categoryService;

    protected UserGroupService userGroupService;

    protected File userListInitFile = null;

    protected File categoryListInitFile = null;

    protected File userGroupListInitFile = null;

    /**
     * The password encoder to be set as default
     */
    protected GeoStorePasswordEncoder passwordEncoder = null;
    /**
     * If set to true, the recoding of the password is automatic
     */
    protected boolean allowPasswordRecoding = false;

    @Override
    public void afterPropertiesSet() throws Exception {

        LOGGER.info("===== Starting GeoStore services =====");
        //initialize password encoding
        initPasswordEncoding();
        long catCnt = categoryService.getCount(null);
        if (catCnt == 0) {
            LOGGER.warn("No category found.");
            if (categoryListInitFile != null) {
                LOGGER.warn("Initializing categories from file " + categoryListInitFile);
                initCategories(categoryListInitFile);
            } else {
                LOGGER.info("No category initializer defined.");
            }
        } else {
            LOGGER.info("Categories already in db: " + catCnt);
        }

        long userGroupCnt = userGroupService.getAll(null, null).size();
        if (userGroupCnt == 0) {
            LOGGER.warn("No usersgroup found.");
            if (userGroupListInitFile != null) {
                LOGGER.warn("Initializing users from file " + userGroupListInitFile);
                initUsersGroup(userGroupListInitFile);
            } else {
                LOGGER.info("No usersgroup initializer defined.");
            }
        } else {
            LOGGER.info("UsersGroup already in db: " + userGroupCnt);

        }

        long userCnt = userService.getCount(null);
        if (userCnt == 0) {
            LOGGER.warn("No user found.");
            if (userListInitFile != null) {
                LOGGER.warn("Initializing users from file " + userListInitFile);
                initUsers(userListInitFile);
            } else {
                LOGGER.info("No user initializer defined.");
            }
        } else {
            LOGGER.info("Users already in db: " + userCnt);
        }
    }

    private void initPasswordEncoding() {
        LOGGER.info("=== Set up the security system   ====");
        LOGGER.info("Encoding Type:" + passwordEncoder.getEncodingType());

        PwEncoder.setEncoder(this.passwordEncoder);
        //check and convert passwords
        try {
            List<User> users = userService.getAll(0, 1);
            if (users != null && users.size() > 0) {
                //check password encription of the first user availabe
                boolean responsible = this.passwordEncoder.isResponsibleForEncoding(users.get(0).getPassword());

                //if the current password encoder is the responsible for the encoding of the password 
                //we suppose the conversion is already happended
                if (responsible)
                    return;
                LOGGER.warn(
                        "=======================================================================================");
                LOGGER.warn(
                        "   WARNING: USERS PASSWORDS ARE NOT SYNCRONIZED WITH THE CONFIGURED PASSWORD ENCODER   ");
                LOGGER.warn(
                        "=======================================================================================");
                //check if the password is old legacy, so GeoStoreAESEncoder is the responsible for the encoding
                GeoStoreAESEncoder e = new GeoStoreAESEncoder();
                boolean isLegacy = e.isResponsibleForEncoding(users.get(0).getPassword());
                if (isLegacy) {
                    if (!allowPasswordRecoding) {
                        LOGGER.warn(
                                "To convert old passwords to new ones use geostoreInitializer.allowPasswordRecoding=true");
                        return;
                    }
                    LOGGER.info("Starting password conversion...");
                    for (User u : userService.getAll(null, null)) {
                        String p = u.getPassword();
                        if (e.isResponsibleForEncoding(p)) {
                            String dec = e.decode(p);
                            String enc = this.passwordEncoder.encodePassword(dec.toCharArray(), null);
                            u.setPassword(enc);
                            try {
                                userService.update(u);
                                LOGGER.info("UPDATED USER PASSWORD for the user:" + u.getName());
                            } catch (NotFoundServiceEx e1) {
                                LOGGER.error("===> ERROR updating user password for user" + u.getName());

                            }
                        }
                    }
                    LOGGER.info("Password conversion finished!");
                }

            }
        } catch (BadRequestServiceEx e) {
            //error getting users is not a problem at this stage.
            //e.printStackTrace();
        }
    }

    private void initCategories(File file) {
        try {
            JAXBContext context = GeoStoreJAXBContext.getContext();
            CategoryList list = (CategoryList) context.createUnmarshaller().unmarshal(file);
            for (Category item : list.getList()) {
                LOGGER.info("Adding category " + item);
                categoryService.insert(item);
            }
        } catch (JAXBException ex) {
            throw new RuntimeException("Error reading categories init file " + file, ex);
        } catch (Exception e) {
            LOGGER.error("Error while initting categories. Rolling back.", e);
            List<Category> removeList;
            try {
                removeList = categoryService.getAll(null, null);
            } catch (BadRequestServiceEx ex) {
                throw new RuntimeException(
                        "Error while rolling back categories initialization. Your DB may now contain an incomplete category list. Please check manually.",
                        e);
            }

            for (Category cat : removeList) {
                categoryService.delete(cat.getId());
            }

            throw new RuntimeException("Error while initting categories.");
        }

    }

    private void initUsers(File file) {
        try {
            userService.insertSpecialUsers();
            JAXBContext context = getUserContext();

            InitUserList list = (InitUserList) context.createUnmarshaller().unmarshal(file);
            for (User user : list.getList()) {
                LOGGER.info("Adding user " + user);
                userService.insert(user);
            }
        } catch (JAXBException ex) {
            throw new RuntimeException("Error reading users init file " + file, ex);
        } catch (Exception e) {
            LOGGER.error("Error while initting users. Rolling back.", e);
            List<User> removeList;
            try {
                removeList = userService.getAll(null, null);
            } catch (BadRequestServiceEx ex) {
                throw new RuntimeException(
                        "Error while rolling back user initialization. Your DB may now contain an incomplete user list. Please check manually.",
                        e);
            }

            for (User user : removeList) {
                userService.delete(user.getId());
            }

            throw new RuntimeException("Error while initting users.");
        }
    }

    private void initUsersGroup(File file) throws NotFoundServiceEx, BadRequestServiceEx {
        try {
            userGroupService.insertSpecialUsersGroups();
            JAXBContext context = GeoStoreJAXBContext.getContext();
            UserGroupList list = (UserGroupList) context.createUnmarshaller().unmarshal(file);
            for (RESTUserGroup userGroup : list.getUserGroupList()) {
                LOGGER.info("Adding user group " + userGroup);
                UserGroup ug = new UserGroup();
                ug.setGroupName(userGroup.getGroupName());
                ug.setDescription(userGroup.getDescription());
                try {
                    userGroupService.insert(ug);
                } catch (ReservedUserGroupNameEx e) {
                    // If  a reserved username is in the init usergroup file log the exception and skip this insertion
                    LOGGER.warn(e.getMessage());
                }
            }
        } catch (JAXBException ex) {
            throw new RuntimeException("Error reading usersgroup init file " + file, ex);
        } catch (Exception e) {
            LOGGER.error("Error while initting usersgroups. Rolling back.", e);
            List<UserGroup> removeList;
            try {
                removeList = userGroupService.getAll(null, null);
            } catch (BadRequestServiceEx ex) {
                throw new RuntimeException(
                        "Error while rolling back usergroup initialization. Your DB may now contain an incomplete usergroup list. Please check manually.",
                        e);
            }
            for (UserGroup ug : removeList) {
                userGroupService.delete(ug.getId());
            }
            throw new RuntimeException("Error while initting usersgroup.");
        }
    }

    private static JAXBContext getUserContext() {

        List<Class> allClasses = GeoStoreJAXBContext.getGeoStoreClasses();
        allClasses.add(InitUserList.class);

        if (LOGGER.isDebugEnabled())
            LOGGER.debug("Initializing JAXBContext with " + allClasses.size() + " classes " + allClasses);

        try {
            return JAXBContext.newInstance(allClasses.toArray(new Class[allClasses.size()]));
        } catch (JAXBException ex) {
            LOGGER.error("Can't create GeoStore context: " + ex.getMessage(), ex);
            return null;
        }
    }

    // ==========================================================================

    public void setUserListInitFile(File userListInitFile) {
        this.userListInitFile = userListInitFile;
    }

    public void setCategoryListInitFile(File categoryListInitFile) {
        this.categoryListInitFile = categoryListInitFile;
    }

    public void setUserGroupListInitFile(File userGroupListInitFile) {
        this.userGroupListInitFile = userGroupListInitFile;
    }

    // ==========================================================================

    public void setCategoryService(CategoryService categoryService) {
        this.categoryService = categoryService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void setUserGroupService(UserGroupService userGroupService) {
        this.userGroupService = userGroupService;
    }

    // ==========================================================================

    public GeoStorePasswordEncoder getPasswordEncoder() {
        return passwordEncoder;
    }

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

    // ===========================================================================
    public boolean isAllowPasswordRecoding() {
        return allowPasswordRecoding;
    }

    public void setAllowPasswordRecoding(boolean allowPasswordRecoding) {
        this.allowPasswordRecoding = allowPasswordRecoding;
    }

}