com.samples.platform.core.security.UserProvider.java Source code

Java tutorial

Introduction

Here is the source code for com.samples.platform.core.security.UserProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2013, 2014, 2015 QPark Consulting  S.a r.l.
 * 
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0. 
 * The Eclipse Public License is available at 
 * http://www.eclipse.org/legal/epl-v10.html.
 ******************************************************************************/
package com.samples.platform.core.security;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;

import com.qpark.eip.core.ReInitalizeable;
import com.qpark.eip.core.spring.ApplicationPlaceholderConfigurer;
import com.qpark.eip.core.spring.security.EipUserProvider;

/**
 * The {@link UserProvider} read the user name and roles assignments out of the
 * applications properties. These are normally stored in the templates
 * <i>bus.app.xxx-user.properties</i> file and loaded into the
 * {@link ApplicationPlaceholderConfigurer}.
 * <p/>
 * Properties starting with <i>bus.user.definition.xxx</i> defining the user
 * with key <code>xxx</code>. The user name property ends with <i>userName</i>,
 * the password with <i>password</i>. The properties containing the roles
 * assignments contain a <i>.role.</i> in their name. The following example
 * shows the user definition of user with key <code>xxx</code> having the name
 * <i>nameOfUserA</i>.
 *
 * <pre>
 * bus.user.definition.xxx.userName=nameOfUserA
 * bus.user.definition.xxx.password=password
 * bus.user.definition.xxx.role.0=ROLE_GET_USER
 * bus.user.definition.xxx.role.1=ROLE_COMMON
 * bus.user.definition.xxx.role.2=ROLE_READ
 * </pre>
 *
 * The user <code>nameOfUserA</code> has to authenticate with password
 * <code>password</code> and get the authority to get user, do all things
 * in service common and to access all read operations of all services.
 * @author bhausen
 */
public class UserProvider implements EipUserProvider, ReInitalizeable {
    /** The container having the user data out of the parsed properties. */
    static class UserDefinition {
        /** The key of the user. */
        private final String key;
        /** The name of the user. */
        private String name;
        /** The password of the user. */
        private String password = "";
        /** The set containing the roles of the user. */
        private final TreeSet<String> rolenames = new TreeSet<String>();

        /**
         * Create a {@link UserDefinition} with the key.
         * @param key
         */
        UserDefinition(final String key) {
            this.key = key;
        }

        /**
         * Add the role to the set of role names the user is assigned to .
         * @param rolename the role name to add.
         */
        public void addRolename(final String rolename) {
            if (rolename.startsWith("ROLE_")) {
                this.rolenames.add(rolename);
            }
        }

        /**
         * Get the key of the user.
         * @return the key.
         */
        public String getKey() {
            return this.key;
        }

        /**
         * Get the name of the user.
         * @return the name.
         */
        public String getName() {
            return this.name;
        }

        /**
         * Get the password of the user.
         * @return the password.
         */
        public String getPassword() {
            return this.password;
        }

        /**
         * Get the list of {@link GrantedAuthority} containing the roles of the
         * user.
         * @return the list of {@link GrantedAuthority}.
         */
        public List<GrantedAuthority> getRoles() {
            List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
            for (String rolename : this.rolenames) {
                roles.add(new SimpleGrantedAuthority(rolename));
            }
            return roles;
        }

        /**
         * Set the name of the user.
         * @param name the name of the user.
         */
        public void setName(final String name) {
            this.name = name;
        }

        /**
         * Set the password of the user.
         * @param password the password of the user.
         */
        public void setPassword(final String password) {
            this.password = password;
        }

        /**
         * Get the size of the list of roles of the user.
         * @return the number of roles of the user.
         */
        public int size() {
            return this.rolenames.size();
        }

        /**
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            StringBuffer sb = new StringBuffer(512);
            sb.append("User \"").append(this.name).append("\" with roles ");
            int i = 0;
            for (String rolename : this.rolenames) {
                if (i > 0) {
                    sb.append(", ");
                }
                sb.append(rolename);
                i++;
            }
            return sb.toString();
        }
    }

    /**
     * Get the user definition key out of the property name (<code>xxx</code> in
     * the example).
     * @param propertyName The property name.
     * @return the user name key part.
     */
    private static String extractUser(final String propertyName) {
        String userName = "";
        userName = propertyName.substring(BUS_PROPERTY_NAME_START.length(), propertyName.length());
        userName = userName.substring(0, userName.indexOf('.'));
        return userName;
    }

    /** The {@link Logger}. */
    private final Logger logger = LoggerFactory.getLogger(UserProvider.class);

    /** The {@link ApplicationPlaceholderConfigurer}. */
    @Autowired
    private ApplicationPlaceholderConfigurer properties;

    /** The start of all user definition property names. */
    private static final String BUS_PROPERTY_NAME_START = "bus.user.definition.";
    /** The name of the anonymous role. */
    public static final String ROLE_ANONYMOUS = "ROLE_ANONYMOUS";
    /** The name of the common role. */
    public static final String ROLE_COMMON = "ROLE_COMMON";
    /** The map containing the User objects of the application. */
    private final Map<String, User> userMap = new HashMap<String, User>();

    /**
     * Read the user definitions out of the properties and put the into the map
     * {@link UserProvider#userMap}.
     */
    public void createUsers() {
        this.logger.trace("+createUsers");
        /* Create an _sorted_ map containing all user definition properties. */
        TreeMap<String, String> userDefinitionProperties = new TreeMap<String, String>();
        for (Map.Entry<String, String> entry : this.properties.getProperties().entrySet()) {
            if (entry.getKey() != null && entry.getKey().startsWith(BUS_PROPERTY_NAME_START)) {
                userDefinitionProperties.put(entry.getKey(), entry.getValue());
            }
        }

        /* Create a map of UserDefinitions parsed out of the properties. */
        HashMap<String, UserDefinition> parsedUserDefinitions = new HashMap<String, UserProvider.UserDefinition>();
        UserDefinition userDefinition = null;
        String userKey = null;
        for (Map.Entry<String, String> userDefinitionProperty : userDefinitionProperties.entrySet()) {
            /* Get the user key out of the property name. */
            userKey = extractUser(userDefinitionProperty.getKey());
            if (userDefinition == null || !userDefinition.getKey().equals(userKey)) {
                /* New user key extracted out of the property name. */
                if (userDefinition != null) {
                    /* Previous UserDefinition finished. Put it into the map. */
                    parsedUserDefinitions.put(userDefinition.getName(), userDefinition);
                }
                /* Create the actual UserDefinition with the user key. */
                userDefinition = new UserDefinition(userKey);
            }
            /* Setup the content of the property into the UserDefinition. */
            if (userDefinitionProperty.getKey().endsWith("userName")) {
                userDefinition.setName(userDefinitionProperty.getValue());
            } else if (userDefinitionProperty.getKey().endsWith("password")) {
                userDefinition.setPassword(userDefinitionProperty.getValue());
            } else if (userDefinitionProperty.getKey().contains(".role.")) {
                if (userDefinitionProperty.getValue() != null
                        && !userDefinitionProperty.getValue().equals(ROLE_ANONYMOUS)) {
                    userDefinition.addRolename(userDefinitionProperty.getValue());
                }
            }
        }
        /* Put the last UserDefinition to the map of parsedUserDefinitions. */
        if (userDefinition != null && userDefinition.getName() != null) {
            parsedUserDefinitions.put(userDefinition.getName(), userDefinition);
        }

        /*
         * Update the userMap. If the userName of the userMap is not part of the
         * parsedUserDefinitions any more, the user is removed out of the
         * userMap.
         */
        List<String> keyList = new ArrayList<String>(this.userMap.size());
        Collections.addAll(keyList, this.userMap.keySet().toArray(new String[this.userMap.keySet().size()]));
        for (String userName : keyList) {
            userDefinition = parsedUserDefinitions.get(userName);
            if (!parsedUserDefinitions.containsKey(userName)) {
                this.userMap.remove(userName);
            }
        }
        /*
         * All UserDefinitions out of the parsedUserDefinitions are mapped to a
         * User and put into the userMap.
         */
        for (UserDefinition ud : parsedUserDefinitions.values()) {
            this.userMap.put(ud.getName(), this.getUser(ud));
        }
        this.logger.trace("-createUsers");
    }

    /**
     * @see com.qpark.eip.core.spring.security.EipUserProvider#getUser(java.lang.String)
     */
    @Override
    public User getUser(final String username) {
        if (this.userMap.size() == 0) {
            this.createUsers();
        }
        return this.userMap.get(username);
    }

    /**
     * Add the user from the userDefinition to the map.
     * @param userDefinition
     */
    private User getUser(final UserDefinition userDefinition) {
        /* Only if the userdefinition contains roles add ROLE_COMMON. */
        /* ROLE_COMMON is not automatically added any more. */
        // if (userDefinition.size() > 0) {
        // userDefinition.addRolename(ROLE_COMMON);
        // }
        userDefinition.addRolename(ROLE_ANONYMOUS);
        boolean enabled = true;
        boolean accountNonExpired = true;
        boolean credentialsNonExpired = true;
        boolean accountNonLocked = true;
        User user = new PlatformUser(userDefinition.getName(), userDefinition.getPassword(), enabled,
                accountNonExpired, credentialsNonExpired, accountNonLocked, userDefinition.getRoles());
        this.logger.info("Created: {}", userDefinition.toString());
        return user;
    }

    /**
     * @see com.qpark.eip.core.ReInitalizeable#reInitalize()
     */
    @Override
    public void reInitalize() {
        this.logger.debug("+reInitalize: Setup the userMap ({})", this.userMap.size());
        this.createUsers();
        this.logger.debug("-reInitalize: Setup the userMap ({})", this.userMap.size());
    }
}