001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/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 08:39:07 -0800 (Thu, 27 Dec 2007) $
078: */
079: public class PolicyDocument {
080:
081: private ILogger LOG = LoggerFactory.getLogger(PolicyDocument.class);
082:
083: private static final NamespaceContext nsContext = CommonNamespaces
084: .getNamespaceContext();
085:
086: private Document doc = null;
087:
088: private String service = null;
089:
090: /**
091: * @param url
092: * @throws SecurityConfigurationException
093: */
094: public PolicyDocument(URL url)
095: throws SecurityConfigurationException {
096: try {
097: Reader reader = new InputStreamReader(url.openStream());
098: doc = XMLTools.parse(reader);
099: service = XMLTools.getRequiredAttrValue("service", null,
100: doc.getDocumentElement());
101: } catch (Exception e) {
102: LOG.logError(e.getMessage(), e);
103: throw new SecurityConfigurationException(StringTools
104: .stackTraceToString(e));
105: }
106: }
107:
108: /**
109: * @param doc
110: * document containing a policy document
111: * @throws SecurityConfigurationException
112: */
113: public PolicyDocument(Document doc)
114: throws SecurityConfigurationException {
115: this .doc = doc;
116: try {
117: service = XMLTools.getRequiredAttrValue("service", null,
118: doc.getDocumentElement());
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() throws SecurityConfigurationException,
133: XMLParsingException {
134: Condition general = getGeneralCondition();
135: SecurityConfig sc = null;
136: String dgSecPrefix = CommonNamespaces.DGSEC_PREFIX;
137: List<Node> nl = XMLTools.getNodes(doc, "/" + dgSecPrefix
138: + ":OWSPolicy/" + dgSecPrefix + ":Security", nsContext);
139: if (nl.size() > 0) {
140: sc = getSecuityConfig();
141: }
142: Request[] requests = getRequests();
143: return new Policy(sc, general, requests);
144: }
145:
146: /**
147: * @return Returns the generalCondition.
148: */
149: private Condition getGeneralCondition()
150: throws SecurityConfigurationException {
151: Condition condition = null;
152: OperationParameter[] op = new OperationParameter[4];
153: String xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'getContentLength']";
154: op[0] = getOperationParameter("getContentLength", xpath);
155: xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'postContentLength']";
156: op[1] = getOperationParameter("postContentLength", xpath);
157: xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'httpHeader']";
158: op[2] = getOperationParameter("httpHeader", xpath);
159: xpath = "/dgsec:OWSPolicy/dgsec:GeneralConditions/dgsec:Conditions/dgsec:Parameter[@name = 'requestMethod']";
160: op[3] = getOperationParameter("requestType", xpath);
161: condition = new Condition(op);
162: // } catch ( Exception e ) {
163: // LOG.logError( e.getMessage(), e );
164: // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
165: // }
166: return condition;
167: }
168:
169: /**
170: * @return the secuityConfig.
171: */
172: private SecurityConfig getSecuityConfig()
173: throws SecurityConfigurationException {
174: SecurityConfig securityConfig = null;
175:
176: String xpath = null;
177: xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryClass";
178:
179: try {
180: String regClass = XMLTools.getNodeAsString(doc, xpath,
181: nsContext, "org.deegree.security.drm.SQLRegistry");
182: xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:ReadWriteTimeout";
183: String tmp = XMLTools.getNodeAsString(doc, xpath,
184: nsContext, "300");
185: int readWriteTimeout = Integer.parseInt(tmp);
186: RegistryConfig registryConfig = getRegistryConfig();
187: AuthentificationSettings authSet = getAuthentificationSettings();
188: securityConfig = new SecurityConfig(regClass,
189: readWriteTimeout, registryConfig, authSet);
190:
191: } catch (XMLParsingException e) {
192: throw new SecurityConfigurationException(e.getMessage());
193: }
194: //
195: // } catch ( Exception e ) {
196: // LOG.logError( e.getMessage(), e );
197: // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
198: // }
199:
200: return securityConfig;
201: }
202:
203: /**
204: * returns the configuration of the used rights management registry
205: *
206: * @return the configuration of the used rights management registry
207: * @throws SecurityConfigurationException
208: */
209: private RegistryConfig getRegistryConfig()
210: throws SecurityConfigurationException {
211: RegistryConfig registryConfig = null;
212: String xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Driver";
213:
214: try {
215: String driver = XMLTools.getNodeAsString(doc, xpath,
216: nsContext, null);
217: xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Url";
218: String logon = XMLTools.getNodeAsString(doc, xpath,
219: nsContext, null);
220: xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:User";
221: String user = XMLTools.getNodeAsString(doc, xpath,
222: nsContext, null);
223: xpath = "/dgsec:OWSPolicy/dgsec:Security/dgsec:RegistryConfig/dgjdbc:JDBCConnection/dgjdbc:Password";
224: String password = XMLTools.getNodeAsString(doc, xpath,
225: nsContext, null);
226: if (driver != null && logon != null) {
227: DefaultDBConnection con = new DefaultDBConnection(
228: driver, logon, user, password);
229: registryConfig = new RegistryConfig(con);
230: } else if ((driver != null && logon == null)
231: || (driver == null && logon != null)) {
232: throw new SecurityConfigurationException(Messages
233: .getString("PolicyDocument.DatabaseConnection"));
234: }
235: } catch (XMLParsingException e) {
236: throw new SecurityConfigurationException(e.getMessage());
237: }
238:
239: // } catch ( Exception e ) {
240: // LOG.logError( e.getMessage(), e );
241: // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
242: // }
243: return registryConfig;
244: }
245:
246: /**
247: * returns the settings for accessing the authentification authority
248: *
249: * @return the settings for accessing the authentification authority
250: * @throws SecurityConfigurationException
251: */
252: private AuthentificationSettings getAuthentificationSettings()
253: throws SecurityConfigurationException {
254: AuthentificationSettings authSet = null;
255:
256: StringBuffer xpath = new StringBuffer(
257: "/dgsec:OWSPolicy/dgsec:Security/");
258: xpath
259: .append("dgsec:AuthentificationSettings/dgsec:AuthentificationService");
260: xpath.append("/dgsec:OnlineResource/@xlink:href");
261: try {
262: String onlineRes = XMLTools.getNodeAsString(doc, xpath
263: .toString(), nsContext, null);
264: if (onlineRes != null) {
265: BaseURL baseURL = new BaseURL(null, new URL(onlineRes));
266: authSet = new AuthentificationSettings(baseURL);
267: }
268: } catch (XMLParsingException e) {
269: throw new SecurityConfigurationException(e.getMessage());
270: } catch (MalformedURLException e) {
271: throw new SecurityConfigurationException(e.getMessage());
272: }
273:
274: // } catch ( Exception e ) {
275: // LOG.logError( e.getMessage(), e );
276: // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
277: // }
278:
279: return authSet;
280: }
281:
282: /**
283: * @return returns the requests described by the policy document
284: */
285: private Request[] getRequests()
286: throws SecurityConfigurationException {
287: Request[] requests = null;
288: // try {
289: List<Node> nl = null;
290: try {
291: nl = XMLTools.getNodes(doc,
292: "/dgsec:OWSPolicy/dgsec:Requests/*", nsContext);
293: } catch (XMLParsingException e) {
294: throw new SecurityConfigurationException(e.getMessage());
295: }
296: if (nl != null) {
297: requests = new Request[nl.size()];
298: for (int i = 0; i < requests.length; i++) {
299: requests[i] = getRequest((Element) nl.get(i));
300: }
301: }
302: // } catch ( Exception e ) {
303: // LOG.logError( e.getMessage(), e );
304: // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
305: // }
306: return requests;
307: }
308:
309: /**
310: * returns the requests described by the passed <tt>Element</tt>
311: *
312: * @param element
313: * @return created <tt>Request</tt>
314: * @throws SecurityConfigurationException
315: */
316: private Request getRequest(Element element)
317: throws SecurityConfigurationException {
318: String name = element.getLocalName();
319: Request request = null;
320: Condition preCon = null;
321: Condition postCon = null;
322:
323: try {
324: List<Node> nl = XMLTools.getNodes(element,
325: "./dgsec:PreConditions/dgsec:Parameter", nsContext);
326: OperationParameter[] op = new OperationParameter[nl.size()];
327: for (int i = 0; i < nl.size(); i++) {
328: op[i] = getOperationParameter((Element) nl.get(i));
329: }
330: preCon = new Condition(op);
331:
332: nl = XMLTools
333: .getNodes(element,
334: "./dgsec:PostConditions/dgsec:Parameter",
335: nsContext);
336: op = new OperationParameter[nl.size()];
337: for (int i = 0; i < nl.size(); i++) {
338: op[i] = getOperationParameter((Element) nl.get(i));
339: }
340: postCon = new Condition(op);
341: request = new Request(service, name, preCon, postCon);
342: } catch (XMLParsingException e) {
343: LOG.logError(e.getMessage(), e);
344: throw new SecurityConfigurationException(e.getMessage());
345: }
346:
347: // } catch ( Exception e ) {
348: // LOG.logError( e.getMessage(), e );
349: // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
350: // }
351:
352: return request;
353: }
354:
355: /**
356: * creates an <tt>OperationParameter</tt> with the passed name from the also passed root XPath. A root XPath is an
357: * expression to the desired parameter node.
358: *
359: * @param name
360: * name of the OperationParameter
361: * @param xpathRoot
362: * @return the parameter
363: * @throws SecurityConfigurationException
364: */
365: private OperationParameter getOperationParameter(String name,
366: String xpathRoot) throws SecurityConfigurationException {
367: OperationParameter op = null;
368: // try {
369: try {
370: if (XMLTools.getNodes(doc, xpathRoot, nsContext).size() == 0) {
371: // return OperationParameter that denies any access
372: return new OperationParameter(name, false);
373: }
374: // is parameter coupled to user specific rights
375: String tmp = XMLTools.getRequiredNodeAsString(doc,
376: xpathRoot + "/@userCoupled", nsContext)
377: .toLowerCase();
378: boolean userCoupled = tmp.equals("true") || tmp.equals("1");
379:
380: // is any? -> no restrictions
381: tmp = XMLTools.getNodeAsString(doc, xpathRoot
382: + "/dgsec:Any", nsContext, "false");
383: boolean any = !tmp.equals("false");
384:
385: if (!any) {
386: // get values if not 'any'
387: List<Element> list = XMLTools.getElements(doc,
388: xpathRoot + "/dgsec:Value", nsContext);
389: List<String> valueList = null;
390: if (list != null) {
391: valueList = new ArrayList<String>(list.size());
392: for (int j = 0; j < list.size(); j++) {
393: valueList.add(XMLTools.getStringValue(list
394: .get(j)));
395: }
396: }
397: list = XMLTools.getElements(doc, xpathRoot
398: + "/dgsec:ComplexValue/*", nsContext);
399: op = new OperationParameter(name, valueList, list,
400: userCoupled);
401: } else {
402: op = new OperationParameter(name, any);
403: }
404: } catch (XMLParsingException e) {
405: LOG.logError(e.getMessage(), e);
406: throw new SecurityConfigurationException(e.getMessage());
407: }
408:
409: // } catch ( Exception e ) {
410: // LOG.logError( e.getMessage(), e );
411: // throw new SecurityConfigurationException( StringTools.stackTraceToString( e ) );
412: // }
413: return op;
414: }
415:
416: /**
417: * creates an <tt>OperationParameter</tt> from the passed element.
418: *
419: * @param element
420: * encapsulating a parameter
421: * @return created <tt>OperationParameter</tt>
422: * @throws XMLParsingException
423: */
424: private OperationParameter getOperationParameter(Element element)
425: throws XMLParsingException {
426: OperationParameter op = null;
427: String name = XMLTools.getRequiredAttrValue("name", null,
428: element);
429: String uc = XMLTools.getAttrValue(element, null, "userCoupled",
430: "false");
431: boolean userCoupled = uc.equals("true") || uc.equals("1");
432: boolean any = XMLTools.getNode(element, "dgsec:Any", nsContext) != null;
433: if (!any) {
434: List<Element> list = XMLTools.getElements(element,
435: "dgsec:Value", nsContext);
436: List<String> valueList = null;
437: if (list != null) {
438: valueList = new ArrayList<String>(list.size());
439: for (int j = 0; j < list.size(); j++) {
440: valueList.add(XMLTools.getStringValue(list.get(j)));
441: }
442: }
443: list = XMLTools.getElements(element,
444: "dgsec:ComplexValue/*", nsContext);
445: op = new OperationParameter(name, valueList, list,
446: userCoupled);
447: } else {
448: op = new OperationParameter(name, any);
449: }
450:
451: return op;
452: }
453:
454: }
|