Package org.nimbustools.querygeneral.security

Source Code of org.nimbustools.querygeneral.security.FileUserDetailsService

package org.nimbustools.querygeneral.security;

import org.springframework.core.io.Resource;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataRetrievalFailureException;
import org.mortbay.util.QuotedStringTokenizer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.HashMap;
import java.util.NoSuchElementException;

/**
* UserDetailsService which loads users from a file.
*
* The file format is one user per line: DN accessID secret
* Any token may be quoted and they are separated by whitespace.
* Lines starting with # are ignored
*/
public class FileUserDetailsService implements QueryUserDetailsService {

    private static final Log logger =
            LogFactory.getLog(FileUserDetailsService.class.getName());
    private static final String DELIMS = " \t\n\r\f";

    final private Object lock = new Object();

    private File file;
    private long lastModified;

    final private Map<String, QueryUser> mapByID;
    final private Map<String, QueryUser> mapByDN;


    public FileUserDetailsService(Resource fileResource) throws IOException {
        if (fileResource == null) {
            throw new IllegalArgumentException("fileResource may not be null");
        }

        mapByID = new HashMap<String, QueryUser>();
        mapByDN = new HashMap<String, QueryUser>();

        load(fileResource.getFile());
    }

    public QueryUser loadUserByUsername(String username)
            throws UsernameNotFoundException, DataAccessException {

        if (username == null) {
            throw new IllegalArgumentException("username may not be null");
        }

        synchronized (this.lock) {

            this.refreshIfNeeded();

            final QueryUser user = mapByID.get(username);
            if (user != null) {
                return user;
            }

            throw new UsernameNotFoundException("access identifier '"
                    +username+"' unknown");
        }
    }

    public QueryUser loadUserByDn(String dn)
            throws UsernameNotFoundException, DataAccessException {
        if (dn == null) {
            throw new IllegalArgumentException("dn may not be null");
        }
        synchronized (this.lock) {

            this.refreshIfNeeded();

            final QueryUser user = mapByDN.get(dn);
            if (user != null) {
                return user;
            }

            throw new UsernameNotFoundException("DN '"
                    +dn+"' unknown");
        }
    }

    public boolean refreshIfNeeded() throws DataAccessException {
        synchronized (this.lock) {

            if (this.file.lastModified() > this.lastModified) {
                try {
                    load(this.file);
                } catch (IOException e) {
                    throw new DataRetrievalFailureException(
                        "Error refreshing user file", e);
                }
                return true;
            }
            return false;
        }
    }

    private void load(File file) throws IOException {

        if (file == null) {
            throw new IllegalArgumentException("file may not be null");
        }

        InputStream in = null;
        try {
            in = new FileInputStream(file);
            this.file = file;
            this.lastModified = file.lastModified();
            load(in);
        } finally {
            if (in != null) {
                try { in.close(); }
                catch(Exception e) {
                    logger.warn("Failed to close (??)", e);
                }
            }
        }
    }

    private void load(InputStream stream) throws IOException {
        final BufferedReader reader =
                new BufferedReader(new InputStreamReader(stream));

        mapByID.clear();
        mapByDN.clear();

        String line;
        while ((line = reader.readLine()) != null) {

            // format is DN accessID secret
            // each token can be quoted and is seperated by whitespace

            line = line.trim();

            if (line.length() == 0 || line.charAt(0) == '#') {
                continue;
            }

            final QuotedStringTokenizer tokenizer =
                    new QuotedStringTokenizer(line, DELIMS);

            final QueryUser user;
            try {
                final String dn = tokenizer.nextToken();
                final String accessID = tokenizer.nextToken();
                final String secret = tokenizer.nextToken();

                user = new QueryUser(accessID, secret, dn);

            } catch (NoSuchElementException e) {
                logger.warn("encountered illegal query user entry in file: '"+
                        line+"'. Ignoring.");
                continue;
            }

            mapByID.put(user.getAccessID(), user);
            mapByDN.put(user.getDn(), user);
        }
    }
}
TOP

Related Classes of org.nimbustools.querygeneral.security.FileUserDetailsService

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.