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