/*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library 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.1 of the License, or (at your option) any later version. This library 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.security.owsrequestvalidator; import java.io.InputStreamReader; import java.io.Reader; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.deegree.framework.log.ILogger; import org.deegree.framework.log.LoggerFactory; import org.deegree.framework.util.StringTools; import org.deegree.framework.xml.NamespaceContext; import org.deegree.framework.xml.XMLParsingException; import org.deegree.framework.xml.XMLTools; import org.deegree.ogcbase.BaseURL; import org.deegree.ogcbase.CommonNamespaces; import org.deegree.security.SecurityConfigurationException; import org.deegree.security.owsproxy.AuthentificationSettings; import org.deegree.security.owsproxy.Condition; import org.deegree.security.owsproxy.DefaultDBConnection; import org.deegree.security.owsproxy.OperationParameter; import org.deegree.security.owsproxy.RegistryConfig; import org.deegree.security.owsproxy.Request; import org.deegree.security.owsproxy.SecurityConfig; import org.deegree.security.owsproxy.UsersOperationParameter; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.deegree.security.owsproxy.UsersOperationParameter.OpParameterRoleEntry; /** * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> * @author last edited by: $Author: poth $ * * @version 1.1, $Revision: 1.18 $, $Date: 2006/08/02 14:14:42 $ * * @since 1.1 * */ public class PolicyDocument { private ILogger LOG = LoggerFactory.getLogger( PolicyDocument.class ); private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext(); private Document doc = null; private String service = null; /** * @param url * @throws SecurityConfigurationException */ public PolicyDocument( URL url ) throws SecurityConfigurationException { try { Reader reader = new InputStreamReader( url.openStream() ); doc = XMLTools.parse( reader ); service = XMLTools.getRequiredAttrValue( "service", null, doc.getDocumentElement() ); } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); } } /** * @param doc * document containing a policy document */ public PolicyDocument( Document doc ) throws SecurityConfigurationException { this.doc = doc; try { service = XMLTools.getRequiredAttrValue( "service", null, doc.getDocumentElement() ); } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); } } /** * returns the <tt>Policy</tt> created from the encapsulated DOM abject. * * @return */ public Policy getPolicy() throws SecurityConfigurationException, XMLParsingException { Condition general = getGeneralCondition(); SecurityConfig sc = null; List nl = XMLTools.getNodes( doc, "/dgsec:OWSPolicy/dgsec:Security", nsContext ); if ( nl.size() > 0 ) { sc = getSecuityConfig(); } Request[] requests = getRequests(); return new Policy( sc, general, requests ); } /** * @return Returns the generalCondition. */ private Condition getGeneralCondition() throws SecurityConfigurationException { Condition condition = null; try { OperationParameter[] op = new OperationParameter[4]; String xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'getContentLength']"; op[0] = getOperationParameter( "getContentLength", xpath ); xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'postContentLength']"; op[1] = getOperationParameter( "postContentLength", xpath ); xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'httpHeader']"; op[2] = getOperationParameter( "httpHeader", xpath ); xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'requestMethod']"; op[3] = getOperationParameter( "requestType", xpath ); condition = new Condition( op ); } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); } return condition; } /** * @return Returns the secuityConfig. */ private SecurityConfig getSecuityConfig() throws SecurityConfigurationException { SecurityConfig securityConfig = null; try { String xpath = null; xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryClass"; String regClass = XMLTools.getNodeAsString( doc, xpath, nsContext, "org.deegree.security.drm.SQLRegistry" ); xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:ReadWriteTimeout"; String tmp = XMLTools.getNodeAsString( doc, xpath, nsContext, "300" ); int readWriteTimeout = Integer.parseInt( tmp ); RegistryConfig registryConfig = getRegistryConfig(); AuthentificationSettings authSet = getAuthentificationSettings(); securityConfig = new SecurityConfig( regClass, readWriteTimeout, registryConfig, authSet ); } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); } return securityConfig; } /** * returns the configuration of the used rights management registry * * @return * @throws SecurityConfigurationException */ private RegistryConfig getRegistryConfig() throws SecurityConfigurationException { RegistryConfig registryConfig = null; try { String xpath = null; xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Driver"; String driver = XMLTools.getNodeAsString( doc, xpath, nsContext, null ); xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Url"; String logon = XMLTools.getNodeAsString( doc, xpath, nsContext, null ); xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:User"; String user = XMLTools.getNodeAsString( doc, xpath, nsContext, null ); xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Password"; String password = XMLTools.getNodeAsString( doc, xpath, nsContext, null ); if ( driver != null && logon != null ) { DefaultDBConnection con = new DefaultDBConnection( driver, logon, user, password ); registryConfig = new RegistryConfig( con ); } else if ( (driver != null && logon == null) || (driver == null && logon != null) ) { throw new SecurityConfigurationException( Messages.getString( "PolicyDocument.DatabaseConnection" ) ); } } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); } return registryConfig; } /** * returns the settings for accessing the authentification authority * * @return * @throws SecurityConfigurationException */ private AuthentificationSettings getAuthentificationSettings() throws SecurityConfigurationException { AuthentificationSettings authSet = null; try { StringBuffer xpath = new StringBuffer( "/dgsec:OWSPolicy/dgsec:Security/" ); xpath.append( "dgsec:AuthentificationSettings/dgsec:AuthentificationService" ); xpath.append( "/dgsec:OnlineResource/@xlink:href" ); String onlineRes = XMLTools.getNodeAsString( doc, xpath.toString(), nsContext, null ); if ( onlineRes != null ) { BaseURL baseURL = new BaseURL( null, new URL( onlineRes ) ); authSet = new AuthentificationSettings( baseURL ); } } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); } return authSet; } /** * @return returns the requests described by the policy document */ private Request[] getRequests() throws SecurityConfigurationException { Request[] requests = null; try { List nl = XMLTools.getNodes( doc, "/dgsec:OWSPolicy/dgsec:Requests/*", nsContext ); requests = new Request[nl.size()]; for ( int i = 0; i < requests.length; i++ ) { requests[i] = getRequest( (Element) nl.get( i ) ); } } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); } return requests; } /** * returns the requests described by the passed <tt>Element</tt> * * @param element * @return created <tt>Request</tt> * @throws SecurityConfigurationException */ private Request getRequest( Element element ) throws SecurityConfigurationException { String name = element.getLocalName(); Request request = null; Condition preCon = null; Condition postCon = null; try { List nl = XMLTools.getNodes( element, "./dgsec:PreConditions/dgsec:Parameter", nsContext ); OperationParameter[] op = new OperationParameter[nl.size()]; for ( int i = 0; i < nl.size(); i++ ) { op[i] = getOperationParameter( (Element) nl.get( i ) ); } preCon = new Condition( op ); nl = XMLTools.getNodes( element, "./dgsec:PostConditions/dgsec:Parameter", nsContext ); op = new OperationParameter[nl.size()]; for ( int i = 0; i < nl.size(); i++ ) { op[i] = getOperationParameter( (Element) nl.get( i ) ); } postCon = new Condition( op ); request = new Request( service, name, preCon, postCon ); } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); } return request; } /** * creates an <tt>OperationParameter</tt> with the passed name from the also passed root * XPath. A root XPath is an expression to the desired parameter node. * * @param name * name of the OperationParameter * @param xpathRoot * @return * @throws SecurityConfigurationException */ private OperationParameter getOperationParameter( String name, String xpathRoot ) throws SecurityConfigurationException { OperationParameter op = null; try { if ( XMLTools.getNodes( doc, xpathRoot, nsContext ).size() == 0 ) { // return OperationParameter that denies any access return new OperationParameter( name, false ); } // is parameter coupled to user specific rights String tmp = XMLTools.getRequiredNodeAsString( doc, xpathRoot + "/@userCoupled", nsContext ).toLowerCase(); boolean userCoupled = tmp.equals( "true" ) || tmp.equals( "1" ); // is any? -> no restrictions tmp = XMLTools.getNodeAsString( doc, xpathRoot + "/dgsec:Any", nsContext, "false" ); boolean any = !tmp.equals( "false" ); if ( !any ) { // get values if not 'any' String[] values = XMLTools.getNodesAsStrings( doc, xpathRoot + "/dgsec:Value", nsContext ); op = new OperationParameter( name, values, userCoupled ); } else { op = new OperationParameter( name, any ); } } catch ( Exception e ) { LOG.logError( e.getMessage(), e ); throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); } return op; } /** * creates an <tt>OperationParameter</tt> from the passed element. * * @param element * encapsulating a parameter * @return created <tt>OperationParameter</tt> * @throws XMLParsingException */ // XXXsyp This is unused private OperationParameter getOperationParameterNested( Element element ) throws XMLParsingException { OperationParameter op = null; String name = XMLTools.getRequiredAttrValue( "name", null, element ); String uc = XMLTools.getRequiredAttrValue( "userCoupled", null, element ); boolean userCoupled = uc.equals( "true" ) || uc.equals( "1" ); boolean any = XMLTools.getNode( element, "dgsec:Any", nsContext ) != null; if ( !any ) { List list = XMLTools.getNodes( element, "dgsec:Value", nsContext ); String[] values = new String[list.size()]; for ( int j = 0; j < values.length; j++ ) { values[j] = XMLTools.getStringValue( (Element) list.get( j ) ); } op = new OperationParameter( name, values, userCoupled ); } else { op = new OperationParameter( name, any ); } return op; } /** * creates an <tt>OperationParameter</tt> from the passed element. * * @param element * encapsulating a parameter * @return created <tt>OperationParameter</tt> * @throws XMLParsingException */ private OperationParameter getOperationParameter( Element element ) throws XMLParsingException { OperationParameter op = null; String name = XMLTools.getRequiredAttrValue( "name", null, element ); // XXXsyp userCoupled is always false and ignored from document //String uc = XMLTools.getRequiredAttrValue( "userCoupled", null, element ); //boolean userCoupled = uc.equals( "true" ) || uc.equals( "1" ); boolean userCoupled = false; // ******** //XMLTools.getNodes(contextNode, xPathQuery, nsContext) // XXXsyp rename role List roles = XMLTools.getNodes( element, "dgsec:Role", nsContext ); if (roles.size() > 0) { System.out.println("has roles"); //Map<String,OperationParameter> ops = new HashMap<String,OperationParameter>(); List ops = new ArrayList(); for ( int i = 0; i < roles.size(); i++ ) { Element el = (Element) roles.get( i ); String roleName = el.getAttribute("name"); OperationParameter _op = getOperationParameterInternal(el, name, userCoupled); /* List list = XMLTools.getNodes( el, "dgsec:Value", nsContext ); String[] values = new String[list.size()]; for ( int j = 0; j < values.length; j++ ) { values[j] = XMLTools.getStringValue( (Element) list.get( j ) ); } */ System.out.println(_op); // XXX continue there /* OperationParameter uop; if (_op.isAny()) { uop = new UsersOperationParameter( name, _op.isAny() ); } else { uop = new UsersOperationParameter( name, (String[])_op.getValues().toArray(new String[] {}), _op.isUserCoupled() ); } return uop; */ //ops.put(roleName, _op); // TODO: multiple roles ops.add(new OpParameterRoleEntry(new String[] {roleName}, _op)); } return new UsersOperationParameter(name, ops, false); } // ******** op = getOperationParameterInternal(element, name, userCoupled); return op; } private OperationParameter getOperationParameterInternal(Element element, String name, boolean userCoupled) throws XMLParsingException { OperationParameter op; boolean any = XMLTools.getNode( element, "dgsec:Any", nsContext ) != null; if ( !any ) { List list = XMLTools.getNodes( element, "dgsec:Value", nsContext ); String[] values = new String[list.size()]; for ( int j = 0; j < values.length; j++ ) { values[j] = XMLTools.getStringValue( (Element) list.get( j ) ); } op = new OperationParameter( name, values, userCoupled ); } else { op = new OperationParameter( name, any ); } return op; } } /* ******************************************************************** Changes to this class. What the people have been up to: $Log: PolicyDocument.java,v $ Revision 1.18 2006/08/02 14:14:42 poth made JDBC connection for security manager optional Revision 1.17 2006/05/25 09:53:30 poth adapated to changed/simplified policy xml-schema ********************************************************************** */