View Javadoc

    1   /* Credential
    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.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         // TODO: Account for port.  Currently we do not distingush between
    255         // http and https; they both get same crawl server instance.
    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 }