001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/security/owsrequestvalidator/PolicyDocument.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2007 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: rbezema $
076 *
077 * @version $Revision: 7484 $, $Date: 2007-06-06 13:07:13 +0200 (Mi, 06 Jun 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 }