1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 package org.apache.xml.security.test.utils.resolver;
20 
21 import java.io.FileInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.net.URI;
25 import java.net.URISyntaxException;
26 import java.util.HashMap;
27 import java.util.Map;
28 
29 import org.apache.xml.security.signature.XMLSignatureInput;
30 import org.apache.xml.security.utils.resolver.ResourceResolverException;
31 import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
32 import org.w3c.dom.Attr;
33 
34 /**
35  * This class helps us home users to resolve http URIs without a network
36  * connection.
37  * <BR />
38  * The OfflineResolver is only needed for Unit testing. This is not needed for
39  * a production environment. It's a very simple cache/proxy to HTTP space
40  * so that I can do unit testing with http:// URIs even if I'm not connected
41  * to the internet.
42  *
43  */
44 public class OfflineResolver extends ResourceResolverSpi {
45 
46     /** {@link org.apache.commons.logging} logging facility */
47     static org.apache.commons.logging.Log log =
48         org.apache.commons.logging.LogFactory.getLog(OfflineResolver.class.getName());
49 
50     /** Field _uriMap */
51     static Map<String, String> _uriMap = null;
52 
53     /** Field _mimeMap */
54     static Map<String, String> _mimeMap = null;
55 
56     static {
org.apache.xml.security.Init.init()57         org.apache.xml.security.Init.init();
58 
59         _uriMap = new HashMap<String, String>();
60         _mimeMap = new HashMap<String, String>();
61 
62         String basedir =
63             System.getProperty("basedir") == null ? "./": System.getProperty("basedir") + "/";
64 
65         OfflineResolver.register(
66             "http://www.w3.org/TR/xml-stylesheet",
67             basedir + "src/test/resources/org/w3c/www/TR/xml-stylesheet.html", "text/html"
68         );
69         OfflineResolver.register(
70             "http://www.w3.org/TR/2000/REC-xml-20001006",
71             basedir + "src/test/resources/org/w3c/www/TR/2000/REC-xml-20001006", "text/xml"
72         );
73         OfflineResolver.register(
74             "http://www.nue.et-inf.uni-siegen.de/index.html",
75             basedir + "src/test/resources/org/apache/xml/security/temp/nuehomepage", "text/html"
76         );
77         OfflineResolver.register(
78             "http://www.nue.et-inf.uni-siegen.de/~geuer-pollmann/id2.xml",
79             basedir + "src/test/resources/org/apache/xml/security/temp/id2.xml", "text/xml"
80         );
81         OfflineResolver.register(
82             "http://xmldsig.pothole.com/xml-stylesheet.txt",
83              basedir + "src/test/resources/com/pothole/xmldsig/xml-stylesheet.txt", "text/xml"
84         );
85         OfflineResolver.register(
86             "http://www.w3.org/Signature/2002/04/xml-stylesheet.b64",
87             basedir
88             + "src/test/resources/ie/baltimore/merlin-examples/merlin-xmldsig-twenty-three/xml-stylesheet.b64",
89             "text/plain"
90         );
91     }
92 
93     /**
94      * Method engineResolve
95      *
96      * @param uri
97      * @param BaseURI
98      *
99      * @throws ResourceResolverException
100      */
engineResolve(Attr uri, String BaseURI)101     public XMLSignatureInput engineResolve(Attr uri, String BaseURI)
102         throws ResourceResolverException {
103         try {
104             String URI = uri.getNodeValue();
105 
106             if (OfflineResolver._uriMap.containsKey(URI)) {
107                 String newURI = (String) OfflineResolver._uriMap.get(URI);
108 
109                 log.debug("Mapped " + URI + " to " + newURI);
110 
111                 InputStream is = new FileInputStream(newURI);
112 
113                 log.debug("Available bytes = " + is.available());
114 
115                 XMLSignatureInput result = new XMLSignatureInput(is);
116 
117                 // XMLSignatureInput result = new XMLSignatureInput(inputStream);
118                 result.setSourceURI(URI);
119                 result.setMIMEType((String) OfflineResolver._mimeMap.get(URI));
120 
121                 return result;
122             } else {
123                 Object exArgs[] = {"The URI " + URI + " is not configured for offline work" };
124 
125                 throw new ResourceResolverException(
126                     "generic.EmptyMessage", exArgs, uri, BaseURI
127                 );
128             }
129         } catch (IOException ex) {
130             throw new ResourceResolverException("generic.EmptyMessage", ex, uri, BaseURI);
131         }
132     }
133 
134     /**
135      * We resolve http URIs <I>without</I> fragment...
136      *
137      * @param uri
138      * @param BaseURI
139      */
engineCanResolve(Attr uri, String BaseURI)140     public boolean engineCanResolve(Attr uri, String BaseURI) {
141         String uriNodeValue = uri.getNodeValue();
142         if (uriNodeValue.equals("") || uriNodeValue.startsWith("#")) {
143             return false;
144         }
145 
146         URI uriNew = null;
147         try {
148             uriNew = getNewURI(uri.getNodeValue(), BaseURI);
149             if (uriNew.getScheme().equals("http")) {
150                 log.debug("I state that I can resolve " + uriNew.toString());
151                 return true;
152             }
153 
154         } catch (URISyntaxException ex) {
155             //
156         }
157 
158         return false;
159     }
160 
161     /**
162      * Method register
163      *
164      * @param URI
165      * @param filename
166      * @param MIME
167      */
register(String URI, String filename, String MIME)168     private static void register(String URI, String filename, String MIME) {
169         OfflineResolver._uriMap.put(URI, filename);
170         OfflineResolver._mimeMap.put(URI, MIME);
171     }
172 
getNewURI(String uri, String baseURI)173     private static URI getNewURI(String uri, String baseURI) throws URISyntaxException {
174         URI newUri = null;
175         if (baseURI == null || "".equals(baseURI)) {
176             newUri = new URI(uri);
177         } else {
178             newUri = new URI(baseURI).resolve(uri);
179         }
180 
181         // if the URI contains a fragment, ignore it
182         if (newUri.getFragment() != null) {
183             URI uriNewNoFrag =
184                 new URI(newUri.getScheme(), newUri.getSchemeSpecificPart(), null);
185             return uriNewNoFrag;
186         }
187         return newUri;
188     }
189 
190 }
191