Package org.exist.http.servlets

Source Code of org.exist.http.servlets.AbstractExistHttpServlet

/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-2012 The eXist Project
* http://exist-db.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*  $Id: EXistServlet.java 14945 2011-07-22 20:05:08Z deliriumsky $
*/
package org.exist.http.servlets;

import java.io.File;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.exist.EXistException;
import org.exist.http.urlrewrite.XQueryURLRewrite;
import org.exist.security.AuthenticationException;
import java.security.Principal;
import org.exist.security.Subject;
import org.exist.security.internal.web.HttpAccount;
import org.exist.storage.BrokerPool;
import org.exist.util.Configuration;
import org.exist.util.DatabaseConfigurationException;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Database;
import org.xmldb.api.base.XMLDBException;
import org.exist.security.SecurityManager;
import org.exist.security.XmldbPrincipal;
import org.exist.security.internal.AccountImpl;

/**
*
* @author Adam Retter <adam.retter@googlemail.com>
*/
public abstract class AbstractExistHttpServlet extends HttpServlet {

  private static final long serialVersionUID = 804071766041263220L;

  public final static String DEFAULT_ENCODING = "UTF-8";
   
    private BrokerPool pool;
    private String formEncoding = DEFAULT_ENCODING;
    private String containerEncoding = DEFAULT_ENCODING;
    private String defaultUsername = SecurityManager.GUEST_USER;
    private String defaultPassword = SecurityManager.GUEST_USER;
    private Authenticator authenticator;
    private Subject defaultUser = null;
    private boolean internalOnly = false;
   
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
       
        //prepare the database
        try {
            setPool(getOrCreateBrokerPool(config));
        } catch (final EXistException e) {
                throw new ServletException("No database instance available");
        } catch (final DatabaseConfigurationException e) {
                throw new ServletException("Unable to configure database instance: " + e.getMessage(), e);
        }
       
        //general eXist Servlet config
        doGeneralExistServletConfig(config);
    }
   
    @Override
    public void destroy() {
        super.destroy();
        BrokerPool.stopAll(false);
    }
   
    public abstract Logger getLog();
   
    private BrokerPool getOrCreateBrokerPool(ServletConfig config) throws EXistException, DatabaseConfigurationException, ServletException {

        // Configure BrokerPool
        if(BrokerPool.isConfigured(BrokerPool.DEFAULT_INSTANCE_NAME)) {
            getLog().info("Database already started. Skipping configuration ...");
        } else {
            String confFile = config.getInitParameter("configuration");
            String dbHome = config.getInitParameter("basedir");
            final String start = config.getInitParameter("start");
            if(confFile == null) {
                confFile = "conf.xml";
            }

            if (dbHome == null) {
                dbHome = config.getServletContext().getRealPath("/");
            } else {
                dbHome = config.getServletContext().getRealPath(dbHome);
                if (dbHome == null) {
                    // tomcat 8 workaround: returns null on getRealPath("WEB-INF").
                    // try to detect it differently:
                    String dir = config.getServletContext().getRealPath("/");
                    if (dir != null) {
                        dbHome = new File(dir, "WEB-INF").getAbsolutePath();
                    }
                }
            }
            getLog().info("EXistServlet: exist.home=" + dbHome);

            final File f = new File(dbHome + File.separator + confFile);
            getLog().info("Reading configuration from " + f.getAbsolutePath());
            if (!f.canRead()) {
                throw new ServletException("Configuration file " + confFile + " not found or not readable");
            }

            final Configuration configuration = new Configuration(confFile, dbHome);
            if(start != null && "true".equals(start)) {
                doDatabaseStartup(configuration);
            }
        }

        return BrokerPool.getInstance();
    }
   
    private void doDatabaseStartup(Configuration configuration) throws ServletException {
        if(configuration == null) {
            throw new ServletException("Database has not been " + "configured");
        }
       
        getLog().info("Configuring eXist instance");
       
        try {
            if(!BrokerPool.isConfigured(BrokerPool.DEFAULT_INSTANCE_NAME)) {
                BrokerPool.configure(1, 5, configuration);
            }
        } catch(final EXistException e) {
            throw new ServletException(e.getMessage(), e);
        } catch(final DatabaseConfigurationException e) {
            throw new ServletException(e.getMessage(), e);
        }
       
        try {
            getLog().info("Registering XMLDB driver");
            final Class<?> clazz = Class.forName("org.exist.xmldb.DatabaseImpl");
            final Database database = (Database) clazz.newInstance();
            DatabaseManager.registerDatabase(database);
        } catch(final ClassNotFoundException e) {
            getLog().info("ERROR", e);
        } catch(final InstantiationException e) {
            getLog().info("ERROR", e);
        } catch(final IllegalAccessException e) {
            getLog().info("ERROR", e);
        } catch(final XMLDBException e) {
            getLog().info("ERROR", e);
        }
    }
   
    private void doGeneralExistServletConfig(ServletConfig config) {
        String option = config.getInitParameter("use-default-user");
        boolean useDefaultUser = true;
        if(option != null) {
            useDefaultUser = "true".equals(option.trim());
        }
        if(useDefaultUser) {
            option = config.getInitParameter("user");
            if(option != null) {
                setDefaultUsername(option);

                option = config.getInitParameter("password");
                if(option != null) {
                    setDefaultPassword(option);
                }

                if(getDefaultUsername() != null) {
                    try {
                        setDefaultUser(getPool().getSecurityManager().authenticate(getDefaultUsername(), getDefaultPassword()));
                    } catch(final AuthenticationException e) {
                        setDefaultUser(null);
                    }
                } else {
                    setDefaultUser(null);
                }
            } else {
                setDefaultUser(pool.getSecurityManager().getGuestSubject());
            }

            if (getDefaultUser() != null) {
                getLog().info("Using default user " + getDefaultUsername() + " for all unauthorized requests.");
            } else {
                getLog().error("Default user " + getDefaultUsername() + " cannot be found.  A BASIC AUTH challenge will be the default.");
            }
        } else {
            getLog().info("No default user.  All requires must be authorized or will result in a BASIC AUTH challenge.");
            setDefaultUser(null);
        }
       
        setAuthenticator(new BasicAuthenticator(getPool()));

        // get form and container encoding's
        final String configFormEncoding = config.getInitParameter("form-encoding");
        if(configFormEncoding != null) {
            setFormEncoding(configFormEncoding);
        }
       
        final String configContainerEncoding = config.getInitParameter("container-encoding");
        if(configContainerEncoding != null) {
            setContainerEncoding(configContainerEncoding);
        }
       
        final String param = config.getInitParameter("hidden");
        if(param != null) {
            internalOnly = Boolean.valueOf(param);
        }
    }
   
    protected Subject authenticate(HttpServletRequest request, HttpServletResponse response) throws IOException {
       
        if(isInternalOnly() && request.getAttribute(XQueryURLRewrite.RQ_ATTR) == null) {
            response.sendError(HttpServletResponse.SC_FORBIDDEN);
            return null;
        }
       
        Principal principal = HttpAccount.getUserFromServletRequest(request);
        if (principal != null) {return (Subject) principal;}

        // Try to validate the principal if passed from the Servlet engine
        principal = request.getUserPrincipal();

        if (principal != null) {
          if ( XmldbPrincipal.class.isAssignableFrom( principal.getClass() ) ) {
 
              final String username = ((XmldbPrincipal) principal).getName();
              final String password = ((XmldbPrincipal) principal).getPassword();
 
              getLog().info("Validating Principle: " + username);
              try {
                  return getPool().getSecurityManager().authenticate(username, password);
              } catch (final AuthenticationException e) {
                  getLog().info(e.getMessage());
              }
          }
 
          if (principal instanceof Subject) {
              return (Subject)principal;
          }
        }

        // Secondly try basic authentication
        final String auth = request.getHeader("Authorization");
        if (auth == null && getDefaultUser() != null) {
            return getDefaultUser();
        }
        return getAuthenticator().authenticate(request, response);
    }

    protected boolean isInternalOnly() {
        return internalOnly;
    }

    private void setInternalOnly(boolean internalOnly) {
        this.internalOnly = internalOnly;
    }
   
    protected Subject getDefaultUser() {
        return defaultUser;
    }

    private void setDefaultUser(Subject defaultUser) {
        this.defaultUser = defaultUser;
    }

    protected Authenticator getAuthenticator() {
        return authenticator;
    }

    private void setAuthenticator(Authenticator authenticator) {
        this.authenticator = authenticator;
    }

    protected String getDefaultPassword() {
        return defaultPassword;
    }

    private void setDefaultPassword(String defaultPassword) {
        this.defaultPassword = defaultPassword;
    }

    protected String getDefaultUsername() {
        return defaultUsername;
    }

    private void setDefaultUsername(String defaultUsername) {
        this.defaultUsername = defaultUsername;
    }
   
    protected String getContainerEncoding() {
        return containerEncoding;
    }

    private void setContainerEncoding(String containerEncoding) {
        this.containerEncoding = containerEncoding;
    }

    protected String getFormEncoding() {
        return formEncoding;
    }

    private void setFormEncoding(String formEncoding) {
        this.formEncoding = formEncoding;
    }

    protected BrokerPool getPool() {
        return pool;
    }
   
    private void setPool(BrokerPool pool) {
        this.pool = pool;
    }
}
TOP

Related Classes of org.exist.http.servlets.AbstractExistHttpServlet

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.