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.io.Serializable;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.logging.Logger;
29
30 import javax.management.AttributeNotFoundException;
31
32 import org.archive.crawler.datamodel.CrawlURI;
33 import org.archive.crawler.datamodel.CredentialStore;
34 import org.archive.crawler.settings.SettingsHandler;
35
36
37 /***
38 * A credential representation.
39 *
40 * Added to the CrawlServer upon successful authentication. Used as a marker
41 * of successful authentication event and for carrying credential
42 * payload to be used subsequently doing preemptive authentications (e.g.
43 * For case of RFC2617, needs to be offered everytime we're accessing inside
44 * a protected area). Also carried by the CrawlURI when cycling through
45 * processing chain trying a credential to see if it will authenticate.
46 *
47 * <p>This class exists because its not safe to keep references
48 * to the settings derived Credential classes so instead of keeping references
49 * to credential classes, we carry around this avatar.
50 *
51 * <p>Scope for avatars is crawlserver. Only used within a CrawlServer
52 * scope.
53 *
54 * <p>Immutable.
55 *
56 * @author stack
57 * @version $Revision: 4668 $, $Date: 2006-09-26 21:49:01 +0000 (Tue, 26 Sep 2006) $
58 */
59 public class CredentialAvatar
60 implements Serializable {
61
62 private static final long serialVersionUID = 4489542750898404807L;
63
64 private static final Logger logger =
65 Logger.getLogger(CredentialAvatar.class.getName());
66
67 /***
68 * Key for this credential avatar.
69 */
70 private final String key;
71
72 /***
73 * Type represented by this avatar.
74 */
75 private final Class type;
76
77 /***
78 * Data.
79 *
80 * May be null.
81 *
82 * <p>This used to be an Object and I used to store in here
83 * the httpclient AuthScheme but AuthScheme is not serializable
84 * and so there'd be trouble getting this payload to lie down
85 * in a bdb database. Changed it to String. That should be
86 * generic enough for credential purposes.
87 */
88 private final String payload;
89
90
91 /***
92 * Constructor.
93 * @param type Type for this credential avatar.
94 * @param key Key for this credential avatar.
95 */
96 public CredentialAvatar(Class type, String key) {
97 this(type, key, null);
98 }
99
100 /***
101 * Constructor.
102 * @param type Type for this credential avatar.
103 * @param key Key for this credential avatar.
104 * @param payload Data credential needs rerunning or preempting. May be
105 * null and then just the presence is used as signifier of successful
106 * auth.
107 */
108 public CredentialAvatar(Class type, String key, String payload) {
109 if (!checkType(type)) {
110 throw new IllegalArgumentException("Type is unrecognized: " +
111 type);
112 }
113 this.key = key;
114 this.type = type;
115 this.payload = payload;
116 }
117
118 /***
119 * Shutdown default constructor.
120 */
121 private CredentialAvatar() {
122 super();
123 this.key = null;
124 this.type = null;
125 this.payload = null;
126 }
127
128 /***
129 * @param candidateType Type to check.
130 * @return True if this is a known credential type.
131 */
132 protected boolean checkType(Class candidateType) {
133 boolean result = false;
134 List types = CredentialStore.getCredentialTypes();
135 for (Iterator i = types.iterator(); i.hasNext();) {
136 if (((Class)i.next()).equals(candidateType)) {
137 result = true;
138 break;
139 }
140 }
141 return result;
142 }
143
144 /***
145 * @return Returns the payload. May be null.
146 */
147 public String getPayload() {
148 return this.payload;
149 }
150
151 /***
152 * @return Returns the key.
153 */
154 public String getKey() {
155 return this.key;
156 }
157
158 /***
159 * @return Type represented by this avatar.
160 */
161 public Class getType() {
162 return this.type;
163 }
164
165 /***
166 * @param otherType Class to match.
167 * @return True if this credential avatar is of same type.
168 */
169 public boolean match(Class otherType) {
170 return this.type.equals(otherType);
171 }
172
173 /***
174 * @param otherType Credential to match.
175 * @param otherKey Key to test.
176 * @return True if this is avatar for passed credential.
177 */
178 public boolean match(Class otherType, String otherKey) {
179 return match(otherType) &&
180 (otherKey != null && this.key != null &&
181 this.key.equals(otherKey));
182 }
183
184 public String toString() {
185 return getType() + "." + this.getKey();
186 }
187
188 /***
189 * @param handler Settings handler.
190 * @param curi CrawlURI to use for context.
191 * @return The credential this avatar represents.
192 */
193 public Credential getCredential(SettingsHandler handler, CrawlURI curi) {
194 Credential result = null;
195
196 CredentialStore cs = CredentialStore.getCredentialStore(handler);
197 if (cs == null) {
198 logger.severe("No credential store for " + curi);
199 return result;
200 }
201
202 Iterator i = cs.iterator(curi);
203 if (i == null) {
204 logger.severe("Have CredentialAvatar " + toString() +
205 " but no iterator: " + curi);
206 return result;
207 }
208
209 while (i.hasNext()) {
210 Credential c = (Credential)i.next();
211 if (!this.type.isInstance(c)) {
212 continue;
213 }
214 String credKey = null;
215 try {
216 credKey = c.getKey(curi);
217 }
218 catch (AttributeNotFoundException e) {
219 logger.severe("Failed to get key for " + c + " from " + curi);
220 }
221 if (credKey != null && credKey.equals(getKey())) {
222 result = c;
223 break;
224 }
225 }
226
227 if (result == null) {
228 logger.severe("Have CredentialAvatar " + toString() +
229 " but no corresponding credential: " + curi);
230 }
231
232 return result;
233 }
234 }