001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/security/owsrequestvalidator/PolicyDocument.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.security.owsrequestvalidator; 037 038 import java.io.InputStreamReader; 039 import java.io.Reader; 040 import java.net.MalformedURLException; 041 import java.net.URL; 042 import java.util.ArrayList; 043 import java.util.List; 044 045 import org.deegree.framework.log.ILogger; 046 import org.deegree.framework.log.LoggerFactory; 047 import org.deegree.framework.util.StringTools; 048 import org.deegree.framework.xml.NamespaceContext; 049 import org.deegree.framework.xml.XMLParsingException; 050 import org.deegree.framework.xml.XMLTools; 051 import org.deegree.ogcbase.BaseURL; 052 import org.deegree.ogcbase.CommonNamespaces; 053 import org.deegree.security.SecurityConfigurationException; 054 import org.deegree.security.owsproxy.AuthentificationSettings; 055 import org.deegree.security.owsproxy.Condition; 056 import org.deegree.security.owsproxy.DefaultDBConnection; 057 import org.deegree.security.owsproxy.OperationParameter; 058 import org.deegree.security.owsproxy.RegistryConfig; 059 import org.deegree.security.owsproxy.Request; 060 import org.deegree.security.owsproxy.SecurityConfig; 061 import org.w3c.dom.Document; 062 import org.w3c.dom.Element; 063 import org.w3c.dom.Node; 064 065 /** 066 * 067 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 068 * @author last edited by: $Author: aschmitz $ 069 * 070 * @version $Revision: 31356 $, $Date: 2011-07-26 09:19:13 +0200 (Di, 26 Jul 2011) $ 071 */ 072 public class PolicyDocument { 073 074 private ILogger LOG = LoggerFactory.getLogger( PolicyDocument.class ); 075 076 private static final NamespaceContext nsContext = CommonNamespaces.getNamespaceContext(); 077 078 private Document doc = null; 079 080 private String service = null; 081 082 /** 083 * @param url 084 * @throws SecurityConfigurationException 085 */ 086 public PolicyDocument( URL url ) throws SecurityConfigurationException { 087 try { 088 Reader reader = new InputStreamReader( url.openStream() ); 089 doc = XMLTools.parse( reader ); 090 service = XMLTools.getRequiredAttrValue( "service", null, doc.getDocumentElement() ); 091 } catch ( Exception e ) { 092 LOG.logError( e.getMessage(), e ); 093 throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); 094 } 095 } 096 097 /** 098 * @param doc 099 * document containing a policy document 100 * @throws SecurityConfigurationException 101 */ 102 public PolicyDocument( Document doc ) throws SecurityConfigurationException { 103 this.doc = doc; 104 try { 105 service = XMLTools.getRequiredAttrValue( "service", null, doc.getDocumentElement() ); 106 } catch ( XMLParsingException e ) { 107 LOG.logError( e.getMessage(), e ); 108 throw new SecurityConfigurationException( e.getMessage() ); 109 } 110 } 111 112 public List<String> getWhitelist() 113 throws SecurityConfigurationException { 114 try { 115 List<String> list = XMLTools.getNodesAsStringList( doc, 116 "/dgsec:OWSPolicy/dgsec:Whitelist/dgsec:PassedParameter", 117 nsContext ); 118 return list; 119 } catch ( XMLParsingException e ) { 120 LOG.logError( e.getMessage(), e ); 121 throw new SecurityConfigurationException( e.getMessage() ); 122 } 123 } 124 125 /** 126 * returns the <tt>Policy</tt> created from the encapsulated DOM abject. 127 * 128 * @return the <tt>Policy</tt> created from the encapsulated DOM abject. 129 * @throws SecurityConfigurationException 130 * @throws XMLParsingException 131 */ 132 public Policy getPolicy() 133 throws SecurityConfigurationException, XMLParsingException { 134 Condition general = getGeneralCondition(); 135 SecurityConfig sc = null; 136 String dgSecPrefix = CommonNamespaces.DGSEC_PREFIX; 137 List<Node> nl = XMLTools.getNodes( doc, "/" + dgSecPrefix + ":OWSPolicy/" + dgSecPrefix + ":Security", 138 nsContext ); 139 if ( nl.size() > 0 ) { 140 sc = getSecuityConfig(); 141 } 142 Request[] requests = getRequests(); 143 List<String> whitelist = getWhitelist(); 144 return new Policy( sc, general, requests, whitelist ); 145 } 146 147 /** 148 * @return Returns the generalCondition. 149 */ 150 private Condition getGeneralCondition() 151 throws SecurityConfigurationException { 152 Condition condition = null; 153 OperationParameter[] op = new OperationParameter[4]; 154 String xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'getContentLength']"; 155 op[0] = getOperationParameter( "getContentLength", xpath ); 156 xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'postContentLength']"; 157 op[1] = getOperationParameter( "postContentLength", xpath ); 158 xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'httpHeader']"; 159 op[2] = getOperationParameter( "httpHeader", xpath ); 160 xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'requestMethod']"; 161 op[3] = getOperationParameter( "requestType", xpath ); 162 condition = new Condition( op ); 163 // } catch ( Exception e ) { 164 // LOG.logError( e.getMessage(), e ); 165 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); 166 // } 167 return condition; 168 } 169 170 /** 171 * @return the secuityConfig. 172 */ 173 private SecurityConfig getSecuityConfig() 174 throws SecurityConfigurationException { 175 SecurityConfig securityConfig = null; 176 177 String xpath = null; 178 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryClass"; 179 180 try { 181 String regClass = XMLTools.getNodeAsString( doc, xpath, nsContext, "org.deegree.security.drm.SQLRegistry" ); 182 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:ReadWriteTimeout"; 183 String tmp = XMLTools.getNodeAsString( doc, xpath, nsContext, "300" ); 184 int readWriteTimeout = Integer.parseInt( tmp ); 185 RegistryConfig registryConfig = getRegistryConfig(); 186 AuthentificationSettings authSet = getAuthentificationSettings(); 187 securityConfig = new SecurityConfig( regClass, readWriteTimeout, registryConfig, authSet ); 188 189 } catch ( XMLParsingException e ) { 190 throw new SecurityConfigurationException( e.getMessage() ); 191 } 192 // 193 // } catch ( Exception e ) { 194 // LOG.logError( e.getMessage(), e ); 195 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); 196 // } 197 198 return securityConfig; 199 } 200 201 /** 202 * returns the configuration of the used rights management registry 203 * 204 * @return the configuration of the used rights management registry 205 * @throws SecurityConfigurationException 206 */ 207 private RegistryConfig getRegistryConfig() 208 throws SecurityConfigurationException { 209 RegistryConfig registryConfig = null; 210 String xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Driver"; 211 212 try { 213 String driver = XMLTools.getNodeAsString( doc, xpath, nsContext, null ); 214 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Url"; 215 String logon = XMLTools.getNodeAsString( doc, xpath, nsContext, null ); 216 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:User"; 217 String user = XMLTools.getNodeAsString( doc, xpath, nsContext, null ); 218 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Password"; 219 String password = XMLTools.getNodeAsString( doc, xpath, nsContext, null ); 220 if ( driver != null && logon != null ) { 221 DefaultDBConnection con = new DefaultDBConnection( driver, logon, user, password ); 222 registryConfig = new RegistryConfig( con ); 223 } else if ( ( driver != null && logon == null ) || ( driver == null && logon != null ) ) { 224 throw new SecurityConfigurationException( Messages.getString( "PolicyDocument.DatabaseConnection" ) ); 225 } 226 } catch ( XMLParsingException e ) { 227 throw new SecurityConfigurationException( e.getMessage() ); 228 } 229 230 // } catch ( Exception e ) { 231 // LOG.logError( e.getMessage(), e ); 232 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); 233 // } 234 return registryConfig; 235 } 236 237 /** 238 * returns the settings for accessing the authentification authority 239 * 240 * @return the settings for accessing the authentification authority 241 * @throws SecurityConfigurationException 242 */ 243 private AuthentificationSettings getAuthentificationSettings() 244 throws SecurityConfigurationException { 245 AuthentificationSettings authSet = null; 246 247 StringBuffer xpath = new StringBuffer( "/dgsec:OWSPolicy/dgsec:Security/" ); 248 xpath.append( "dgsec:AuthentificationSettings/dgsec:AuthentificationService" ); 249 xpath.append( "/dgsec:OnlineResource/@xlink:href" ); 250 try { 251 String onlineRes = XMLTools.getNodeAsString( doc, xpath.toString(), nsContext, null ); 252 if ( onlineRes != null ) { 253 BaseURL baseURL = new BaseURL( null, new URL( onlineRes ) ); 254 authSet = new AuthentificationSettings( baseURL ); 255 } 256 } catch ( XMLParsingException e ) { 257 throw new SecurityConfigurationException( e.getMessage() ); 258 } catch ( MalformedURLException e ) { 259 throw new SecurityConfigurationException( e.getMessage() ); 260 } 261 262 // } catch ( Exception e ) { 263 // LOG.logError( e.getMessage(), e ); 264 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); 265 // } 266 267 return authSet; 268 } 269 270 /** 271 * @return returns the requests described by the policy document 272 */ 273 private Request[] getRequests() 274 throws SecurityConfigurationException { 275 Request[] requests = null; 276 // try { 277 List<Node> nl = null; 278 try { 279 nl = XMLTools.getNodes( doc, "/dgsec:OWSPolicy/dgsec:Requests/*", nsContext ); 280 } catch ( XMLParsingException e ) { 281 throw new SecurityConfigurationException( e.getMessage() ); 282 } 283 if ( nl != null ) { 284 requests = new Request[nl.size()]; 285 for ( int i = 0; i < requests.length; i++ ) { 286 requests[i] = getRequest( (Element) nl.get( i ) ); 287 } 288 } 289 // } catch ( Exception e ) { 290 // LOG.logError( e.getMessage(), e ); 291 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); 292 // } 293 return requests; 294 } 295 296 /** 297 * returns the requests described by the passed <tt>Element</tt> 298 * 299 * @param element 300 * @return created <tt>Request</tt> 301 * @throws SecurityConfigurationException 302 */ 303 private Request getRequest( Element element ) 304 throws SecurityConfigurationException { 305 String name = element.getLocalName(); 306 Request request = null; 307 Condition preCon = null; 308 Condition postCon = null; 309 310 try { 311 boolean any = XMLTools.getNode( element, "./dgsec:PreConditions/dgsec:Any", nsContext ) != null; 312 if ( any ) { 313 preCon = new Condition( true ); 314 } else { 315 List<Node> nl = XMLTools.getNodes( element, "./dgsec:PreConditions/dgsec:Parameter", nsContext ); 316 OperationParameter[] op = new OperationParameter[nl.size()]; 317 for ( int i = 0; i < nl.size(); i++ ) { 318 op[i] = getOperationParameter( (Element) nl.get( i ) ); 319 } 320 preCon = new Condition( op ); 321 } 322 323 any = XMLTools.getNode( element, "./dgsec:PostConditions/dgsec:Any", nsContext ) != null; 324 if ( any ) { 325 postCon = new Condition( true ); 326 } else { 327 List<Node> nl = XMLTools.getNodes( element, "./dgsec:PostConditions/dgsec:Parameter", nsContext ); 328 OperationParameter[] op = new OperationParameter[nl.size()]; 329 for ( int i = 0; i < nl.size(); i++ ) { 330 op[i] = getOperationParameter( (Element) nl.get( i ) ); 331 } 332 postCon = new Condition( op ); 333 } 334 request = new Request( service, name, preCon, postCon ); 335 } catch ( XMLParsingException e ) { 336 LOG.logError( e.getMessage(), e ); 337 throw new SecurityConfigurationException( e.getMessage() ); 338 } 339 340 // } catch ( Exception e ) { 341 // LOG.logError( e.getMessage(), e ); 342 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); 343 // } 344 345 return request; 346 } 347 348 /** 349 * creates an <tt>OperationParameter</tt> with the passed name from the also passed root XPath. A root XPath is an 350 * expression to the desired parameter node. 351 * 352 * @param name 353 * name of the OperationParameter 354 * @param xpathRoot 355 * @return the parameter 356 * @throws SecurityConfigurationException 357 */ 358 private OperationParameter getOperationParameter( String name, String xpathRoot ) 359 throws SecurityConfigurationException { 360 OperationParameter op = null; 361 // try { 362 try { 363 if ( XMLTools.getNodes( doc, xpathRoot, nsContext ).size() == 0 ) { 364 // return OperationParameter that denies any access 365 return new OperationParameter( name, false ); 366 } 367 // is parameter coupled to user specific rights 368 String tmp = XMLTools.getRequiredNodeAsString( doc, xpathRoot + "/@userCoupled", nsContext ).toLowerCase(); 369 boolean userCoupled = tmp.equals( "true" ) || tmp.equals( "1" ); 370 371 // is any? -> no restrictions 372 tmp = XMLTools.getNodeAsString( doc, xpathRoot + "/dgsec:Any", nsContext, "false" ); 373 boolean any = !tmp.equals( "false" ); 374 375 if ( !any ) { 376 // get values if not 'any' 377 List<Element> list = XMLTools.getElements( doc, xpathRoot + "/dgsec:Value", nsContext ); 378 List<String> valueList = null; 379 if ( list != null ) { 380 valueList = new ArrayList<String>( list.size() ); 381 for ( int j = 0; j < list.size(); j++ ) { 382 valueList.add( XMLTools.getStringValue( list.get( j ) ) ); 383 } 384 } 385 list = XMLTools.getElements( doc, xpathRoot + "/dgsec:ComplexValue/*", nsContext ); 386 op = new OperationParameter( name, valueList, list, userCoupled ); 387 } else { 388 op = new OperationParameter( name, any ); 389 } 390 } catch ( XMLParsingException e ) { 391 LOG.logError( e.getMessage(), e ); 392 throw new SecurityConfigurationException( e.getMessage() ); 393 } 394 395 // } catch ( Exception e ) { 396 // LOG.logError( e.getMessage(), e ); 397 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) ); 398 // } 399 return op; 400 } 401 402 /** 403 * creates an <tt>OperationParameter</tt> from the passed element. 404 * 405 * @param element 406 * encapsulating a parameter 407 * @return created <tt>OperationParameter</tt> 408 * @throws XMLParsingException 409 */ 410 private OperationParameter getOperationParameter( Element element ) 411 throws XMLParsingException { 412 OperationParameter op = null; 413 String name = XMLTools.getRequiredAttrValue( "name", null, element ); 414 String uc = XMLTools.getAttrValue( element, null, "userCoupled", "false" ); 415 boolean userCoupled = uc.equals( "true" ) || uc.equals( "1" ); 416 boolean any = XMLTools.getNode( element, "dgsec:Any", nsContext ) != null; 417 if ( !any ) { 418 List<Element> list = XMLTools.getElements( element, "dgsec:Value", nsContext ); 419 List<String> valueList = null; 420 if ( list != null ) { 421 valueList = new ArrayList<String>( list.size() ); 422 for ( int j = 0; j < list.size(); j++ ) { 423 valueList.add( XMLTools.getStringValue( list.get( j ) ) ); 424 } 425 } 426 list = XMLTools.getElements( element, "dgsec:ComplexValue/*", nsContext ); 427 op = new OperationParameter( name, valueList, list, userCoupled ); 428 } else { 429 op = new OperationParameter( name, any ); 430 } 431 432 return op; 433 } 434 435 }