Package org.fcrepo.server.security

Source Code of org.fcrepo.server.security.BackendSecurityDeserializer

/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package org.fcrepo.server.security;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import org.fcrepo.common.Constants;
import org.fcrepo.server.errors.GeneralException;
import org.fcrepo.server.errors.StreamIOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



/**
* SAX parser to deserialize the beSecurity XML file that contains configuration
* properties for backend services.
*
* @author Sandy Payette
*/
public class BackendSecurityDeserializer
        extends DefaultHandler
        implements Constants {

    private static final Logger logger =
            LoggerFactory.getLogger(BackendSecurityDeserializer.class);

    /** Attribute names in the beSecurity spec file */
    public static final String CALL_BASIC_AUTH = "callBasicAuth";

    public static final String CALL_SSL = "callSSL";

    public static final String CALL_USERNAME = "callUsername";

    public static final String CALL_PASSWORD = "callPassword";

    public static final String CALLBACK_BASIC_AUTH = "callbackBasicAuth";

    public static final String CALLBACK_SSL = "callbackSSL";

    //public static final String CALLBACK_USERNAME = "callbackUsername";
    //public static final String CALLBACK_PASSWORD = "callbackPassword";
    public static final String IPLIST = "iplist";

    public static final String ROLE = "role";

    /** Target objects for deserialization. */
    private final BackendSecuritySpec beSS;

    private Hashtable<String, String> beProperties =
            new Hashtable<String, String>();

    /** Temp variables for SAX parse */
    private final SAXParser tmp_parser;

    private boolean tmp_rootElementFound;

    private int tmp_level;

    private String tmp_parentRole;

    private Hashtable<String, String> tmp_rootProperties;

    private Hashtable<String, String> tmp_serviceProperties;

    private String tmp_role;

    public BackendSecurityDeserializer(String characterEncoding,
                                       boolean validate)
            throws FactoryConfigurationError, ParserConfigurationException,
            SAXException, UnsupportedEncodingException {
        StringBuffer buf = new StringBuffer();
        buf.append("test");
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setValidating(validate);
        spf.setNamespaceAware(true);
        tmp_parser = spf.newSAXParser();

        // set up objects for the parsed information
        beSS = new BackendSecuritySpec();
        beProperties = new Hashtable<String, String>();
    }

    public BackendSecuritySpec deserialize(String inFilePath)
            throws GeneralException, StreamIOException,
            UnsupportedEncodingException {

        logger.debug("Parsing beSecurity file...");

        tmp_level = 0;
        try {
            FileInputStream fis = new FileInputStream(new File(inFilePath));
            tmp_parser.parse(fis, this);
        } catch (IOException ioe) {
            throw new StreamIOException("BackendSecurityDeserializer: "
                    + "Stream IO problem while parsing backend security config file.");
        } catch (SAXException se) {
            throw new GeneralException("BackendSecurityDeserializer: "
                    + "Error parsing backend security config file. "
                    + se.getMessage());
        }
        if (!tmp_rootElementFound) {
            throw new GeneralException("BackendSecurityDeserializer: "
                    + "Root element not found in backend security config file.");
        }

        logger.debug("Parse successful.");
        return beSS;
    }

    @Override
    public void startElement(String uri,
                             String localName,
                             String qName,
                             Attributes a) throws SAXException {

        if (uri.equals(BE_SECURITY.uri)
                && localName.equals("serviceSecurityDescription")) {

            logger.debug("start element uri=" + uri + " localName=" + localName
                    + " tmp_level=" + tmp_level);

            tmp_role = grab(a, BE_SECURITY.uri, ROLE);
            beProperties = new Hashtable<String, String>();
            setProperty(CALL_BASIC_AUTH, grab(a,
                                              BE_SECURITY.uri,
                                              CALL_BASIC_AUTH));
            setProperty(CALL_SSL, grab(a, BE_SECURITY.uri, CALL_SSL));
            setProperty(CALL_USERNAME, grab(a, BE_SECURITY.uri, CALL_USERNAME));
            setProperty(CALL_PASSWORD, grab(a, BE_SECURITY.uri, CALL_PASSWORD));
            setProperty(CALLBACK_BASIC_AUTH, grab(a,
                                                  BE_SECURITY.uri,
                                                  CALLBACK_BASIC_AUTH));
            setProperty(CALLBACK_SSL, grab(a, BE_SECURITY.uri, CALLBACK_SSL));
            setProperty(IPLIST, grab(a, BE_SECURITY.uri, IPLIST));

            try {
                if (tmp_level == 0) {
                    tmp_rootElementFound = true;
                    tmp_rootProperties = new Hashtable<String, String>();
                    tmp_rootProperties.putAll(beProperties);
                    validateProperties();
                    beSS.setSecuritySpec("default", null, beProperties);
                } else if (tmp_level == 1) {
                    tmp_parentRole = tmp_role;
                    tmp_serviceProperties = new Hashtable<String, String>();
                    tmp_serviceProperties.putAll(beProperties);
                    inheritProperties(tmp_rootProperties);
                    validateProperties();
                    beSS.setSecuritySpec(tmp_role, null, beProperties);
                } else if (tmp_level == 2) {
                    inheritProperties(tmp_serviceProperties);
                    inheritProperties(tmp_rootProperties);
                    validateProperties();
                    beSS
                            .setSecuritySpec(tmp_parentRole,
                                             tmp_role,
                                             beProperties);
                } else {
                    logger.debug("xml element depth exceeded");
                    throw new SAXException("BackendSecurityDeserializer: "
                            + "serviceSecurityDescription elements can only "
                            + "be nested two levels deep from root element!");
                }
            } catch (Exception e) {
                throw new SAXException("BackendSecurityDeserializer: "
                        + "Error setting properties for role " + tmp_role
                        + ". " + e.getMessage());
            }
            tmp_level++;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) {

        logger.debug("end element uri=" + uri + " localName=" + localName
                + " tmp_level=" + tmp_level);
        if (uri.equals(BE_SECURITY.uri)
                && localName.equals("serviceSecurityDescription")) {
            tmp_level--;
        }
    }

    private static String grab(Attributes a,
                               String namespace,
                               String elementName) {
        String ret = a.getValue(namespace, elementName);
        if (ret == null) {
            ret = a.getValue(elementName);
        }
        return ret;
    }

    private void setProperty(String key, String value) {
        if (key != null && value != null) {
            logger.debug("Setting propery.  key=" + key + " value=" + value);
            beProperties.put(key, value);
        }
    }

    private void inheritProperties(Hashtable inheritableProperties) {

        logger.debug("Setting inherited properties...");
        Iterator it = inheritableProperties.keySet().iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            if (!beProperties.containsKey(key)) {
                setProperty(key, (String) inheritableProperties.get(key));
            }
        }
    }

    private void validateProperties() throws GeneralException {

        logger.debug("Validating properties...");
        if (!beProperties.containsKey(CALL_BASIC_AUTH)) {
            setProperty(CALL_BASIC_AUTH, "false");
        }
        if (!beProperties.containsKey(CALL_SSL)) {
            setProperty(CALL_SSL, "false");
        }
        if (!beProperties.containsKey(CALLBACK_BASIC_AUTH)) {
            setProperty(CALLBACK_BASIC_AUTH, "false");
        }
        if (!beProperties.containsKey(CALLBACK_SSL)) {
            setProperty(CALLBACK_SSL, "false");
        }
        if (beProperties.get(CALL_BASIC_AUTH).equals("true")) {
            if (!beProperties.containsKey(CALL_USERNAME)) {
                throw new GeneralException("BackendSecurityDeserializer: "
                        + "callBasicAuth is set to true, but callUsername is missing"
                        + "for role of " + tmp_role);
            }
            if (!beProperties.containsKey(CALL_PASSWORD)) {
                throw new GeneralException("BackendSecurityDeserializer: "
                        + "callBasicAuth is set to true, but callPassword is missing"
                        + "for role of " + tmp_role);
            }
        }
    }

    public static void main(String[] args) throws Exception {
        logger.debug("BackendSecurityDeserializer start main()...");
        BackendSecurityDeserializer bds =
                new BackendSecurityDeserializer("UTF-8", false);
        BackendSecuritySpec beSS = bds.deserialize(args[0]);

        // Let's see all the stuff...
        Set allRoleKeys = beSS.listRoleKeys();
        Iterator iterRoles = allRoleKeys.iterator();
        while (iterRoles.hasNext()) {
            String roleKey = (String) iterRoles.next();
            logger.debug("************ ROLEKEY = " + roleKey);
            // let's see all the properties for this role...
            Hashtable roleProperties = beSS.getSecuritySpec(roleKey);
            Iterator iterProps = roleProperties.keySet().iterator();
            while (iterProps.hasNext()) {
                String propKey = (String) iterProps.next();
                String propValue = (String) roleProperties.get(propKey);
                logger.debug(propKey + "=" + propValue);
            }
        }
    }
}
TOP

Related Classes of org.fcrepo.server.security.BackendSecurityDeserializer

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.