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 }