org.geoserver.security.PropertyAuthenticationKeyMapper.java Source code

Java tutorial

Introduction

Here is the source code for org.geoserver.security.PropertyAuthenticationKeyMapper.java

Source

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
 * (c) 2001 - 2013 OpenPlans
 * This code is licensed under the GPL 2.0 license, available at the root
 * application directory.
 */
package org.geoserver.security;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.geoserver.security.impl.GeoServerUser;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.StringUtils;

/**
 * Uses the property file <code>$GEOSERVER_DATA_DIR/security/authkey.properties</code> as the source
 * for unique user identifiers. The file format is:
 * <ul>
 * <li>userkey1=username1</li>
 * <li>userkey2=username2</li>
 * <li>...</li>
 * </ul>
 * 
 * The file will be automatically reloaded when modified
 * 
 * @author Andrea Aime - GeoSolutions
 */
public class PropertyAuthenticationKeyMapper extends AbstractAuthenticationKeyMapper {

    /**
     * Name of the file used to store the authentication keys
     */
    public static final String AUTHKEYS_FILE = "authkeys.properties";

    PropertyFileWatcher fileWatcher;
    Properties authKeyProps;

    public boolean supportsReadOnlyUserGroupService() {
        return true;
    }

    @Override
    synchronized public GeoServerUser getUser(String key) throws IOException {
        checkProperties();

        if (authKeyProps == null) {
            synchronize();
        }

        if (fileWatcher.isStale()) // reload if necessary
            authKeyProps = fileWatcher.getProperties();

        String userName = authKeyProps.getProperty(key);
        if (StringUtils.hasLength(userName) == false) {
            LOGGER.warning("Cannot find user for auth key: " + key);
            return null;
        }
        GeoServerUser theUser = null;
        try {
            theUser = (GeoServerUser) getUserGroupService().loadUserByUsername(userName);
        } catch (UsernameNotFoundException ex) {
            LOGGER.warning(
                    "Cannot find user: " + userName + " in user/group service: " + getUserGroupServiceName());
            return null;
        }

        if (theUser.isEnabled() == false) {
            LOGGER.info("Found user " + theUser.getUsername() + " for key " + key + ", but this user is disabled");
            return null;
        }

        return theUser;
    }

    @Override
    protected void checkProperties() throws IOException {
        super.checkProperties();
    }

    @Override
    synchronized public int synchronize() throws IOException {
        checkProperties();

        File propFile = new File(getSecurityManager().getUserGroupRoot(), getUserGroupServiceName());
        propFile = new File(propFile, AUTHKEYS_FILE);

        File backupFile = new File(getSecurityManager().getUserGroupRoot(), getUserGroupServiceName());
        backupFile = new File(backupFile, AUTHKEYS_FILE + ".backup");

        // check if the previous synchronize failed
        if (backupFile.exists())
            throw new IOException("The file: " + backupFile.getCanonicalPath() + " has to be removed first");

        authKeyProps = new Properties();
        Properties oldProps = new Properties();

        // check if property file exists and reload                        
        if (propFile.exists()) {
            FileUtils.copyFile(propFile, backupFile);
            FileInputStream inputFile = new FileInputStream(backupFile);
            try {
                oldProps.load(inputFile);
            } finally {
                inputFile.close();
            }
        }

        Map<Object, Object> reverseMap = new HashMap<Object, Object>();
        for (Entry<Object, Object> entry : oldProps.entrySet()) {
            reverseMap.put(entry.getValue(), entry.getKey());
        }

        GeoServerUserGroupService service = getUserGroupService();

        int counter = 0;
        for (GeoServerUser user : service.getUsers()) {
            if (reverseMap.containsKey(user.getUsername())) {
                authKeyProps.put(reverseMap.get(user.getUsername()), user.getUsername());
            } else {
                authKeyProps.put(createAuthKey(), user.getUsername());
                counter++;
            }
        }
        FileOutputStream outputFile = new FileOutputStream(propFile, false);
        try {
            authKeyProps.store(outputFile, "Format is authkey=username");
        } finally {
            outputFile.close();
        }

        if (backupFile.exists())
            backupFile.delete();

        fileWatcher = new PropertyFileWatcher(propFile);
        return counter;
    }
}