1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.archive.crawler.datamodel;
24
25 import java.lang.reflect.InvocationTargetException;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Set;
32 import java.util.logging.Logger;
33
34 import javax.management.AttributeNotFoundException;
35 import javax.management.InvalidAttributeValueException;
36 import javax.management.MBeanException;
37 import javax.management.ReflectionException;
38
39 import org.archive.crawler.datamodel.credential.Credential;
40 import org.archive.crawler.datamodel.credential.HtmlFormCredential;
41 import org.archive.crawler.datamodel.credential.Rfc2617Credential;
42 import org.archive.crawler.settings.CrawlerSettings;
43 import org.archive.crawler.settings.MapType;
44 import org.archive.crawler.settings.ModuleType;
45 import org.archive.crawler.settings.SettingsHandler;
46 import org.archive.crawler.settings.Type;
47
48
49 /***
50 * Front door to the credential store.
51 *
52 * Come here to get at credentials.
53 *
54 * <p>See <a
55 * href="http://crawler.archive.org/proposals/auth/#credentialstoredesign">Credential
56 * Store Design</a>.
57 *
58 * @author stack
59 * @version $Revision: 4656 $, $Date: 2006-09-25 21:34:50 +0000 (Mon, 25 Sep 2006) $
60 */
61 public class CredentialStore extends ModuleType {
62
63 private static final long serialVersionUID = -7916979754932063634L;
64
65 private static Logger logger = Logger.getLogger(
66 "org.archive.crawler.datamodel.CredentialStore");
67
68 public static final String ATTR_NAME = "credential-store";
69
70 /***
71 * Name of the contained credentials map type.
72 */
73 public static final String ATTR_CREDENTIALS = "credentials";
74
75 /***
76 * List of possible credential types as a List.
77 *
78 * This types are inner classes of this credential type so they cannot
79 * be created without their being associated with a credential list.
80 */
81 private static final List credentialTypes;
82
83 static {
84
85 Class [] tmp = {HtmlFormCredential.class, Rfc2617Credential.class};
86 credentialTypes = Collections.unmodifiableList(Arrays.asList(tmp));
87 }
88
89 /***
90 * Constructor.
91 *
92 * @param name for this credential store.
93 */
94 public CredentialStore(String name)
95 {
96 super(name, "Credentials used by heritrix" +
97 " authenticating. See http://crawler.archive.org/proposals/auth/" +
98 " for background.");
99
100 Type t = addElementToDefinition(new MapType(ATTR_CREDENTIALS,
101 "Map of credentials.", Credential.class));
102 t.setOverrideable(true);
103 t.setExpertSetting(true);
104 }
105
106 /***
107 * @return Unmodifable list of credential types.
108 */
109 public static List getCredentialTypes() {
110 return CredentialStore.credentialTypes;
111 }
112
113 /***
114 * Get a credential store reference.
115 * @param context A settingshandler object.
116 * @return A credential store or null if we failed getting one.
117 */
118 public static CredentialStore getCredentialStore(SettingsHandler context) {
119
120 CredentialStore cs = null;
121
122 try {
123 cs = (CredentialStore)context.getOrder().
124 getAttribute(CredentialStore.ATTR_NAME);
125 } catch (AttributeNotFoundException e) {
126 logger.severe("Failed to get credential store: " + e.getMessage());
127 } catch (MBeanException e) {
128 logger.severe("Failed to get credential store: " + e.getMessage());
129 } catch (ReflectionException e) {
130 logger.severe("Failed to get credential store: " + e.getMessage());
131 }
132
133 return cs;
134 }
135
136 /***
137 * @param context Pass a CrawlURI, CrawlerSettings or UURI. Used to set
138 * context. If null, we use global context.
139 * @return A map of all credentials from passed context.
140 * @throws AttributeNotFoundException
141 */
142 protected MapType get(Object context)
143 throws AttributeNotFoundException {
144
145 return (MapType)getAttribute(context, ATTR_CREDENTIALS);
146 }
147
148 /***
149 * @param context Pass a CrawlURI, CrawlerSettings or UURI. Used to set
150 * context. If null, we use global context.
151 * @return An iterator or null.
152 */
153 public Iterator iterator(Object context) {
154
155 MapType m = null;
156 try {
157 m = (MapType)getAttribute(context, ATTR_CREDENTIALS);
158 } catch (AttributeNotFoundException e) {
159 logger.severe("Failed get credentials: " + e.getMessage());
160 }
161 return (m == null)? null: m.iterator(context);
162 }
163
164 /***
165 * @param context Pass a CrawlURI, CrawlerSettings or UURI. Used to set
166 * context. If null, we use global context.
167 * @param name Name to give the manufactured credential. Should be unique
168 * else the add of the credential to the list of credentials will fail.
169 * @return Returns <code>name</code>'d credential.
170 * @throws AttributeNotFoundException
171 * @throws MBeanException
172 * @throws ReflectionException
173 */
174 public Credential get(Object context, String name)
175 throws AttributeNotFoundException, MBeanException, ReflectionException {
176
177 return (Credential)get(context).getAttribute(name);
178 }
179
180 /***
181 * Create and add to the list a credential of the passed <code>type</code>
182 * giving the credential the passed <code>name</code>.
183 *
184 * @param context Pass a CrawlerSettings. Used to set
185 * context. If null, we use global context.
186 * @param name Name to give the manufactured credential. Should be unique
187 * else the add of the credential to the list of credentials will fail.
188 * @param type Type of credentials to get.
189 * @return The credential created and added to the list of credentials.
190 * @throws IllegalArgumentException
191 * @throws AttributeNotFoundException
192 * @throws InvocationTargetException
193 * @throws InvalidAttributeValueException
194 */
195 public Credential create(CrawlerSettings context, String name, Class type)
196 throws IllegalArgumentException, InvocationTargetException,
197 InvalidAttributeValueException, AttributeNotFoundException {
198
199 Credential result = (Credential)SettingsHandler.
200 instantiateModuleTypeFromClassName(name, type.getName());
201
202 get(context).addElement(context, result);
203 return result;
204 }
205
206 /***
207 * Delete the credential <code>name</code>.
208 *
209 * @param context Pass a CrawlerSettings. Used to set
210 * context. If null, we use global context.
211 * @param credential Credential to delete.
212 * @throws IllegalArgumentException
213 * @throws AttributeNotFoundException
214 */
215 public void remove(CrawlerSettings context, Credential credential)
216 throws AttributeNotFoundException, IllegalArgumentException {
217
218 remove(context, credential.getName());
219 }
220
221 /***
222 * Delete the credential <code>name</code>.
223 *
224 * @param context Pass a CrawlerSettings. Used to set
225 * context. If null, we use global context.
226 * @param name Name of credential to delete.
227 * @throws IllegalArgumentException
228 * @throws AttributeNotFoundException
229 */
230 public void remove(CrawlerSettings context, String name)
231 throws IllegalArgumentException, AttributeNotFoundException {
232
233 get(context).removeElement(context, name);
234 }
235
236 /***
237 * Return set made up of all credentials of the passed
238 * <code>type</code>.
239 *
240 * @param context Pass a CrawlURI or a CrawlerSettings. Used to set
241 * context. If null, we use global context.
242 * @param type Type of the list to return. Type is some superclass of
243 * credentials.
244 * @return Unmodifable sublist of all elements of passed type.
245 */
246 public Set subset(CrawlURI context, Class type) {
247 return subset(context, type, null);
248 }
249
250 /***
251 * Return set made up of all credentials of the passed
252 * <code>type</code>.
253 *
254 * @param context Pass a CrawlURI or a CrawlerSettings. Used to set
255 * context. If null, we use global context.
256 * @param type Type of the list to return. Type is some superclass of
257 * credentials.
258 * @param rootUri RootUri to match. May be null. In this case we return
259 * all. Currently we expect the CrawlServer name to equate to root Uri.
260 * Its not. Currently it doesn't distingush between servers of same name
261 * but different ports (e.g. http and https).
262 * @return Unmodifable sublist of all elements of passed type.
263 */
264 public Set<Credential> subset(CrawlURI context, Class type, String rootUri) {
265
266 Set<Credential> result = null;
267 Iterator i = iterator(context);
268 if (i != null) {
269 while(i.hasNext()) {
270 Credential c = (Credential)i.next();
271 if (!type.isInstance(c)) {
272 continue;
273 }
274 if (rootUri != null) {
275 String cd = null;
276 try {
277 cd = c.getCredentialDomain(context);
278 }
279 catch (AttributeNotFoundException e) {
280 logger.severe("Failed to get cred domain: " +
281 context + ": " + e.getMessage());
282 }
283 if (cd == null) {
284 continue;
285 }
286 if (!rootUri.equalsIgnoreCase(cd)) {
287 continue;
288 }
289 }
290 if (result == null) {
291 result = new HashSet<Credential>();
292 }
293 result.add(c);
294 }
295 }
296 return result;
297 }
298 }