URLHandler | Line # 55 | 38 | 7 | 76.7% |
0.7671233
|
No Tests | |||
1 | /* | |
2 | * Copyright (c) 2000-2005, University of Salford | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions are met: | |
7 | * | |
8 | * Redistributions of source code must retain the above copyright notice, this | |
9 | * list of conditions and the following disclaimer. | |
10 | * | |
11 | * Redistributions in binary form must reproduce the above copyright notice, | |
12 | * this list of conditions and the following disclaimer in the documentation | |
13 | * and/or other materials provided with the distribution. | |
14 | * | |
15 | * Neither the name of the University of Salford nor the names of its | |
16 | * contributors may be used to endorse or promote products derived from this | |
17 | * software without specific prior written permission. | |
18 | * | |
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | |
31 | ||
32 | package issrg.pba.rbac; | |
33 | ||
34 | import java.util.Map; | |
35 | import java.util.Hashtable; | |
36 | import java.security.Principal; | |
37 | import issrg.utils.repository.Entry; | |
38 | import issrg.pba.rbac.policies.Subtree; | |
39 | import issrg.pba.rbac.policies.URLSubtree; | |
40 | import issrg.utils.repository.FileRepository; | |
41 | import issrg.utils.repository.RepositoryException; | |
42 | ||
43 | /** | |
44 | * This class is a constructor of various URL-related instances: | |
45 | * Subtrees (for domain matching), Principals and Entries (for domain matching). | |
46 | * It also maintains a register of URL Handlers for other protocols, so that | |
47 | * a relevant URL Handler can be found for a specific URL. | |
48 | * | |
49 | * <p>The instances of this class handle all URLs as if they were HTTP URLs. | |
50 | * Subclass it and override the methods to handle URLs of other types. | |
51 | * | |
52 | * @author A.Otenko | |
53 | * @version 1.0 | |
54 | */ | |
55 | public class URLHandler { | |
56 | ||
57 | public static final String HTTP_PROTOCOL = "http"; | |
58 | public static final String HTTPS_PROTOCOL = "https"; | |
59 | public static final String FILE_PROTOCOL = "file"; | |
60 | ||
61 | public static final int HTTP_PORT = 80; | |
62 | public static final int HTTPS_PORT = 443; | |
63 | ||
64 | /** | |
65 | * This variable is here to allow emulation of file: URLs as HTTP URLs. | |
66 | */ | |
67 | protected static final int FILE_PORT = 0; | |
68 | ||
69 | private static Map protocols = new Hashtable(); | |
70 | ||
71 | 11 | static{ |
72 | 11 | addProtocol(new URLHandler(HTTP_PROTOCOL, HTTP_PORT)); |
73 | 11 | addProtocol(new URLHandler(HTTPS_PROTOCOL, HTTPS_PORT)); |
74 | 11 | addProtocol(new URLHandler(FILE_PROTOCOL, FILE_PORT)); |
75 | 11 | addProtocol(new LDAPURLHandler()); |
76 | } | |
77 | ||
78 | /** | |
79 | * This method registers a new protocol URL handler, so if a URL | |
80 | * for this protocol has to be parsed, the getPrincipal and getSubtree nodes | |
81 | * will know who can handle such URLs. | |
82 | * | |
83 | * @param u the URLHandler that can handle URLs for a specific protocol | |
84 | */ | |
85 | 49 | public static void addProtocol(URLHandler u){ |
86 | 49 | protocols.put(u.getProtocol().toLowerCase(), u); |
87 | } | |
88 | ||
89 | /** | |
90 | * This method removes a protocol handler for a particular protocol name. | |
91 | * | |
92 | * @param protocol the protocol name for which handler has to be removed | |
93 | */ | |
94 | 0 | public static void removeProtocol(String protocol){ |
95 | 0 | protocols.remove(protocol.toLowerCase()); |
96 | } | |
97 | ||
98 | /** | |
99 | * This method returns a handler for URLs for a given protocol. | |
100 | * | |
101 | * @param protocol the protocol to get the handler for | |
102 | * | |
103 | * @return the URLHandler object handling URLs for a given protocol; null, if no handler | |
104 | * has been assigned | |
105 | */ | |
106 | 120 | public static URLHandler getURLHandler(String protocol){ |
107 | 0 | if (protocol==null) return null; |
108 | 120 | return (URLHandler)protocols.get(protocol.toLowerCase()); |
109 | } | |
110 | ||
111 | /** | |
112 | * This method returns the protocol name, given a URL. | |
113 | * | |
114 | * @param url the URL to get the protocol name from | |
115 | * | |
116 | * @return the protocol name as it is in the URL | |
117 | * | |
118 | * @throws BadURLException if this is not a URL with a protocol string in it | |
119 | */ | |
120 | 257 | public static String getProtocolName(String url) throws BadURLException { |
121 | 0 | if (url==null) return null; |
122 | ||
123 | 257 | int i = url.indexOf(":"); // find the position of the first colon character |
124 | 257 | if (i<0) throw new BadURLException("URL "+url+" does not have a protocol part"); |
125 | ||
126 | 132 | return url.substring(0, i); |
127 | } | |
128 | ||
129 | /** | |
130 | * This method returns a Principal, created by corresponding URLHandler. | |
131 | * | |
132 | * <p>This is equivalent to getURLHandler(getProtocolName(url)).getPrincipal(url); | |
133 | * | |
134 | * @param url the URL as the Principal | |
135 | * | |
136 | * @return the Principal object, created by corresponding URLHandler; null, if no | |
137 | * matching URLHandler has been found | |
138 | * | |
139 | * @throws BadURLException if the URL does not have a protocol part, or the | |
140 | * URLHandler doesn't like it | |
141 | */ | |
142 | 3 | public static Principal getPrincipalByURL(String url) throws BadURLException { |
143 | 3 | URLHandler uh = getURLHandler(getProtocolName(url)); |
144 | ||
145 | 3 | return uh==null? null: uh.getPrincipal(url); |
146 | } | |
147 | ||
148 | ||
149 | /** | |
150 | * This method returns a Entry object, created by corresponding URLHandler. | |
151 | * | |
152 | * <p>This is equivalent to getURLHandler(getProtocolName(url)).getEntry(url); | |
153 | * | |
154 | * @param url the URL of the Entry | |
155 | * | |
156 | * @return the Entry object, created by corresponding URLHandler; null, if no | |
157 | * matching URLHandler has been found | |
158 | * | |
159 | * @throws BadURLException if the URL does not have a protocol part, or the | |
160 | * URLHandler doesn't like it | |
161 | */ | |
162 | 56 | public static Entry getEntryByURL(String url) throws BadURLException { |
163 | ||
164 | 56 | URLHandler uh = getURLHandler(getProtocolName(url)); |
165 | 56 | return uh==null? null: uh.getEntry(url); |
166 | } | |
167 | ||
168 | /** | |
169 | * This method returns a Subtree object, created by corresponding URLHandler. | |
170 | * | |
171 | * <p>This is equivalent to getURLHandler(getProtocolName(url)).getSubtree(url, min, max); | |
172 | * | |
173 | * @param url the URL of the base Entry | |
174 | * @param min the minimum number of levels below the base Entry where the | |
175 | * matching entries can be located; pass 0, if no retriction is placed | |
176 | * @param max the maximum number of levels below the base Entry where the | |
177 | * matching entries can be located; pass -1 if no restriction is placed | |
178 | * @param exclude the array of the subtrees specifying what entries to exclude | |
179 | * from this subtree | |
180 | * | |
181 | * @return the Subtree object, created by corresponding URLHandler; null, if no | |
182 | * matching URLHandler has been found | |
183 | * | |
184 | * @throws BadURLException if the URL does not have a protocol part, or the | |
185 | * URLHandler doesn't like it | |
186 | */ | |
187 | 44 | public static Subtree getSubtreeByURL(String url, int min, int max, Subtree [] exclude) throws BadURLException { |
188 | 44 | URLHandler uh = getURLHandler(getProtocolName(url)); |
189 | 44 | return uh==null? null: uh.getSubtree(url, min, max, exclude); |
190 | } | |
191 | ||
192 | /** | |
193 | * This method will find a URLHandler for the protocol and create the | |
194 | * AttributeRepository that will provide access to that repository. | |
195 | * | |
196 | * <p>Same as URLHandler.getURLHandler(URLHandler.getProtocolName(url)).getRepository(url); | |
197 | * | |
198 | * @param url - the URL of the repository | |
199 | * | |
200 | * @return AttributeRepository pointed to by the URL, or null, if no repository | |
201 | * could be created (e.g. no URLHandler could be found) | |
202 | * | |
203 | * @throws BadURLException if the URL is malformed | |
204 | */ | |
205 | 7 | public static issrg.utils.repository.AttributeRepository getRepositoryByURL(String url) throws BadURLException { |
206 | //System.err.println("getting a repository for "+url);//*************** | |
207 | 7 | URLHandler uh = getURLHandler(getProtocolName(url)); |
208 | 7 | return uh==null? null: uh.getRepository(url); |
209 | } | |
210 | ||
211 | 13 | protected URLHandler(){} |
212 | ||
213 | protected String protocol; | |
214 | protected int defaultPort; | |
215 | ||
216 | /** | |
217 | * This constructor builds an instance of URLHandler that will be able to | |
218 | * handle | |
219 | * URLs of given protocol, and listening on given default port. | |
220 | * | |
221 | * @param protocol the string name of the protocol (without trailing ":"); | |
222 | * case of characters is ignored | |
223 | * @param defaultPort the number of the default port the protocol listens on | |
224 | */ | |
225 | 36 | public URLHandler(String protocol, int defaultPort){ |
226 | 36 | this.protocol=protocol.toLowerCase(); |
227 | 36 | this.defaultPort=defaultPort; |
228 | } | |
229 | ||
230 | /** | |
231 | * This method returns the string name of the protocol (without the trailing | |
232 | * colon). | |
233 | * The protocol is in lowercase letters. | |
234 | * | |
235 | * @return string name of the protocol in lowercase characters | |
236 | */ | |
237 | 33 | public String getProtocol(){ |
238 | 33 | return protocol; |
239 | } | |
240 | ||
241 | /** | |
242 | * This method returns the number of the defaul port that the protocol listens | |
243 | * on | |
244 | * | |
245 | * @return integer number of the port on which the protocol listens by default | |
246 | */ | |
247 | 0 | public int getDefaultPort(){ |
248 | 0 | return defaultPort; |
249 | } | |
250 | ||
251 | /** | |
252 | * This method returns a Principal for a given HTTP URL string. | |
253 | * It checks if the passed URL string matches the protocol this Handler is | |
254 | * registered for. | |
255 | * | |
256 | * @param url the string representation of the HTTP URL (including the | |
257 | * protocol name part) | |
258 | * (the actual protocol name is checked with the string returned by | |
259 | * getProtocol, | |
260 | * but the format of the rest of the URL is as specified in HTTP RFC) | |
261 | * | |
262 | * @return Principal of the corresponding URL | |
263 | * | |
264 | * @throws BadURLException if the URL is malformed | |
265 | */ | |
266 | 57 | public Principal getPrincipal(String url) throws BadURLException { |
267 | 57 | URLPrincipal upi=new URLPrincipal(url, defaultPort); |
268 | ||
269 | 57 | if (!upi.getProtocol().equals(protocol)){ |
270 | 0 | throw new BadURLException("Wrong URL parser: "+upi.getProtocol()+": found, "+protocol+": expected"); |
271 | } | |
272 | ||
273 | 57 | return upi; |
274 | } | |
275 | ||
276 | /** | |
277 | * This method returns an Entry identified by a given HTTP URL. | |
278 | * | |
279 | * <p>This URLHandler does (Entry)getPrincipal(url) - so if your Principal | |
280 | * implements the Entry interface, you can leave the getEntry method. | |
281 | * | |
282 | * @param url the string representation of the HTTP URL (see comments for | |
283 | * getPrincipal method) | |
284 | * | |
285 | * @return Entry identified by the URL | |
286 | * | |
287 | * @throws BadURLException if the URL is malformed | |
288 | */ | |
289 | 56 | public Entry getEntry(String url) throws BadURLException { |
290 | 56 | return (Entry)getPrincipal(url); // invoke the same method, so it will do the same checks |
291 | } | |
292 | ||
293 | /** | |
294 | * This method returns a Subtree specified using a Base Entry URL and Min | |
295 | * and Max level | |
296 | * specifications. | |
297 | * | |
298 | * @param url the URL of the Base Entry; port may be specified as a range of | |
299 | * ports by using nn-mm notation (two numbers separated by hyphen); | |
300 | * if no port is specified, any port matches the subtree specification | |
301 | * @param min the Min value for the subtree | |
302 | * @param max the Max value for the subtree | |
303 | * | |
304 | * @see issrg.pba.rbac.policies.Subtree | |
305 | * | |
306 | * @throws BadURLException if the URL is malformed | |
307 | */ | |
308 | 44 | public Subtree getSubtree(String url, int min, int max, Subtree [] exclude) throws BadURLException { |
309 | 44 | return new URLSubtree(url, defaultPort, min, max, exclude); |
310 | } | |
311 | ||
312 | /** | |
313 | * This method returns an instance of a repository that would be able to | |
314 | * retrieve attributes given the URL. Some Repositories may use only the | |
315 | * host part of the URL to connect to the server, ignoring the path part. | |
316 | * | |
317 | * <p>In this version of the URLHandler, no HTTP/HTTPS repositories are | |
318 | * implemented, so null is returned for such URLs. | |
319 | * | |
320 | * @param url - the URL of the repository | |
321 | * | |
322 | * @return the AttributeRepository | |
323 | */ | |
324 | 6 | public issrg.utils.repository.AttributeRepository getRepository(String url) throws BadURLException { |
325 | 0 | if (!protocol.equals(FILE_PROTOCOL)) return null; |
326 | ||
327 | 6 | try{ |
328 | 6 | return new FileRepository(url); |
329 | }catch (RepositoryException re){ | |
330 | 0 | throw new BadURLException("File Repository could not be connected: "+url, re); |
331 | } | |
332 | } | |
333 | } |
|