Package org.geoserver.security

Source Code of org.geoserver.security.GeoserverUserDao

/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.geoserver.security;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.userdetails.User;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.userdetails.memory.UserAttribute;
import org.acegisecurity.userdetails.memory.UserAttributeEditor;
import org.geoserver.config.GeoServer;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.platform.GeoServerExtensions;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.vfny.geoserver.global.ConfigurationException;
import org.vfny.geoserver.global.GeoserverDataDirectory;

/**
* A simple DAO reading/writing the user's property files
*
* @author Andrea Aime - OpenGeo
*
*/
public class GeoserverUserDao implements UserDetailsService {
    /** logger */
    static Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geoserver.security");

    TreeMap<String, User> userMap;

    PropertyFileWatcher userDefinitionsFile;
   
    File securityDir;

    GeoServer geoServer;
   
    /**
     * Returns the {@link GeoserverUserDao} instance registered in the GeoServer Spring context
     */
    public static GeoserverUserDao get() {
        return GeoServerExtensions.bean(GeoserverUserDao.class);
    }
   
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,
            DataAccessException {
        checkUserMap();

        UserDetails user = userMap.get(username);
        if (user == null)
            throw new UsernameNotFoundException("Could not find user: " + username);

        return user;
    }

    /**
     * Either loads the default property file on the first access, or reloads it if it has been
     * modified since last access.
     *
     * @throws DataAccessResourceFailureException
     */
    void checkUserMap() throws DataAccessResourceFailureException {
        InputStream is = null;
        OutputStream os = null;
        if ((userMap == null) || ((userDefinitionsFile != null) && userDefinitionsFile.isStale())) {
            try {
                if (userDefinitionsFile == null) {
                    File propFile = new File(securityDir, "users.properties");

                    if (!propFile.exists()) {
                        // we're probably dealing with an old data dir, create
                        // the file without
                        // changing the username and password if possible
                        Properties p = new Properties();
                        GeoServerInfo global = geoServer.getGlobal();
                        if ((geoServer != null) && (global.getAdminUsername() != null)
                                && !global.getAdminUsername().trim().equals("")) {
                            p.put(global.getAdminUsername(), global.getAdminPassword()
                                    + ",ROLE_ADMINISTRATOR");
                        } else {
                            p.put("admin", "geoserver,ROLE_ADMINISTRATOR");
                        }

                        os = new FileOutputStream(propFile);
                        p.store(os, "Format: name=password,ROLE1,...,ROLEN");
                        os.close();

                        // setup a sample service.properties
                        File serviceFile = new File(securityDir, "service.properties");
                        os = new FileOutputStream(serviceFile);
                        is = GeoserverUserDao.class
                                .getResourceAsStream("serviceTemplate.properties");
                        byte[] buffer = new byte[1024];
                        int count = 0;
                        while ((count = is.read(buffer)) > 0) {
                            os.write(buffer, 0, count);
                        }
                    }

                    userDefinitionsFile = new PropertyFileWatcher(propFile);
                }

                userMap = loadUsersFromProperties(userDefinitionsFile.getProperties());
            } catch (Exception e) {
                LOGGER.log(Level.SEVERE, "An error occurred loading user definitions", e);
            } finally {
                if (is != null)
                    try {
                        is.close();
                    } catch (IOException ei) { /* nothing to do */
                    }
                if (os != null)
                    try {
                        os.close();
                    } catch (IOException eo) { /* nothing to do */
                    }
            }
        }
    }

    /**
     * Get the list of roles currently known by users (there's guarantee the well known
     * ROLE_ADMINISTRATOR will be part of the lot)
     */
    public List<String> getRoles() {
        checkUserMap();
       
        Set<String> roles = new TreeSet<String>();
        roles.add("ROLE_ADMINISTRATOR");
        for (User user : getUsers()) {
            for (GrantedAuthority ga : user.getAuthorities()) {
                roles.add(ga.getAuthority());
            }
        }
        return new ArrayList<String>(roles);
    }

    /**
     * Returns the list of users. To be used for UI editing of users, it's a live map
     *
     * @return
     */
    public List<User> getUsers() {
        checkUserMap();
       
        return new ArrayList(userMap.values());
    }
   
    /**
     * Adds a user in the user map
     * @param user
     */
    public void putUser(User user) {
        checkUserMap();
       
        if(userMap.containsKey(user.getUsername()))
            throw new IllegalArgumentException("The user " + user.getUsername() + " already exists");
        else
            userMap.put(user.getUsername(), user);
    }
   
    /**
     * Updates a user in the user map
     * @param user
     */
    public void setUser(User user) {
        checkUserMap();
       
        if(userMap.containsKey(user.getUsername()))
            userMap.put(user.getUsername(), user);
        else
            throw new IllegalArgumentException("The user " + user.getUsername() + " already exists");
    }
   
    /**
     * Removes the specified user from the users list
     * @param username
     * @return
     */
    public boolean removeUser(String username) {
        checkUserMap();
       
        return userMap.remove(username) != null;
    }

    /**
     * Writes down the current users map to file system
     */
    public void storeUsers() throws IOException {
        FileOutputStream os = null;
        try {
            // turn back the users into a users map
            Properties p = storeUsersToProperties(userMap);

            // write out to the data dir
            File propFile = new File(securityDir, "users.properties");
            os = new FileOutputStream(propFile);
            p.store(os, null);
        } catch (Exception e) {
            if (e instanceof IOException)
                throw (IOException) e;
            else
                throw (IOException) new IOException(
                        "Could not write updated users list to file system").initCause(e);
        } finally {
            if (os != null)
                os.close();
        }
    }

    public GeoServer getGeoServer() {
        return geoServer;
    }

    public void setGeoServer(GeoServer geoServer) throws ConfigurationException {
        this.geoServer = geoServer;
        securityDir = GeoserverDataDirectory.findCreateConfigDir("security");
    }
   
    /**
     * Force the dao to reload its definitions from the file
     */
    public void reload() {
        userDefinitionsFile = null;
    }

    /**
     * Loads the user from property file into the users map
     *
     * @param users
     * @param props
     */
    TreeMap<String, User> loadUsersFromProperties(Properties props) {
        TreeMap<String, User> users = new TreeMap<String, User>();
        UserAttributeEditor configAttribEd = new UserAttributeEditor();

        for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
            // the attribute editors parses the list of strings into password, username and enabled
            // flag
            String username = (String) iter.next();
            configAttribEd.setAsText(props.getProperty(username));

            // if the parsing succeeded turn that into a user object
            UserAttribute attr = (UserAttribute) configAttribEd.getValue();
            if (attr != null) {
                User user = createUserObject(username, attr.getPassword(), attr.isEnabled(), attr.getAuthorities());
                users.put(username, user);
            }
        }

        return users;
    }

    protected User createUserObject(String username,String password, boolean isEnabled,GrantedAuthority[] authorities) {
       return new User(username, password, isEnabled, true, true,
                true, authorities);
    }
   
   
    /**
     * Stores the provided user map into a properties object
     *
     * @param userMap
     * @return
     */
    Properties storeUsersToProperties(Map<String, User> userMap) {
        Properties p = new Properties();
        for (User user : userMap.values()) {
            p.setProperty(user.getUsername(), serializeUser(user));
        }
        return p;
    }

    /**
     * Turns the users password, granted authorities and enabled state into a property file value
     *
     * @param user
     * @return
     */
    String serializeUser(User user) {
        StringBuffer sb = new StringBuffer();
        sb.append(user.getPassword());
        sb.append(",");
        for (GrantedAuthority ga : user.getAuthorities()) {
            sb.append(ga.getAuthority());
            sb.append(",");
        }
        sb.append(user.isEnabled() ? "enabled" : "disabled");
        return sb.toString();
    }

}
TOP

Related Classes of org.geoserver.security.GeoserverUserDao

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.