Package org.exist.xquery.functions.xmldb

Source Code of org.exist.xquery.functions.xmldb.XMLDBAuthenticate

/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-2010 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$
*/
package org.exist.xquery.functions.xmldb;

import org.apache.log4j.Logger;

import org.exist.EXistException;
import org.exist.dom.QName;
import org.exist.http.servlets.RequestWrapper;
import org.exist.http.servlets.SessionWrapper;
import org.exist.security.AuthenticationException;
import org.exist.security.SecurityManager;
import org.exist.security.Subject;
import org.exist.storage.BrokerPool;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.BasicFunction;
import org.exist.xquery.Cardinality;
import org.exist.xquery.FunctionSignature;
import org.exist.xquery.Variable;
import org.exist.xquery.XPathException;
import org.exist.xquery.XQueryContext;
import org.exist.xquery.functions.request.RequestModule;
import org.exist.xquery.functions.session.SessionModule;
import org.exist.xquery.value.BooleanValue;
import org.exist.xquery.value.FunctionReturnSequenceType;
import org.exist.xquery.value.FunctionParameterSequenceType;
import org.exist.xquery.value.JavaObjectValue;
import org.exist.xquery.value.Sequence;
import org.exist.xquery.value.SequenceType;
import org.exist.xquery.value.Type;
import org.xmldb.api.DatabaseManager;
import org.xmldb.api.base.Collection;
import org.xmldb.api.base.XMLDBException;

/**
* @author Wolfgang Meier (wolfgang@exist-db.org)
* @author Andrzej Taramina (andrzej@chaeron.com)
* @author ljo
*/

public class XMLDBAuthenticate extends BasicFunction {
    private static final Logger logger = Logger.getLogger(XMLDBAuthenticate.class);

  public final static FunctionSignature authenticateSignature =
      new FunctionSignature(
        new QName("authenticate", XMLDBModule.NAMESPACE_URI, XMLDBModule.PREFIX),
        "Check if the user, $user-id, can authenticate against the database collection $collection-uri. The function simply tries to " +
        "read the collection $collection-uri, using the credentials " +
        "$user-id and $password. " +
                XMLDBModule.COLLECTION_URI + " " +
        "It returns true if the authentication succeeds, false otherwise.",
        new SequenceType[] {
            new FunctionParameterSequenceType("collection-uri", Type.STRING, Cardinality.EXACTLY_ONE, "The collection URI"),
            new FunctionParameterSequenceType("user-id", Type.STRING, Cardinality.ZERO_OR_ONE, "The user-id"),
            new FunctionParameterSequenceType("password", Type.STRING, Cardinality.ZERO_OR_ONE, "The password")
        },
        new FunctionReturnSequenceType(Type.BOOLEAN, Cardinality.EXACTLY_ONE, "true() on successful authentication, false() otherwise")
      );
 
    public final static FunctionSignature loginSignatures[] = {
   
        new FunctionSignature(
            new QName("login", XMLDBModule.NAMESPACE_URI, XMLDBModule.PREFIX),
            "Login the user, $user-id, and set it as the owner " +
            "of the currently executing XQuery. " +
            XMLDBModule.COLLECTION_URI + " " +
      "It returns true if the authentication succeeds, false otherwise. " +
            "If called from a HTTP context the login is cached for the " +
            "lifetime of the HTTP session and may be used for any XQuery " +
            "run in that session. " +
            "If an HTTP session does not already exist, none will be created.",
            new SequenceType[] {
                new FunctionParameterSequenceType("collection-uri", Type.STRING, Cardinality.EXACTLY_ONE, "The collection URI"),
                new FunctionParameterSequenceType("user-id", Type.STRING, Cardinality.ZERO_OR_ONE, "The user-id"),
                new FunctionParameterSequenceType("password", Type.STRING, Cardinality.ZERO_OR_ONE, "The password")
      },
      new FunctionReturnSequenceType(Type.BOOLEAN, Cardinality.EXACTLY_ONE, "true() on successful authentication and owner elevation, false() otherwise")
    ),
 
    new FunctionSignature(
            new QName("login", XMLDBModule.NAMESPACE_URI, XMLDBModule.PREFIX),
            "Login the user, $user-id, and set it as the owner " +
            "of the currently executing XQuery. " +
            XMLDBModule.COLLECTION_URI + " " +
      "It returns true() if the authentication succeeds, " +
            "false() otherwise. " +
            "If called from a HTTP context the login is cached for the " +
            "lifetime of the HTTP session and may be used for any XQuery" +
            "run in that session. " +
            "$create-session specifies whether to create an HTTP session on " +
            "successful authentication or not. " +
            "If $create-session is false() or the empty sequence no session " +
            "will be created if one does not already exist.",
            new SequenceType[] {
                new FunctionParameterSequenceType("collection-uri", Type.STRING, Cardinality.EXACTLY_ONE, "The collection URI"),
                new FunctionParameterSequenceType("user-id", Type.STRING, Cardinality.ZERO_OR_ONE, "The user-id"),
                new FunctionParameterSequenceType("password", Type.STRING, Cardinality.ZERO_OR_ONE, "The password"),
    new FunctionParameterSequenceType("create-session", Type.BOOLEAN, Cardinality.ZERO_OR_ONE, "whether to create the session or not on successful authentication, default false()")
      },
      new FunctionReturnSequenceType(Type.BOOLEAN, Cardinality.EXACTLY_ONE, "true() on successful authentication and owner elevation, false() otherwise")
    )
  };
   
  /**
   * @param context
   * @param signature
   */
  public XMLDBAuthenticate( XQueryContext context, FunctionSignature signature )
  {
    super( context, signature );
  }

    /* (non-Javadoc)
     * @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
     */
    public Sequence eval( Sequence[] args, Sequence contextSequence )
        throws XPathException {
        if( args[1].isEmpty() ) {
            return BooleanValue.FALSE;
        }
       
        final String uri = args[0].getStringValue();
        final String userName = args[1].getStringValue();
        if (userName == null) {
            logger.error("Unable to authenticate username == NULL");
            return BooleanValue.FALSE;
        }
       
        final String password = args[2].getStringValue();
   
        boolean createSession = false;
   
        if (args.length > 3) {
            createSession = args[3].effectiveBooleanValue();
        }
       
        XmldbURI targetColl;
   
        if( !uri.startsWith( XmldbURI.XMLDB_SCHEME + ':' ) ) {
            targetColl = XmldbURI.EMBEDDED_SERVER_URI.resolveCollectionPath( XmldbURI.create( uri ) );
        } else {
            targetColl = XmldbURI.create( uri );
        }
       
        try {
            Subject user;
         
            try {
              final SecurityManager sm = BrokerPool.getInstance().getSecurityManager();
              user = sm.authenticate(userName, password);
            } catch (final AuthenticationException e) {
                logger.error("Unable to authenticate user: " + userName + " " + getLocation());
                return BooleanValue.FALSE;
            } catch (final EXistException e) {
                logger.error("Unable to authenticate user: " + userName + " " + getLocation(), e);
                return BooleanValue.FALSE;
            }
           
            final Collection root = DatabaseManager.getCollection( targetColl.toString(), userName, password );

            if( root == null ) {
                logger.error("Unable to authenticate user: target collection " + targetColl + " does not exist " + getLocation());
                return BooleanValue.FALSE;
            }
     
            if( isCalledAs( "login" ) ) {
                context.getBroker().setSubject( user );
               
                /** if there is a http session cache the user in the http session */
                cacheUserInHttpSession( user, createSession );
            }
     
            return BooleanValue.TRUE;
        } catch (final XMLDBException e) {
            logger.error(getLocation() + " : " + e.getMessage(), e);
            return BooleanValue.FALSE;
        }
    }
   
    private String getLocation() {
        return "@ " + getContext().getXacmlSource().getKey() + " [" + getLine() + ":" + getColumn() + "]";
    }
 
  /**
   * If there is a HTTP Session, then this will store the user object in the session under the key
   * defined by XQueryContext.HTTP_SESSIONVAR_XMLDB_USER
   *
   * @param user  The User to cache in the session
   * @param createSession  Create session?
   */
  private void cacheUserInHttpSession( Subject user, boolean createSession ) throws XPathException
  {
    final Variable var = getSessionVar( createSession );
   
        if( var != null && var.getValue() != null ) {
        if( var.getValue().getItemType() == Type.JAVA_OBJECT ) {
            final JavaObjectValue session = (JavaObjectValue) var.getValue().itemAt(0);
           
            if( session.getObject() instanceof SessionWrapper ) {
              ((SessionWrapper)session.getObject()).setAttribute( XQueryContext.HTTP_SESSIONVAR_XMLDB_USER, user );
            }
        }
      }
  }
         
  /**
   * Get the HTTP Session variable. Create it if requested and it doesn't exist.
   *
   * @param createSession  Create session?
   */
  private Variable getSessionVar( boolean createSession ) throws XPathException
  {
    final SessionModule sessionModule = (SessionModule)context.getModule( SessionModule.NAMESPACE_URI );
        Variable var = sessionModule.resolveVariable( SessionModule.SESSION_VAR );
   
    if( createSession && ( var == null || var.getValue() == null ) ) {
      SessionWrapper session  = null;
      final RequestModule reqModule = (RequestModule)context.getModule( RequestModule.NAMESPACE_URI );
   
      // request object is read from global variable $request
      final Variable reqVar = reqModule.resolveVariable( RequestModule.REQUEST_VAR );
     
      if( reqVar == null || reqVar.getValue() == null ) {
          logger.error("No request object found in the current XQuery context.");

          throw( new XPathException( this, "No request object found in the current XQuery context." ) );
      }
      if( reqVar.getValue().getItemType() != Type.JAVA_OBJECT ) {
          logger.error( "Variable $request is not bound to an Java object.");
        throw( new XPathException( this, "Variable $request is not bound to an Java object." ) );
      }
     
      final JavaObjectValue reqValue = (JavaObjectValue)reqVar.getValue().itemAt( 0) ;
     
      if( reqValue.getObject() instanceof RequestWrapper ) {
        session = ((RequestWrapper)reqValue.getObject()).getSession( true );
        var = sessionModule.declareVariable( SessionModule.SESSION_VAR, session );
      }
    }
    return( var );
  }
}
TOP

Related Classes of org.exist.xquery.functions.xmldb.XMLDBAuthenticate

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.