View Javadoc

1   /* CredentialStore
2    *
3    * Created on Apr 1, 2004
4    *
5    * Copyright (C) 2004 Internet Archive.
6    *
7    * This file is part of the Heritrix web crawler (crawler.archive.org).
8    *
9    * Heritrix is free software; you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser Public License as published by
11   * the Free Software Foundation; either version 2.1 of the License, or
12   * any later version.
13   *
14   * Heritrix is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU Lesser Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser Public License
20   * along with Heritrix; if not, write to the Free Software
21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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      // Initialize the credentialType data member.
83      static {
84          // Array of all known credential types.
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         // Now add the just-created credential to the list.
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 }