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.credential;
24
25 import java.util.Iterator;
26 import java.util.Set;
27 import java.util.logging.Logger;
28
29 import javax.management.Attribute;
30 import javax.management.AttributeNotFoundException;
31 import javax.management.InvalidAttributeValueException;
32
33 import org.apache.commons.httpclient.HttpClient;
34 import org.apache.commons.httpclient.HttpMethod;
35 import org.archive.crawler.datamodel.CrawlURI;
36 import org.archive.crawler.framework.CrawlController;
37 import org.archive.crawler.settings.CrawlerSettings;
38 import org.archive.crawler.settings.ModuleType;
39 import org.archive.crawler.settings.SimpleType;
40 import org.archive.crawler.settings.Type;
41
42
43
44 /***
45 * Credential type.
46 *
47 * Let this be also a credential in the JAAS sense to in that this is what
48 * gets added to a subject on successful authentication since it contains
49 * data needed to authenticate (realm, login, password, etc.).
50 *
51 * <p>Settings system assumes that subclasses implement a constructor that
52 * takes a name only.
53 *
54 * @author stack
55 * @version $Revision: 2993 $, $Date: 2005-01-04 02:24:59 +0000 (Tue, 04 Jan 2005) $
56 */
57 public abstract class Credential extends ModuleType {
58
59 private static final Logger logger =
60 Logger.getLogger(Credential.class.getName());
61
62 private static final String ATTR_CREDENTIAL_DOMAIN = "credential-domain";
63
64 /***
65 * Constructor.
66 *
67 * @param name Name of this credential.
68 * @param description Descrtiption of this particular credential.
69 */
70 public Credential(String name, String description) {
71 super(name, description);
72 Type t = addElementToDefinition(new SimpleType(ATTR_CREDENTIAL_DOMAIN,
73 "The root domain this credential goes against:" +
74 " E.g. www.archive.org", ""));
75 t.setOverrideable(false);
76 t.setExpertSetting(true);
77 }
78
79 /***
80 * @param context Context to use when searching for credential domain.
81 * @return The domain/root URI this credential is to go against.
82 * @throws AttributeNotFoundException If attribute not found.
83 */
84 public String getCredentialDomain(CrawlURI context)
85 throws AttributeNotFoundException {
86 return (String)getAttribute(ATTR_CREDENTIAL_DOMAIN, context);
87 }
88
89 /***
90 * @param context Context to use when searching for credential domain.
91 * @param domain New domain.
92 * @throws AttributeNotFoundException
93 * @throws InvalidAttributeValueException
94 */
95 public void setCredentialDomain(CrawlerSettings context, String domain)
96 throws InvalidAttributeValueException, AttributeNotFoundException {
97 setAttribute(context, new Attribute(ATTR_CREDENTIAL_DOMAIN, domain));
98 }
99
100 /***
101 * Attach this credentials avatar to the passed <code>curi</code> .
102 *
103 * Override if credential knows internally what it wants to attach as
104 * payload. Otherwise, if payload is external, use the below
105 * {@link #attach(CrawlURI, String)}.
106 *
107 * @param curi CrawlURI to load with credentials.
108 */
109 public void attach(CrawlURI curi) {
110 attach(curi, null);
111 }
112
113 /***
114 * Attach this credentials avatar to the passed <code>curi</code> .
115 *
116 * @param curi CrawlURI to load with credentials.
117 * @param payload Payload to carry in avatar. Usually credentials.
118 */
119 public void attach(CrawlURI curi, String payload) {
120 CredentialAvatar ca = null;
121 try {
122 ca = (payload == null )?
123 new CredentialAvatar(this.getClass(), getKey(curi)):
124 new CredentialAvatar(this.getClass(), getKey(curi), payload);
125 curi.addCredentialAvatar(ca);
126 }
127 catch (AttributeNotFoundException e) {
128 logger.severe("Failed attach of " + this + " for " + curi);
129 }
130 }
131
132 /***
133 * Detach this credential from passed curi.
134 *
135 * @param curi
136 * @return True if we detached a Credential reference.
137 */
138 public boolean detach(CrawlURI curi) {
139 boolean result = false;
140 if (!curi.hasCredentialAvatars()) {
141 logger.severe("This curi " + curi +
142 " has no cred when it should");
143 } else {
144 Set avatars = curi.getCredentialAvatars();
145 for (Iterator i = avatars.iterator(); i.hasNext();) {
146 CredentialAvatar ca = (CredentialAvatar)i.next();
147 try {
148 if (ca.match(getClass(), getKey(curi))) {
149 result = curi.removeCredentialAvatar(ca);
150 }
151 }
152 catch (AttributeNotFoundException e) {
153 logger.severe("Failed detach of " + ca + " from " + curi);
154 }
155 }
156 }
157 return result;
158 }
159
160 /***
161 * Detach all credentials of this type from passed curi.
162 *
163 * @param curi
164 * @return True if we detached references.
165 */
166 public boolean detachAll(CrawlURI curi) {
167 boolean result = false;
168 if (!curi.hasCredentialAvatars()) {
169 logger.severe("This curi " + curi +
170 " has no creds when it should.");
171 } else {
172 Set avatars = curi.getCredentialAvatars();
173 for (Iterator i = avatars.iterator(); i.hasNext();) {
174 CredentialAvatar ca = (CredentialAvatar)i.next();
175 if (ca.match(getClass())) {
176 result = curi.removeCredentialAvatar(ca);
177 }
178 }
179 }
180 return result;
181 }
182
183 /***
184 * @param curi CrawlURI to look at.
185 * @return True if this credential IS a prerequisite for passed
186 * CrawlURI.
187 */
188 public abstract boolean isPrerequisite(CrawlURI curi);
189
190 /***
191 * @param curi CrawlURI to look at.
192 * @return True if this credential HAS a prerequisite for passed CrawlURI.
193 */
194 public abstract boolean hasPrerequisite(CrawlURI curi);
195
196 /***
197 * Return the authentication URI, either absolute or relative, that serves
198 * as prerequisite the passed <code>curi</code>.
199 *
200 * @param curi CrawlURI to look at.
201 * @return Prerequisite URI for the passed curi.
202 */
203 public abstract String getPrerequisite(CrawlURI curi);
204
205 /***
206 * @param context Context to use when searching for credential domain.
207 * @return Key that is unique to this credential type.
208 * @throws AttributeNotFoundException
209 */
210 public abstract String getKey(CrawlURI context)
211 throws AttributeNotFoundException;
212
213 /***
214 * @return True if this credential is of the type that needs to be offered
215 * on each visit to the server (e.g. Rfc2617 is such a type).
216 */
217 public abstract boolean isEveryTime();
218
219 /***
220 * @param curi CrawlURI to as for context.
221 * @param http Instance of httpclient.
222 * @param method Method to populate.
223 * @param payload Avatar payload to use populating the method.
224 * @return True if added a credentials.
225 */
226 public abstract boolean populate(CrawlURI curi, HttpClient http,
227 HttpMethod method, String payload);
228
229 /***
230 * @param curi CrawlURI to look at.
231 * @return True if this credential is to be posted. Return false if the
232 * credential is to be GET'd or if POST'd or GET'd are not pretinent to this
233 * credential type.
234 */
235 public abstract boolean isPost(CrawlURI curi);
236
237 /***
238 * Test passed curi matches this credentials rootUri.
239 * @param controller
240 * @param curi CrawlURI to test.
241 * @return True if domain for credential matches that of the passed curi.
242 */
243 public boolean rootUriMatch(CrawlController controller,
244 CrawlURI curi) {
245 String cd = null;
246 try {
247 cd = getCredentialDomain(curi);
248 }
249 catch (AttributeNotFoundException e) {
250 logger.severe("Failed to get credential domain " + curi + ": " +
251 e.getMessage());
252 }
253
254
255
256 String serverName = controller.getServerCache().getServerFor(curi).
257 getName();
258 logger.fine("RootURI: Comparing " + serverName + " " + cd);
259 return cd != null && serverName != null &&
260 serverName.equalsIgnoreCase(cd);
261 }
262 }