001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/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: mschneider $
069 *
070 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $
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 /**
113 * returns the <tt>Policy</tt> created from the encapsulated DOM abject.
114 *
115 * @return the <tt>Policy</tt> created from the encapsulated DOM abject.
116 * @throws SecurityConfigurationException
117 * @throws XMLParsingException
118 */
119 public Policy getPolicy()
120 throws SecurityConfigurationException, XMLParsingException {
121 Condition general = getGeneralCondition();
122 SecurityConfig sc = null;
123 String dgSecPrefix = CommonNamespaces.DGSEC_PREFIX;
124 List<Node> nl = XMLTools.getNodes( doc, "/" + dgSecPrefix + ":OWSPolicy/" + dgSecPrefix + ":Security",
125 nsContext );
126 if ( nl.size() > 0 ) {
127 sc = getSecuityConfig();
128 }
129 Request[] requests = getRequests();
130 return new Policy( sc, general, requests );
131 }
132
133 /**
134 * @return Returns the generalCondition.
135 */
136 private Condition getGeneralCondition()
137 throws SecurityConfigurationException {
138 Condition condition = null;
139 OperationParameter[] op = new OperationParameter[4];
140 String xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'getContentLength']";
141 op[0] = getOperationParameter( "getContentLength", xpath );
142 xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'postContentLength']";
143 op[1] = getOperationParameter( "postContentLength", xpath );
144 xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'httpHeader']";
145 op[2] = getOperationParameter( "httpHeader", xpath );
146 xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'requestMethod']";
147 op[3] = getOperationParameter( "requestType", xpath );
148 condition = new Condition( op );
149 // } catch ( Exception e ) {
150 // LOG.logError( e.getMessage(), e );
151 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
152 // }
153 return condition;
154 }
155
156 /**
157 * @return the secuityConfig.
158 */
159 private SecurityConfig getSecuityConfig()
160 throws SecurityConfigurationException {
161 SecurityConfig securityConfig = null;
162
163 String xpath = null;
164 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryClass";
165
166 try {
167 String regClass = XMLTools.getNodeAsString( doc, xpath, nsContext, "org.deegree.security.drm.SQLRegistry" );
168 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:ReadWriteTimeout";
169 String tmp = XMLTools.getNodeAsString( doc, xpath, nsContext, "300" );
170 int readWriteTimeout = Integer.parseInt( tmp );
171 RegistryConfig registryConfig = getRegistryConfig();
172 AuthentificationSettings authSet = getAuthentificationSettings();
173 securityConfig = new SecurityConfig( regClass, readWriteTimeout, registryConfig, authSet );
174
175 } catch ( XMLParsingException e ) {
176 throw new SecurityConfigurationException( e.getMessage() );
177 }
178 //
179 // } catch ( Exception e ) {
180 // LOG.logError( e.getMessage(), e );
181 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
182 // }
183
184 return securityConfig;
185 }
186
187 /**
188 * returns the configuration of the used rights management registry
189 *
190 * @return the configuration of the used rights management registry
191 * @throws SecurityConfigurationException
192 */
193 private RegistryConfig getRegistryConfig()
194 throws SecurityConfigurationException {
195 RegistryConfig registryConfig = null;
196 String xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Driver";
197
198 try {
199 String driver = XMLTools.getNodeAsString( doc, xpath, nsContext, null );
200 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Url";
201 String logon = XMLTools.getNodeAsString( doc, xpath, nsContext, null );
202 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:User";
203 String user = XMLTools.getNodeAsString( doc, xpath, nsContext, null );
204 xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Password";
205 String password = XMLTools.getNodeAsString( doc, xpath, nsContext, null );
206 if ( driver != null && logon != null ) {
207 DefaultDBConnection con = new DefaultDBConnection( driver, logon, user, password );
208 registryConfig = new RegistryConfig( con );
209 } else if ( ( driver != null && logon == null ) || ( driver == null && logon != null ) ) {
210 throw new SecurityConfigurationException( Messages.getString( "PolicyDocument.DatabaseConnection" ) );
211 }
212 } catch ( XMLParsingException e ) {
213 throw new SecurityConfigurationException( e.getMessage() );
214 }
215
216 // } catch ( Exception e ) {
217 // LOG.logError( e.getMessage(), e );
218 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
219 // }
220 return registryConfig;
221 }
222
223 /**
224 * returns the settings for accessing the authentification authority
225 *
226 * @return the settings for accessing the authentification authority
227 * @throws SecurityConfigurationException
228 */
229 private AuthentificationSettings getAuthentificationSettings()
230 throws SecurityConfigurationException {
231 AuthentificationSettings authSet = null;
232
233 StringBuffer xpath = new StringBuffer( "/dgsec:OWSPolicy/dgsec:Security/" );
234 xpath.append( "dgsec:AuthentificationSettings/dgsec:AuthentificationService" );
235 xpath.append( "/dgsec:OnlineResource/@xlink:href" );
236 try {
237 String onlineRes = XMLTools.getNodeAsString( doc, xpath.toString(), nsContext, null );
238 if ( onlineRes != null ) {
239 BaseURL baseURL = new BaseURL( null, new URL( onlineRes ) );
240 authSet = new AuthentificationSettings( baseURL );
241 }
242 } catch ( XMLParsingException e ) {
243 throw new SecurityConfigurationException( e.getMessage() );
244 } catch ( MalformedURLException e ) {
245 throw new SecurityConfigurationException( e.getMessage() );
246 }
247
248 // } catch ( Exception e ) {
249 // LOG.logError( e.getMessage(), e );
250 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
251 // }
252
253 return authSet;
254 }
255
256 /**
257 * @return returns the requests described by the policy document
258 */
259 private Request[] getRequests()
260 throws SecurityConfigurationException {
261 Request[] requests = null;
262 // try {
263 List<Node> nl = null;
264 try {
265 nl = XMLTools.getNodes( doc, "/dgsec:OWSPolicy/dgsec:Requests/*", nsContext );
266 } catch ( XMLParsingException e ) {
267 throw new SecurityConfigurationException( e.getMessage() );
268 }
269 if ( nl != null ) {
270 requests = new Request[nl.size()];
271 for ( int i = 0; i < requests.length; i++ ) {
272 requests[i] = getRequest( (Element) nl.get( i ) );
273 }
274 }
275 // } catch ( Exception e ) {
276 // LOG.logError( e.getMessage(), e );
277 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
278 // }
279 return requests;
280 }
281
282 /**
283 * returns the requests described by the passed <tt>Element</tt>
284 *
285 * @param element
286 * @return created <tt>Request</tt>
287 * @throws SecurityConfigurationException
288 */
289 private Request getRequest( Element element )
290 throws SecurityConfigurationException {
291 String name = element.getLocalName();
292 Request request = null;
293 Condition preCon = null;
294 Condition postCon = null;
295
296 try {
297 boolean any = XMLTools.getNode( element, "./dgsec:PreConditions/dgsec:Any", nsContext ) != null;
298 if ( any ) {
299 preCon = new Condition( true );
300 } else {
301 List<Node> nl = XMLTools.getNodes( element, "./dgsec:PreConditions/dgsec:Parameter", nsContext );
302 OperationParameter[] op = new OperationParameter[nl.size()];
303 for ( int i = 0; i < nl.size(); i++ ) {
304 op[i] = getOperationParameter( (Element) nl.get( i ) );
305 }
306 preCon = new Condition( op );
307 }
308
309 any = XMLTools.getNode( element, "./dgsec:PostConditions/dgsec:Any", nsContext ) != null;
310 if ( any ) {
311 postCon = new Condition( true );
312 } else {
313 List<Node> nl = XMLTools.getNodes( element, "./dgsec:PostConditions/dgsec:Parameter", nsContext );
314 OperationParameter[] op = new OperationParameter[nl.size()];
315 for ( int i = 0; i < nl.size(); i++ ) {
316 op[i] = getOperationParameter( (Element) nl.get( i ) );
317 }
318 postCon = new Condition( op );
319 }
320 request = new Request( service, name, preCon, postCon );
321 } catch ( XMLParsingException e ) {
322 LOG.logError( e.getMessage(), e );
323 throw new SecurityConfigurationException( e.getMessage() );
324 }
325
326 // } catch ( Exception e ) {
327 // LOG.logError( e.getMessage(), e );
328 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
329 // }
330
331 return request;
332 }
333
334 /**
335 * creates an <tt>OperationParameter</tt> with the passed name from the also passed root
336 * XPath. A root XPath is an expression to the desired parameter node.
337 *
338 * @param name
339 * name of the OperationParameter
340 * @param xpathRoot
341 * @return the parameter
342 * @throws SecurityConfigurationException
343 */
344 private OperationParameter getOperationParameter( String name, String xpathRoot )
345 throws SecurityConfigurationException {
346 OperationParameter op = null;
347 // try {
348 try {
349 if ( XMLTools.getNodes( doc, xpathRoot, nsContext ).size() == 0 ) {
350 // return OperationParameter that denies any access
351 return new OperationParameter( name, false );
352 }
353 // is parameter coupled to user specific rights
354 String tmp = XMLTools.getRequiredNodeAsString( doc, xpathRoot + "/@userCoupled", nsContext ).toLowerCase();
355 boolean userCoupled = tmp.equals( "true" ) || tmp.equals( "1" );
356
357 // is any? -> no restrictions
358 tmp = XMLTools.getNodeAsString( doc, xpathRoot + "/dgsec:Any", nsContext, "false" );
359 boolean any = !tmp.equals( "false" );
360
361 if ( !any ) {
362 // get values if not 'any'
363 List<Element> list = XMLTools.getElements( doc, xpathRoot + "/dgsec:Value", nsContext );
364 List<String> valueList = null;
365 if ( list != null ) {
366 valueList = new ArrayList<String>( list.size() );
367 for ( int j = 0; j < list.size(); j++ ) {
368 valueList.add( XMLTools.getStringValue( list.get( j ) ) );
369 }
370 }
371 list = XMLTools.getElements( doc, xpathRoot + "/dgsec:ComplexValue/*", nsContext );
372 op = new OperationParameter( name, valueList, list, userCoupled );
373 } else {
374 op = new OperationParameter( name, any );
375 }
376 } catch ( XMLParsingException e ) {
377 LOG.logError( e.getMessage(), e );
378 throw new SecurityConfigurationException( e.getMessage() );
379 }
380
381 // } catch ( Exception e ) {
382 // LOG.logError( e.getMessage(), e );
383 // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
384 // }
385 return op;
386 }
387
388 /**
389 * creates an <tt>OperationParameter</tt> from the passed element.
390 *
391 * @param element
392 * encapsulating a parameter
393 * @return created <tt>OperationParameter</tt>
394 * @throws XMLParsingException
395 */
396 private OperationParameter getOperationParameter( Element element )
397 throws XMLParsingException {
398 OperationParameter op = null;
399 String name = XMLTools.getRequiredAttrValue( "name", null, element );
400 String uc = XMLTools.getAttrValue( element, null, "userCoupled", "false" );
401 boolean userCoupled = uc.equals( "true" ) || uc.equals( "1" );
402 boolean any = XMLTools.getNode( element, "dgsec:Any", nsContext ) != null;
403 if ( !any ) {
404 List<Element> list = XMLTools.getElements( element, "dgsec:Value", nsContext );
405 List<String> valueList = null;
406 if ( list != null ) {
407 valueList = new ArrayList<String>( list.size() );
408 for ( int j = 0; j < list.size(); j++ ) {
409 valueList.add( XMLTools.getStringValue( list.get( j ) ) );
410 }
411 }
412 list = XMLTools.getElements( element, "dgsec:ComplexValue/*", nsContext );
413 op = new OperationParameter( name, valueList, list, userCoupled );
414 } else {
415 op = new OperationParameter( name, any );
416 }
417
418 return op;
419 }
420
421 }