? lib/gsi ? lib/cog-url-ncsa.jar ? lib/cog-jglobus-ncsa.jar ? src/gsimap.properties ? src/edu/ucsb/nceas/metacat/AuthGsi.java ? src/edu/ucsb/nceas/metacat/AuthInfo.java ? src/edu/ucsb/nceas/metacat/GsiMapfile.java ? src/edu/ucsb/nceas/metacat/client/gsi Index: build.properties =================================================================== RCS file: /cvs/metacat/build.properties,v retrieving revision 1.16 diff -r1.16 build.properties 85a86,100 > > # Authentication options -- written into metacat.properties > # can be "Gsi" or "Ldap" > auth-method=Gsi > # can really only be "Ldap" for now > auth-delegate=Ldap > # can be "true" or "false" > auth-delegation-allowed=true > # can be "username+password" or "gss" > auth-precedence=username+password > > # Should logins from localhost with no password be trusted? Useful > # for the GT4 web service wrapper around metacat when it isn't using > # GSI delegation. > auth-trust-localhost=true Index: build.xml =================================================================== RCS file: /cvs/metacat/build.xml,v retrieving revision 1.226 diff -r1.226 build.xml 273a274,278 > > > > > Index: docs/user/metacatinstall.html =================================================================== RCS file: /cvs/metacat/docs/user/metacatinstall.html,v retrieving revision 1.20 diff -r1.20 metacatinstall.html 20a21,28 > 618a627,917 > > > > > > >
>

GSI (Grid Security Infrastructure) Authentication

>
>

Overview

> >

> As an alternative to username/password, Metacat can use Grid > Security Infrastructure (GSI) credentials for authentication, if > you are programming to the Metacat client API. The advantages > are: >

> >
    >
  • > Use of security credentials enables sign-on with other grid > services. >
  • >
  • > Metacat's plaintext HTTP client-server connection is replaced > with encrypted HTTPS+GSI -- that is, SSL HTTP using grid > security credentials for the SSL connection. >
  • >
> > >

Grid Security Setup

> >
    >
  1. >

    If you don't have any Grid infrastructure available already, > you can href="http://grid.ncsa.uiuc.edu/myproxy/fromscratch.html">follow > these instructions to get started from scratch.

    >
  2. > >
  3. >

    Establish host credentials for your Metacat server. The > instructions above will suffice for experimentation, or you can > get host credentials from your own Certificate Authority. You > can always replace them in the future.

    >
  4. >
> >

Tomcat Configuration

> >
    >
  1. > >

    Add JARs to Tomcat's $CATALINA_HOME/common/lib > directory. You can find them in the Metacat distribution in > metacat/lib/gsi:

    > >
    > cog-jglobus-ncsa.jar, commons-pool-1.2.jar, > cryptix32.jar, cryptix-asn1.jar, cryptix.jar, > jce-jdk13-125.jar, jgss.jar, log4j-1.2.8.jar, puretls.jar, > xml-apis.jar >
    > >

    Note that cog-jglobus-ncsa.jar is a modified > version of cog-jglobus.jar which comes with the href="http://www.globus.org/toolkit/">Globus Toolkit. It > includes a patch to enable GSI+HTTPS POST actions (only GET was > supported previously). The patch has been committed to the CoG > source and will be included in a future a version of the Globus > Toolkit, but until then you will need this custom JAR.

    > >
  2. > >
  3. >

    Modify Tomcat's server.xml to listen for > HTTPS+GSI. Note that you can use any available port for this > connector; this example uses 8443.

    > >

    Host credentials: The HTTPS connection will require host > credentials for the Metacat server; the example below assumes > that the host credentials are in > /etc/grid-security, which is the default location > for a Globus > toolkit installation.

    > >

    CA Cert Dir: Any Certificate Authorities (CAs) that you > depend on -- for example, the one that issued your host > credential -- should have their public keys and signing policies > stored in a location that is accessible to Tomcat > (cacertdir, below). The filenames will be > something like 4a6cd8b1.0 and > 4a6cd8b1.signing_policy.

    > >
      > >
    • >

      Add an HTTPSConnector, inside the > <Service name="Catalina"> section, near > the SSL HTTP/1.1 connector definition, which is commented > out by default:

      > >
      > <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
      > <!--
      > <Connector port="8443" maxHttpHeaderSize="8192"
      >            maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
      >            enableLookups="false" disableUploadTimeout="true"
      >            acceptCount="100" scheme="https" secure="true"
      >            clientAuth="false" sslProtocol="TLS" />
      > -->
      > 
      > <!-- Define an HTTPS+GSI (HTTPS with GSI credentials) Connector on port 8443 -->
      > <Connector className="org.globus.tomcat.coyote.net.HTTPSConnector"
      >            port="8443" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" 
      >            autoFlush="true" disableUploadTimeout="true" scheme="https"
      >            enableLookups="true" acceptCount="10" debug="0" 
      >            cert="/etc/grid-security/hostcert.pem"
      >            key="/etc/grid-security/hostkey.pem"
      >            cacertdir="/etc/grid-security/certificates"/>
      > 
      >
    • >
    • >

      Add an HTTPSValve, inside the <Engine > name="Catalina" ...> section, near the > RequestDumperValve definition, which is > commented out by default:

      > >
      > <!--
      > <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
      > -->
      > 
      > <!-- Globus valve for HTTPS+GSI -->
      > <Valve className="org.globus.tomcat.coyote.valves.HTTPSValve"/>
      > 
      >
    • >
    >
  4. > >
  5. >

    Restart Tomcat -- it should now be listening for HTTPS+GSI > connections. Watch for errors in its log file > ($CATALINA_HOME/logs/catalina.out).

    >
  6. >
> >

Metacat Client GSI Login

> >
    >
  1. >

    You can now use GSI credentials to initiate a Metacat > session, replacing Metacat.login(String username, String > password) with Metacat.login(GSSCredential > credential). There are several ways to get a > GSSCredential; one easy method, if you have access > to a MyProxy > server, is to use the CoG > Java libraries to retrieve a proxy credential from MyProxy.

    > >

    Here is some sample Java code. Note that it requires, in > addition to the JARs listed above, > cog-url-ncsa.jar, which can be found in the > metacat/lib directory.

    > >

    Note: for code comments, mouse over the title="like this one">marked sections below.

    > >
    > // 1. Get a GSI security credential
    > org.globus.myproxy.MyProxy server = new MyProxy(host, 7512);
    > org.ietf.jgss.GSSCredential credential = server.get(username, passphrase, lifetime);
    > 
    > // 2. Connect to Metacat via GSI+HTTPS
    > String metacatUrl = "https://<metacat server>:8443/knb/metacat/";
    > edu.ucsb.nceas.metacat.client.Metacat client 
    >     = edu.ucsb.nceas.metacat.client.MetacatFactory.createMetacatConnection(metacatUrl);
    > String loginResult = client.login(credential);
    > 
    > >

    The String returned by > Metacat.login(GSSCredential) will let you know > whether your attempt succeeded.

    >
  2. > >
  3. >

    In order to give GSI users privileges in Metacat, you must > Map GSI user IDs, or Distinguished Names (DNs), to Metacat user > IDs, which will generally be LDAP DNs. You can do this in a map > file that starts out in > metacat/src/gsimap.properties and gets deployed to > Tomcat's webapps/knb/WEB-INF/ directory. You can > modify it in either place, but it will be overwritten each time > you redeploy Metacat if you change it in Tomcat's installation > directory.

    >
  4. >
> >

A Client Inside of Tomcat

> >

Detailed explanation: The sample code above will work in a simple > testing situation such as in an IDE's debugger, and it may work in a > desktop application, but it won't work inside Tomcat. It has two > problems, both of which have to do with Java's protocol handling > facilities. The first problem is a protocol handler collision -- > Tomcat has already instantiated an HTTPS handler, and it is not the > one we need for GSI+HTTPS. The second problem has to do with class > loading: our special HTTPS protocol handlers are not accessible to > Java's protocol handling code because they are not loaded by > Tomcat's root classloader.

> >
    >
  1. > You will most likely need to install the Metacat server and the > Metacat client application in separate instances of > Tomcat in order for them to successfully connect. >
  2. > >
  3. >

    Protocol Handler Collisions:

    > >

    Short answer: replace "https" with > "httpg".

    >
    https://<metacat server>:8443/knb/metacat/
    >

    becomes

    >
    httpg://<metacat server>:8443/knb/metacat/
    > >

    Long answer: The URL in the example above, > https://<metacat server>:8443/knb/metacat/, > uses the HTTPS protocol. However, actually > handling that connection requires a protocol handler that > understands GSI+HTTPS instead of plain HTTPS. Fortunately, > static initialization code in > MetacatGsiClient specifies a non-default > HTTPS handler before the default handler is > instantiated by Java.

    > >

    Unfortunately, in Tomcat, an HTTPS handler has > already been instantiated by the time Metacat code runs, and we > don't have a chance to instantiate our special handler. > Besides, other applications also running in Tomcat may need to > use the default handler.

    > >

    Instead, we can define a new protocol. It could be named > anything -- HTTPGSI, METACAT_GSI, > GRID_HTTP, etc. Metacat defines a handler for a > protocol named HTTPG. To see how it works, see the > static initialization code in > edu.ucsb.nceas.metacat.client.MetacatGsiClient and > the very simple class > edu.ucsb.nceas.protocols.httpg.Handler.

    >
  4. >
  5. >

    Tomcat Classloading: Since the Java classes that dynamically > load protocol handlers are in Tomcat's root classloader, the > protocol handlers themselves must be there also.

    > >
      >
    1. > Copy metacat.jar, utilities.jar, > and cog-url-ncsa.jar from Metacat's lib > directory to a place that is accessible by Tomcat, such as > $CATALINA_HOME/common/lib. >
    2. >
    3. >

      Modify the definition of CLASSPATH in > Tomcat's startup script, > $CATALINA_HOME/bin/catalina.sh (In Windows, > catalina.bat, which has slightly different > syntax).

      > >

      Replace:

      >
      > CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar:\
      > "$CATALINA_HOME"/bin/commons-logging-api.jar
      > 
      >

      With:

      >
      > CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar:\
      > "$CATALINA_HOME"/bin/commons-logging-api.jar:"$CATALINA_HOME"/common/lib/metacat.jar:\
      > "$CATALINA_HOME"/common/lib/utilities.jar:"$CATALINA_HOME"/common/lib/cog-url-ncsa.jar
      > 
      >
    4. >
    > > >
  6. >
>
> Index: lib/metacat.properties =================================================================== RCS file: /cvs/metacat/lib/metacat.properties,v retrieving revision 1.100 diff -r1.100 metacat.properties 43,54d42 < moderators=@moderators@ < < allowedSubmitters=@allowedSubmitters@ < < deniedSubmitters=@deniedSubmitters@ < < timedreplication=@timedreplication@ < < firsttimedreplication=@firsttimedreplication@ < < timedreplicationinterval=@timedreplicationinterval@ < 89,90d76 < indexed_paths=organizationName,originator/individualName/surName,originator/individualName/givenName,originator/organizationName,creator/individualName/surName,creator/individualName/givenName,creator/organizationName,dataset/title,keyword,northBoundingCoordinate,southBoundingCoordinate,westBoundingCoordinate,eastBoundingCoordinate,title,entityName,individualName/surName,abstract/para,surName,givenName,para,geographicDescription,literalLayout < 97c83,88 < authclass=edu.ucsb.nceas.metacat.AuthLdap --- > authclass=edu.ucsb.nceas.metacat.Auth@auth-method@ > authDelegateClass=edu.ucsb.nceas.metacat.Auth@auth-delegate@ > authDelegationAllowed=@auth-delegation-allowed@ > authPrecedence=@auth-precedence@ > gsiMapClass=edu.ucsb.nceas.metacat.GsiMapfile > trustLocalHost=@auth-trust-localhost@ 99c90,91 < ldapurl=ldap://ldap.ecoinformatics.org:389/ --- > #ldapurl=ldap://ldap.ecoinformatics.org:389/ > ldapurl=ldap://ldap.lternet.edu/ 101c93,94 < ldapsurl=ldap://ldap.ecoinformatics.org:389/ --- > #ldapsurl=ldap://ldap.ecoinformatics.org:389/ > ldapsurl=ldap://ldap.lternet.edu/ 103c96,97 < ldapbase=dc=ecoinformatics,dc=org --- > #ldapbase=dc=ecoinformatics,dc=org > ldapbase=o=lter,dc=ecoinformatics,dc=org Index: src/edu/ucsb/nceas/metacat/AuthInterface.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/AuthInterface.java,v retrieving revision 1.7 diff -r1.7 AuthInterface.java 46,48c46,47 < * @param user the name of the principal to authenticate < * @param password the password to use for authentication < * @returns boolean true if authentication successful, false otherwise --- > * @param info authentication information from the user > * @return true if authentication successful, false otherwise 50c49 < public boolean authenticate(String user, String password) --- > public boolean authenticate(AuthInfo info) 56c55 < public String[][] getUsers(String user, String password) --- > public String[][] getUsers(AuthInfo info) 62c61 < public String[] getUsers(String user, String password, String group) --- > public String[] getUsers(AuthInfo info, String group) 68c67 < public String[][] getGroups(String user, String password) --- > public String[][] getGroups(AuthInfo info) 74c73 < public String[][] getGroups(String user, String password, String foruser) --- > public String[][] getGroups(AuthInfo info, String foruser) 80,81c79,80 < * @param user the user for which the attribute list is requested < * @returns HashMap a map of attribute name to a Vector of values --- > * @param foruser the user for which the attribute list is requested > * @return a map of attribute name to a Vector of values 89,92c88,90 < * @param user the user for which the attribute list is requested < * @param authuser the user for authenticating against the service < * @param password the password for authenticating against the service < * @returns HashMap a map of attribute name to a Vector of values --- > * @param info authentication information to use to access the directory > * @param foruser the user for which the attribute list is requested > * @return a map of attribute name to a Vector of values 94c92 < public HashMap getAttributes(String user, String password, String foruser) --- > public HashMap getAttributes(AuthInfo info, String foruser) 100,101c98,99 < * @param user the user which requests the information < * @param password the user's password --- > * @param info authentication information about the user who requests the > * information 103c101 < public String getPrincipals(String user, String password) --- > public String getPrincipals(AuthInfo info) Index: src/edu/ucsb/nceas/metacat/AuthLdap.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/AuthLdap.java,v retrieving revision 1.55 diff -r1.55 AuthLdap.java 31a32,33 > import javax.naming.*; > import javax.naming.directory.*; 33,49d34 < import javax.naming.AuthenticationException; < import javax.naming.Context; < import javax.naming.NamingEnumeration; < import javax.naming.NamingException; < import javax.naming.SizeLimitExceededException; < import javax.naming.InitialContext; < import javax.naming.directory.InvalidSearchFilterException; < import javax.naming.directory.Attribute; < import javax.naming.directory.Attributes; < import javax.naming.directory.BasicAttribute; < import javax.naming.directory.BasicAttributes; < import javax.naming.directory.DirContext; < import javax.naming.directory.InitialDirContext; < import javax.naming.directory.SearchResult; < import javax.naming.directory.SearchControls; < import javax.naming.ReferralException; < import javax.naming.ldap.*; 51,56c36 < import java.util.Iterator; < import java.util.HashMap; < import java.util.Hashtable; < import java.util.Enumeration; < import java.util.Set; < import java.util.Vector; --- > import java.util.*; 66d45 < private MetaCatUtil util = new MetaCatUtil(); 73,76c52 < private Context rContext; < private String userName; < private String userPassword; < ReferralException refExc; --- > ReferralException refExc; 94,96c70,71 < * @param user the name of the principal to authenticate < * @param password the password to use for authentication < * @returns boolean true if authentication successful, false otherwise --- > * @param info authentication information from the user > * @return true if authentication successful, false otherwise 98c73 < public boolean authenticate(String user, String password) throws --- > public boolean authenticate(AuthInfo info) throws 100,104c75,76 < String ldapUrl = this.ldapUrl; < String ldapsUrl = this.ldapsUrl; < String ldapBase = this.ldapBase; < boolean authenticated = false; < String identifier = user; --- > boolean authenticated = false; > String identifier = info.getUsername(); 110c82 < authenticated = ldapAuthenticate(identifier, password); --- > authenticated = ldapAuthenticate(identifier, info.getPassword()); 119,120c91,92 < String refUrl = ""; < String refBase = ""; --- > String refUrl; > String refBase; 132c104 < authenticated = ldapAuthenticate(identifier, password, --- > authenticated = ldapAuthenticate(identifier, info.getPassword(), 138c110 < authenticated = ldapAuthenticate(identifier, password); --- > authenticated = ldapAuthenticate(identifier, info.getPassword()); 171c143 < ConnectException, NamingException, NullPointerException { --- > NamingException, NullPointerException { 185c157 < ConnectException, NamingException, NullPointerException { --- > NamingException, NullPointerException { 191,192c163,164 < userName = identifier; < userPassword = password; --- > // userName = identifier; > // userPassword = password; 220,221d191 < this.ldapUrl = ldapUrl; < this.ldapBase = ldapBase; 272c242 < * @returns String the identifying name for the user, --- > * @return String the identifying name for the user, 423,425c393 < * @param user the user for authenticating against the service < * @param password the password for authenticating against the service < * @returns string array of all of the user names --- > * @return string array of all of the user names 427c395 < public String[][] getUsers(String user, String password) throws --- > public String[][] getUsers(AuthInfo info) throws 429c397 < String[][] users = null; --- > String[][] users; 460c428 < Attributes tempAttr = null; --- > Attributes tempAttr; 508c476 < users[i][3] = (String) uorg.elementAt(i); --- > users[i][3] = (String) uou.elementAt(i); 529,530c497 < * @param user the user for authenticating against the service < * @param password the password for authenticating against the service --- > * @param info represents the user making the request 532c499 < * @returns string array of the user names belonging to the group --- > * @return string array of the user names belonging to the group 534c501 < public String[] getUsers(String user, String password, String group) throws --- > public String[] getUsers(AuthInfo info, String group) throws 536c503 < String[] users = null; --- > String[] users; 564d530 < ; 596,598c562,563 < * @param user the user for authenticating against the service < * @param password the password for authenticating against the service < * @returns string array of the group names --- > * @param info represents the user making the request > * @return string array of the group names 600c565 < public String[][] getGroups(String user, String password) throws --- > public String[][] getGroups(AuthInfo info) throws 602c567 < return getGroups(user, password, null); --- > return getGroups(info, null); 608,609c573 < * @param user the user for authenticating against the service < * @param password the password for authenticating against the service --- > * @param info represents the user making the request 611c575 < * @returns string array of the group names --- > * @return string array of the group names 613c577 < public String[][] getGroups(String user, String password, String foruser) throws --- > public String[][] getGroups(AuthInfo info, String foruser) throws 617c581 < Attributes tempAttr = null; --- > Attributes tempAttr; 620,621c584,585 < userName = user; < userPassword = password; --- > // userName = user; > // userPassword = password; 640c604 < String filter = null; --- > String filter; 708c672 < String filter = null; --- > String filter; 768c732 < * @returns HashMap a map of attribute name to a Vector of values --- > * @return HashMap a map of attribute name to a Vector of values 771c735 < return getAttributes(null, null, foruser); --- > return getAttributes(null, foruser); 777,778c741 < * @param user the user for authenticating against the service < * @param password the password for authenticating against the service --- > * @param info represents the user making the request 780c743 < * @returns HashMap a map of attribute name to a Vector of values --- > * @return HashMap a map of attribute name to a Vector of values 782c745 < public HashMap getAttributes(String user, String password, String foruser) throws --- > public HashMap getAttributes(AuthInfo info, String foruser) throws 785,787d747 < String ldapUrl = this.ldapUrl; < String ldapBase = this.ldapBase; < String userident = foruser; 837,838c797 < private Hashtable getSubtrees(String user, String password, < String ldapUrl, String ldapBase) throws --- > private Hashtable getSubtrees(String ldapUrl, String ldapBase) throws 886c845 < String attrName = (String) attr.getID(); --- > String attrName = attr.getID(); 891c850 < String refName = (String) attr.getID(); --- > String refName = attr.getID(); 946,947c905 < * @param user the user which requests the information < * @param password the user's password --- > * @param info Auth Info representing the user who requests the information 949c907 < public String getPrincipals(String user, String password) throws --- > public String getPrincipals(AuthInfo info) throws 952c910,911 < --- > Vector usersIn = new Vector(); > 960,961c919 < Hashtable subtrees = getSubtrees(user, password, this.ldapUrl, < this.ldapBase); --- > Hashtable subtrees = getSubtrees(this.ldapUrl, this.ldapBase); 963c921 < Enumeration keyEnum = subtrees.keys(); --- > Enumeration keyEnum = subtrees.keys(); 1002,1003c960,961 < String[][] groups = getGroups(user, password); < String[][] users = getUsers(user, password); --- > String[][] groups = getGroups(info); > String[][] users = getUsers(info); 1012c970 < String[] usersForGroup = getUsers(user, password, groups[i][0]); --- > String[] usersForGroup = getUsers(info, groups[i][0]); 1014c972,973 < --- > usersIn.addElement(usersForGroup[j]); > 1042a1002 > if (!usersIn.contains(users[j][0])) { 1053a1014 > } 1056a1018,1022 > if (!usersIn.isEmpty()) { > usersIn.removeAllElements(); > usersIn.trimToSize(); > } > 1087c1053 < boolean isValid = false; --- > boolean isValid; 1090c1056,1057 < isValid = authservice.authenticate(user, password); --- > AuthInfo info = new AuthInfo(user, password); > isValid = authservice.authenticate(info); 1101c1068 < HashMap userInfo = authservice.getAttributes(user, password, user); --- > HashMap userInfo = authservice.getAttributes(info, user); 1103c1070 < Iterator attList = (Iterator) ( ( (Set) userInfo.keySet()).iterator()); --- > Iterator attList = userInfo.keySet().iterator(); 1118c1085 < String[][] groups = authservice.getGroups(user, password); --- > String[][] groups = authservice.getGroups(info); 1129c1096 < String[][] groups = authservice.getGroups(user, password, user); --- > String[][] groups = authservice.getGroups(info, user); 1141c1108 < String[] users = authservice.getUsers(user, password, savedGroup); --- > String[] users = authservice.getUsers(info, savedGroup); 1151c1118 < String[][] users = authservice.getUsers(user, password); --- > String[][] users = authservice.getUsers(info); 1160c1127 < String out = authservice.getPrincipals(user, password); --- > String out = authservice.getPrincipals(info); 1186c1153 < DirContext refDirContext = null; --- > DirContext refDirContext; 1188c1155 < String referralInfo = null; --- > String referralInfo; 1202,1203c1169,1170 < //MetaCatUtil.logMetacat.info("Processing referral (pr1.info): " + userName,35); < //MetaCatUtil.logMetacat.info("Processing referral (pr2)",35); --- > //MetaCatUtil.logMetacat.info("Processing referral (pr1.info): " + userName); > //MetaCatUtil.logMetacat.info("Processing referral (pr2)"); 1205c1172 < rContext = refExc.getReferralContext(); --- > Context rContext = refExc.getReferralContext(); 1251d1217 < DirContext refDirContext = null; 1258,1259c1224 < String refInfo = null; < refInfo = (String) refExc.getReferralInfo(); --- > String refInfo = (String) refExc.getReferralInfo(); 1262c1227 < refInfo.toString()); --- > refInfo); Index: src/edu/ucsb/nceas/metacat/AuthSession.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/AuthSession.java,v retrieving revision 1.18 diff -r1.18 AuthSession.java 30,31d29 < import java.net.ConnectException; < import javax.servlet.http.HttpSession; 32a31,32 > import javax.servlet.http.HttpSession; > import java.net.ConnectException; 41c41 < private String authClass = null; --- > 52,54c52,86 < MetaCatUtil util = new MetaCatUtil(); < this.authClass = util.getOption("authclass"); < this.authService = (AuthInterface)createObject(authClass); --- > String authClass = MetaCatUtil.getOption("authclass"); > this.authService = (AuthInterface)createObject(authClass); > > if (authService instanceof AuthGsi) { > // special config options for GSI authentication > String authDelegateClass = MetaCatUtil.getOption("authDelegateClass"); > String gsiMapClass = MetaCatUtil.getOption("gsiMapClass"); > String authDelegationAllowed = MetaCatUtil.getOption("authDelegationAllowed"); > String authPrecedence = MetaCatUtil.getOption("authPrecedence"); > > AuthGsi gsi = (AuthGsi) authService; > if (authDelegateClass != null) { > AuthInterface delegate = (AuthInterface) createObject(authDelegateClass); > gsi.setDelegate(delegate); > } > if (gsiMapClass != null) { > GsiToUsernameMap map = (GsiToUsernameMap) createObject(gsiMapClass); > gsi.setDnMap(map); > } > if (authDelegationAllowed != null) { > boolean allowed = Boolean.valueOf(authDelegationAllowed).booleanValue(); > if (!allowed && !authDelegationAllowed.trim().toLowerCase().equals("false")) > MetaCatUtil.logMetacat.warn("Config error: authDelegationAllowed " > + "must be \"true\" or \"false\" (found \"" > + authDelegationAllowed + "\"."); > gsi.setAuthnDelegationAllowed(allowed); > } > if (authPrecedence != null) { > try { > gsi.setPrecedence(authPrecedence); > } catch(IllegalArgumentException e) { > System.err.println(e.getMessage()); > } > } > } 70,71c102 < * @param username the username entered when login < * @param password the password entered when login --- > * @param info info from the user, such as username and password 73,77c104,107 < public boolean authenticate(HttpServletRequest request, < String username, String password) { < String message = null; < try { < if ( authService.authenticate(username, password) ) { --- > public boolean authenticate(HttpServletRequest request, AuthInfo info) { > String message; > try { > if ( authService.authenticate(info) ) { 79c109 < // getGroups returns groupname along with their description. --- > // getGroups returns groupname along with their description. 82c112 < authService.getGroups(username,password,username); --- > authService.getGroups(info,info.getUsername()); 93c123 < this.session = createSession(request, username, password, groups); --- > this.session = createSession(request, info, groups); 95c125 < message = "Authentication successful for user: " + username; --- > message = "Authentication successful for user: " + info; 99c129 < message = "Authentication failed for user: " + username; --- > message = "Authentication failed for user: " + info; 104c134,135 < message = "Connection to the authentication service failed in " + --- > ce.printStackTrace(); > message = "Connection to the authentication service failed in " + 107c138,139 < message = ise.getMessage(); --- > ise.printStackTrace(); > message = ise.getMessage(); 114,116c146,147 < /** Get new HttpSession and store username & password in it */ < private HttpSession createSession(HttpServletRequest request, < String username, String password, --- > /** Get new HttpSession and store authentication info in it */ > private HttpSession createSession(HttpServletRequest request, AuthInfo info, 129c160 < session.getAttribute("username")); --- > session.getAttribute("auth")); 137,138c168 < session.setAttribute("username", username); < session.setAttribute("password", password); --- > session.setAttribute("auth", info); 145c175 < session.getAttribute("username")); --- > session.getAttribute("auth")); 161,162c191 < * @param user the user which requests the information < * @param password the user's password --- > * @param info represents the user who requests the information 164c193 < public String getPrincipals(String user, String password) --- > public String getPrincipals(AuthInfo info) 167c196 < return authService.getPrincipals(user, password); --- > return authService.getPrincipals(info); 210c239 < Object object = null; --- > Object object; Index: src/edu/ucsb/nceas/metacat/MetaCatServlet.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/MetaCatServlet.java,v retrieving revision 1.226 diff -r1.226 MetaCatServlet.java 30,35c30 < import java.io.BufferedInputStream; < import java.io.File; < import java.io.FileInputStream; < import java.io.IOException; < import java.io.PrintWriter; < import java.io.StringReader; --- > import java.io.*; 37a33,34 > import java.net.URLEncoder; > import java.net.URLDecoder; 44,48c41,42 < import java.util.Enumeration; < import java.util.Hashtable; < import java.util.Iterator; < import java.util.PropertyResourceBundle; < import java.util.Vector; --- > import java.util.*; > import java.util.regex.PatternSyntaxException; 52,55c46 < import javax.servlet.ServletConfig; < import javax.servlet.ServletContext; < import javax.servlet.ServletException; < import javax.servlet.ServletOutputStream; --- > import javax.servlet.*; 60a52,53 > import edu.ucsb.nceas.utilities.Options; > 61a55 > import org.ietf.jgss.GSSContext; 68,69d61 < import edu.ucsb.nceas.utilities.Options; < 164c156 < --- > 166c158 < --- > 181,182c173,174 < LOG_CONFIG_NAME = dirPath + "/log4j.properties"; < --- > LOG_CONFIG_NAME = dirPath + "/log4j.properties"; > 213,214d204 < } catch (ServletException ex) { < throw ex; 235d224 < 237c226,230 < handleGetOrPost(request, response); --- > try { handleGetOrPost(request, response); } > catch(RuntimeException e) { > e.printStackTrace(); > throw new ServletException(e); > } 244d236 < 246c238,242 < handleGetOrPost(request, response); --- > try { handleGetOrPost(request, response); } > catch(RuntimeException e) { > e.printStackTrace(); > throw new ServletException(e); > } 248a245,255 > /** Copied from org.globus.axis.gsi.GSIConstants, so that we can avoid > * a compile dependency. */ > private static final String > GSI_CREDENTIALS = "org.globus.gsi.credentials", > GSI_AUTHORIZATION = "org.globus.gsi.authorization", > GSI_MODE = "org.globus.gsi.mode", > GSI_AUTH_USERNAME = "org.globus.gsi.authorized.user.name", > GSI_USER_DN = "org.globus.gsi.authorized.user.dn", > GSI_ANONYMOUS = "org.globus.gsi.anonymous", > GSI_CONTEXT = "org.globus.gsi.context"; > 388d394 < 403c409,410 < connPool.printMethodNameHavingBusyDBConnection(); --- > if (connPool != null) > connPool.printMethodNameHavingBusyDBConnection(); 415a423,438 > Enumeration headerNames = request.getHeaderNames(); > while (headerNames.hasMoreElements()) { > String headerName = (String) headerNames.nextElement(); > } > > // check whether incoming connection is via GSI-enabled HTTPS > // these constants are available from GSIConstants, but not imported > // here, to avoid dependencies > GSSContext gsiContext = (GSSContext) request.getAttribute(GSI_CONTEXT); > String gsiUserDN = (String) request.getAttribute(GSI_USER_DN); > boolean gssConnection = gsiContext != null && gsiUserDN != null; > if (gssConnection) { > params.put(GSI_CONTEXT, gsiContext); > params.put(GSI_USER_DN, gsiUserDN); > } > 433a457,499 > // Get extra POST parameters because when the incoming request uses > // chunked coding, they don't automatically get parsed. > if ("application/x-www-form-urlencoded".equals(ctype)) { > try { > String post = readInputStreamAsString(request); > if (post != null && post.length() > 0) { > String[] posts = post.split("&"); > for (int i = 0; i < posts.length; ++i) { > String[] a = posts[i].split("="); > for (int j = 0; j < a.length; ++j) > a[j] = URLDecoder.decode(a[j]); > if (a.length >= 2) { > addToMultimap(params, a[0], a[1]); > } > } > } > } catch(Exception e) { > String msg = "Exception reading remaining POST data: " > + e.getMessage(); > if (MetaCatUtil.debugMessage(msg, 20)) > e.printStackTrace(); > } > } > > String[] usernames = (String[]) params.get("username"), > passwords = (String[]) params.get("password"); > String username = (usernames != null && usernames.length > 0) > ? usernames[0] : null; > String password = (passwords != null && passwords.length > 0) > ? passwords[0] : null; > // if no other identifiers, set username to "public" (anonymous) > if (username == null && gsiUserDN == null) > username = "public"; > AuthInfo authInfo = new AuthInfo > (username, password, gsiContext, gsiUserDN, request); > > for (Iterator i = params.keySet().iterator(); i.hasNext();) { > String key = (String) i.next(); > Object val = params.get(key); > if (val == null) val = "null"; > if (!(val instanceof Object[])) val = new Object[] { val }; > } > 456,457d521 < String username = null; < String password = null; 464c528 < handleLoginAction(out, params, request, response); --- > handleLoginAction(out, authInfo, params, request, response); 476d539 < boolean success = false; 478,482c541,543 < // pool < //size is greater than initial value, shrink the connection < // pool < //size to initial value < success = DBConnectionPool.shrinkConnectionPoolSize(); --- > //pool size is greater than initial value, shrink the > //connection pool size to initial value > boolean success = DBConnectionPool.shrinkConnectionPoolSize(); 496c557,573 < if (sess.isNew() && !params.containsKey("sessionid")) { --- > boolean newSession = sess.isNew() && !params.containsKey("sessionid"); > if (authInfo.getGssContext() != null) { > // if using GSI for authentication, we lose our session > // each time, so we have to re-authenticate; fortunately > // we have enough information to do so > try { > AuthSession authSession = new AuthSession(); > authSession.authenticate(request, authInfo); > // call it a continuing session > newSession = false; > } catch (Exception e) { > throw new ServletException > ("Unable to authenticate based on GSI credentials: " > + e.getMessage(), e); > } > } > if (newSession) { 499a577 > authInfo = new AuthInfo("public", null); 501c579 < sess.setAttribute("username", username); --- > sess.setAttribute("auth", authInfo); 524c602 < * sess.getAttribute("username") + " into session --- > * sess.getAttribute("auth") + " into session 535c613,614 < username = (String) sess.getAttribute("username"); --- > authInfo = (AuthInfo) sess.getAttribute("auth"); > username = authInfo.getUsername(); 538d616 < password = (String) sess.getAttribute("password"); 543c621,623 < if (username == null || (username.trim().equals(""))) { --- > if ((username == null || (username.trim().equals(""))) > && gsiContext == null ) > { 544a625,626 > authInfo = new AuthInfo(username, null); > sess.setAttribute("auth", authInfo); 619c701 < handleGetPrincipalsAction(out, username, password); --- > handleGetPrincipalsAction(out, authInfo); 646c728 < } else if (action.equals("login") || action.equals("logout")) { --- > } else if (action.equals("login") || action.equals("logout"), groupnames) { 709a792,841 > /** Assume that map's keys are objects and its values are arrays. */ > private void addToMultimap(Map params, String key, String value) { > if (params.containsKey(key)) { > String[] oldArray; > Object old = params.get(key); > if (old instanceof String[]) oldArray = (String[]) old; > else { > oldArray = new String[1]; > oldArray[0] = String.valueOf(old); > } > String[] newArray = new String[oldArray.length + 1]; > System.arraycopy(oldArray, 0, newArray, 0, oldArray.length); > newArray[newArray.length - 1] = value; > params.put(key, newArray); > } > else params.put(key, new String[] { value }); > } > > private static final int READ_CHUNK_SIZE = 1024; > > private String readInputStreamAsString(HttpServletRequest request) > throws IOException > { > ServletInputStream in = request.getInputStream(); > List byteses = new ArrayList(); > int total = 0; > while(true) { > byte[] k = new byte[READ_CHUNK_SIZE]; > int n = in.read(k); > if (n <= 0) break; > else { > if (n < READ_CHUNK_SIZE) { > byte[] k2 = new byte[n]; > System.arraycopy(k, 0, k2, 0, n); > k = k2; > } > total += n; > byteses.add(k); > } > } > byte[] all = new byte[total]; > int start = 0; > for (int i = 0; i < byteses.size(); i++) { > byte[] k = (byte[]) byteses.get(i); > System.arraycopy(k, 0, all, start, k.length); > start += k.length; > } > return new String(all); > } > 715c847 < private void handleLoginAction(PrintWriter out, Hashtable params, --- > private void handleLoginAction(PrintWriter out, AuthInfo info, Hashtable params, 719c851 < AuthSession sess = null; --- > AuthSession sess; 721c853 < if(params.get("username") == null){ --- > if(info.getUsername() == null && info.getGssContext() == null){ 730c862,864 < if(params.get("password") == null){ --- > if(info.getPassword() == null && info.getGssContext() == null > && !info.isLocal()) > { 739,741c873,874 < String un = ((String[]) params.get("username"))[0]; < MetaCatUtil.debugMessage("user " + un + " try to login", 20); < String pw = ((String[]) params.get("password"))[0]; --- > MetaCatUtil.debugMessage > ("user " + info.toString(true) + " try to login", 20); 756c889,890 < boolean isValid = sess.authenticate(request, un, pw); --- > > boolean isValid = sess.authenticate(request, info); 763c897 < + "which has username" + session.getAttribute("username") --- > + "which has username" + session.getAttribute("auth") 807c941 < + sess.getAttribute("username") --- > + sess.getAttribute("auth") 941,943c1075,1077 < "attachment; filename=" < + docId + ".zip"); // Set the name of the zip file < --- > "attachment; filename=" > + docId + ".zip"); // Set the name of the zip file > 1357c1491 < --- > 1642c1776 < --- > 1644c1778 < out.println(""); --- > out.println(""); 2169,2170c2303 < private void handleGetPrincipalsAction(PrintWriter out, String user, < String password) --- > private void handleGetPrincipalsAction(PrintWriter out, AuthInfo info) 2174c2307 < String principals = auth.getPrincipals(user, password); --- > String principals = auth.getPrincipals(info); 2478,2479c2611 < String username = null; < String password = null; --- > AuthInfo auth = null; 2485a2618 > // TODO: don't do this if GSI, since session will be new every time 2487,2488c2620,2621 < username = "public"; < sess.setAttribute("username", username); --- > auth = new AuthInfo("public", null); > sess.setAttribute("auth", auth); 2490,2491c2623 < username = (String) sess.getAttribute("username"); < password = (String) sess.getAttribute("password"); --- > auth = (AuthInfo) sess.getAttribute("auth"); 2512,2513c2644,2645 < if (username != null && !username.equals("public")) { < handleUploadAction(request, out, params, fileList, username, --- > if (auth != null && !"public".equals(auth.getUsername())) { > handleUploadAction(request, out, params, fileList, auth.getUsername(), 2909c3041 < --- > Index: src/edu/ucsb/nceas/metacat/client/Metacat.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/client/Metacat.java,v retrieving revision 1.14 diff -r1.14 Metacat.java 26a27,28 > import org.ietf.jgss.GSSCredential; > 54c56,88 < /** --- > /** > *

Log in to a Metacat server using a Grid Security Infrastructure (GSI) > * credential to establish an HTTPS connection. Instead of authenticating > * the user via username and password, the user's identity will be > * extracted from the credential's Distinguished Name (DN).

> * > *

Note that some installations will not have the necessary libraries to > * run GSI, and therefore we need to be able to run the non-GSI Metacat > * client even if those JARs are absent -- catching NoClassDefFoundError, > * etc.

> * > * @return the response string from metacat in XML format > * @throws MetacatAuthException when the client certificate is missing or > * is not trusted or represents a user who is unknown or not authorized to > * log in, or if the underlying connection is HTTP instead of HTTPS. > * @throws UnsupportedOperationException if this client does not support > * GSI-HTTPS. > */ > public String login(GSSCredential credential) > throws MetacatAuthException, MetacatInaccessibleException; > > /** > * Log in over a trusted connection (usually localhost HTTP) with just > * a username to identify the user. The server will only allow this login > * method if it is configured to fully trust incoming connections from this > * client. > * > *

This may be used, depending on the server's configuration, with > * a PKI Distinguished Name (DN), or with an LDAP name.

> */ > public String login(String username) throws MetacatInaccessibleException, MetacatAuthException; > > /** 148d181 < * @param xmlDocument a Reader for accessing the document to be inserted 238c271 < * @returns the sessionId as a String, or null if the session is invalid --- > * @return the sessionId as a String, or null if the session is invalid 248c281 < * @param String the sessionId from a previously established session --- > * @param sessionId the session ID from a previously established session Index: src/edu/ucsb/nceas/metacat/client/MetacatClient.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/client/MetacatClient.java,v retrieving revision 1.18 diff -r1.18 MetacatClient.java 27,36d26 < import java.io.BufferedReader; < import java.io.InputStream; < import java.io.InputStreamReader; < import java.io.PushbackReader; < import java.io.IOException; < import java.io.StringWriter; < import java.io.Reader; < import java.net.URL; < import java.util.Properties; < 39c29,34 < import java.io.File; --- > import edu.ucsb.nceas.metacat.client.gsi.MetacatGsiClient; > import org.ietf.jgss.GSSCredential; > > import java.io.*; > import java.net.URL; > import java.util.Properties; 49,50c44,45 < /** The URL string for the metacat server */ < private String metacatUrl; --- > /** The URL string for the metacat server */ > private String metacatUrl; 52,53c47,48 < /** The session identifier for the session */ < private String sessionId; --- > /** The session identifier for the session */ > private String sessionId; 55,802c50,839 < /** < * Constructor to create a new instance. Protected because instances < * should only be created by the factory MetacatFactory. < */ < protected MetacatClient() < { < this.metacatUrl = null; < this.sessionId = null; < } < < /** < * Method used to log in to a metacat server. Implementations will need < * to cache a cookie value to make the session persistent. Each time a < * call is made to one of the other methods (e.g., read), the cookie will < * need to be passed back to the metacat server along with the request. < * < * @param username the username of the user, like an LDAP DN < * @param password the password for that user for authentication < * @return the response string from metacat in XML format < * @throws MetacatAuthException when the username/password could < * not be authenticated < */ < public String login(String username, String password) < throws MetacatAuthException, MetacatInaccessibleException < { < Properties prop = new Properties(); < prop.put("action", "login"); < prop.put("qformat", "xml"); < prop.put("username", username); < prop.put("password", password); < < String response = null; < try { < response = sendDataForString(prop, null, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < if (response.indexOf("") == -1) { < setSessionId(""); < throw new MetacatAuthException(response); < } else { < int start = response.indexOf("") + 11; < int end = response.indexOf(""); < if ((start != -1) && (end != -1)) { < setSessionId(response.substring(start,end)); < } < } < return response; < } < < /** < * Method used to log out a metacat server. The Metacat server will end < * the session when this call is invoked. < * < * @return the response string from metacat in XML format < * @throws MetacatInaccessibleException when the metacat server can not be < * reached or does not respond < */ < public String logout() throws MetacatInaccessibleException, MetacatException < { < Properties prop = new Properties(); < prop.put("action", "logout"); < prop.put("qformat", "xml"); < < String response = null; < try { < response = sendDataForString(prop, null, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < if (response.indexOf("") == -1) { < throw new MetacatException(response); < } < setSessionId(""); < return response; < } < < /** < * Read an XML document from the metacat server session, accessed by docid, < * and returned as a Reader. < * < * @param docid the identifier of the document to be read < * @return a Reader for accessing the document < * @throws InsufficientKarmaException when the user has insufficent rights < * for the operation < * @throws MetacatInaccessibleException when the metacat server can not be < * reached or does not respond < * @throws MetacatException when the metacat server generates another error < */ < public Reader read(String docid) throws InsufficientKarmaException, < MetacatInaccessibleException, MetacatException < { < PushbackReader pbr = null; < < Properties prop = new Properties(); < prop.put("action", "read"); < prop.put("qformat", "xml"); < prop.put("docid", docid); < < InputStream response = null; < try { < response = sendData(prop, null, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < pbr = new PushbackReader(new InputStreamReader(response), 512); < try { < char[] characters = new char[512]; < int len = pbr.read(characters, 0, 512); < StringWriter sw = new StringWriter(); < sw.write(characters, 0, len); < String message = sw.toString(); < sw.close(); < pbr.unread(characters, 0, len); < < if (message.indexOf("") != -1) { < if (message.indexOf("does not have permission") != -1) { < throw new InsufficientKarmaException(message); < } else { < throw new MetacatException(message); < } < } < } catch (IOException ioe) { < throw new MetacatException( < "MetacatClient: Error converting Reader to String." < + ioe.getMessage()); < } < < return pbr; < } < < < /** < * Read inline data from the metacat server session, accessed by < * inlinedataid and returned as a Reader. < * < * @param inlinedataid the identifier of the data to be read < * @return a Reader for accessing the document < * @throws InsufficientKarmaException when the user has insufficent rights < * for the operation < * @throws MetacatInaccessibleException when the metacat server can not be < * reached or does not respond < * @throws MetacatException when the metacat server generates another error < */ < public Reader readInlineData(String inlinedataid) < throws InsufficientKarmaException, < MetacatInaccessibleException, MetacatException < { < PushbackReader pbr = null; < < Properties prop = new Properties(); < prop.put("action", "readinlinedata"); < prop.put("inlinedataid", inlinedataid); < < InputStream response = null; < try { < response = sendData(prop, null, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < pbr = new PushbackReader(new InputStreamReader(response), 512); < try { < char[] characters = new char[512]; < int len = pbr.read(characters, 0, 512); < StringWriter sw = new StringWriter(); < sw.write(characters, 0, len); < String message = sw.toString(); < sw.close(); < pbr.unread(characters, 0, len); < < if (message.indexOf("") != -1) { < if (message.indexOf("does not have permission") != -1) { < throw new InsufficientKarmaException(message); < } else { < throw new MetacatException(message); < } < } < } catch (IOException ioe) { < throw new MetacatException( < "MetacatClient: Error converting Reader to String." < + ioe.getMessage()); < } < < return pbr; < } < < /** < * Query the metacat document store with the given metacat-compatible < * query document, and return the result set as a Reader. < * < * @param xmlQuery a Reader for accessing the XML version of the query < * @return a Reader for accessing the result set < */ < public Reader query(Reader xmlQuery) throws MetacatInaccessibleException, < IOException < { < Reader reader = null; < String query = null; < try { < query = IOUtil.getAsString(xmlQuery, true); < } catch (IOException ioE) { < throw ioE; < } < < //set up properties < Properties prop = new Properties(); < prop.put("action", "squery"); < prop.put("qformat", "xml"); < prop.put("query", query); < < InputStream response = null; < try { < response = sendData(prop, null, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < reader = new InputStreamReader(response); < return reader; < } < < /** < * Insert an XML document into the repository. < * < * @param docid the docid to insert the document < * @param xmlDocument a Reader for accessing the XML document to be inserted < * @param schema a Reader for accessing the DTD or XML Schema for < * the document < * @return the metacat response message < * @throws InsufficientKarmaException when the user has insufficent rights < * for the operation < * @throws MetacatInaccessibleException when the metacat server can not be < * reached or does not respond < * @throws MetacatException when the metacat server generates another error < * @throws IOException when there is an error reading the xml document < */ < public String insert(String docid, Reader xmlDocument, Reader schema) < throws InsufficientKarmaException, MetacatException, IOException, < MetacatInaccessibleException < { < Reader reader = null; < String doctext = null; < String schematext = null; < try { < doctext = IOUtil.getAsString(xmlDocument, true); < if (schema != null) { < schematext = IOUtil.getAsString(schema, true); < } < } catch (IOException ioE) { < throw ioE; < } < < //set up properties < Properties prop = new Properties(); < prop.put("action", "insert"); < prop.put("docid", docid); < prop.put("doctext", doctext); < if (schematext != null) { < prop.put("dtdtext", schematext); < } < < String response = null; < try { < response = sendDataForString(prop, null, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < // Check for an error condition < if (response.indexOf("") != -1) { < if (response.indexOf("does not have permission") != -1) { < throw new InsufficientKarmaException(response); < } else { < throw new MetacatException(response); < } < } < < return response; < } < < /** < * Update an XML document in the repository. < * < * @param docid the docid to update < * @param xmlDocument a Reader for accessing the XML text to be updated < * @param schema a Reader for accessing the DTD or XML Schema for < * the document < * @return the metacat response message < * @throws InsufficientKarmaException when the user has insufficent rights < * for the operation < * @throws MetacatInaccessibleException when the metacat server can not be < * reached or does not respond < * @throws MetacatException when the metacat server generates another error < * @throws IOException when there is an error reading the xml document < */ < public String update(String docid, Reader xmlDocument, Reader schema) < throws InsufficientKarmaException, MetacatException, IOException, < MetacatInaccessibleException < { < Reader reader = null; < String doctext = null; < String schematext = null; < try { < doctext = IOUtil.getAsString(xmlDocument, true); < if (schema != null) { < schematext = IOUtil.getAsString(schema, true); < } < } catch (IOException ioE) { < throw ioE; < } < < //set up properties < Properties prop = new Properties(); < prop.put("action", "update"); < prop.put("docid", docid); < prop.put("doctext", doctext); < if (schematext != null) { < prop.put("dtdtext", schematext); < } < < String response = null; < try { < response = sendDataForString(prop, null, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < // Check for an error condition < if (response.indexOf("") != -1) { < if (response.indexOf("does not have permission") != -1) { < throw new InsufficientKarmaException(response); < } else { < throw new MetacatException(response); < } < } < < return response; < } < < /** < * Upload a data document into the repository. < * < * @param docid the docid to insert the document < * @param document a Reader for accessing the document to be uploaded < * @return the metacat response message < * @throws InsufficientKarmaException when the user has insufficent rights < * for the operation < * @throws MetacatInaccessibleException when the metacat server can not be < * reached or does not respond < * @throws MetacatException when the metacat server generates another error < * @throws IOException when there is an error reading the xml document < */ < public String upload(String docid, File file) < throws InsufficientKarmaException, MetacatException, IOException, < MetacatInaccessibleException < { < < URL url = new URL(metacatUrl.trim()); < HttpMessage msg = new HttpMessage(url); < //set up properties < Properties arg = new Properties(); < arg.put("action", "upload"); < arg.put("docid", docid); < < Properties filenames = new Properties(); < String filename = file.getAbsolutePath(); < filenames.put("datafile", filename); < < String response = null; < try { < response = sendDataForString(arg, filenames, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < // Check for an error condition < if (response.indexOf("") != -1) { < if (response.indexOf("does not have permission") != -1) { < throw new InsufficientKarmaException(response); < } else { < throw new MetacatException(response); < } < } < < return response; < } < < /** < * Upload a data document into the repository. < * < * @param docid the docid to insert the document < * @param document a Reader for accessing the document to be uploaded < * @return the metacat response message < * @throws InsufficientKarmaException when the user has insufficent rights < * for the operation < * @throws MetacatInaccessibleException when the metacat server can not be < * reached or does not respond < * @throws MetacatException when the metacat server generates another error < * @throws IOException when there is an error reading the xml document < */ < < < public String upload(String docid, String filename, InputStream fileData, < int size) < throws InsufficientKarmaException, MetacatException, IOException, < MetacatInaccessibleException { < < URL url = new URL(metacatUrl.trim()); < HttpMessage msg = new HttpMessage(url); < //set up properties < Properties arg = new Properties(); < arg.put("action", "upload"); < arg.put("docid", docid); < < Properties filenames = new Properties(); < filenames.put("datafile", filename); < < String response = null; < try { < response = sendDataForString(arg, filenames, fileData, size); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < // Check for an error condition < if (response.indexOf("") != -1) { < if (response.indexOf("does not have permission") != -1) { < throw new InsufficientKarmaException(response); < } else { < throw new MetacatException(response); < } < } < < return response; < } < < /** < * Delete an XML document in the repository. < * < * @param docid the docid to delete < * @return the metacat response message < * @throws InsufficientKarmaException when the user has insufficent rights < * for the operation < * @throws MetacatInaccessibleException when the metacat server can not be < * reached or does not respond < * @throws MetacatException when the metacat server generates another error < */ < public String delete(String docid) < throws InsufficientKarmaException, MetacatException, < MetacatInaccessibleException < { < //set up properties < Properties prop = new Properties(); < prop.put("action", "delete"); < prop.put("docid", docid); < < String response = null; < try { < response = sendDataForString(prop, null, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < // Check for an error condition < if (response.indexOf("") != -1) { < if (response.indexOf("does not have permission") != -1) { < throw new InsufficientKarmaException(response); < } else { < throw new MetacatException(response); < } < } < return response; < } < < < /** < * set the access on an XML document in the repository. < * < * @param _docid the docid of the document for which the access should be applied. < * < * @param _principal the document's principal < * < * @param _permission the access permission to be applied to the docid < * {e.g. read,write,all} < * < * @param _permType the permission type to be applied to the document < * {e.g. allow or deny} < * < * @param _permOrder the order that the document's permissions should be < * processed {e.g. denyFirst or allowFirst} < * < * < * @return the metacat response message < * < * @throws InsufficientKarmaException when the user has insufficent rights < * for the operation < * @throws MetacatInaccessibleException when the metacat server can not be < * reached or does not respond < * @throws MetacatException when the metacat server generates another error < */ < public String setAccess(String _docid, String _principal, String < _permission, String _permType, < String _permOrder ) < throws InsufficientKarmaException, MetacatException, < MetacatInaccessibleException < { < //set up properties < Properties prop = new Properties(); < prop.put("action", "setaccess"); < prop.put("docid", _docid); < prop.put("principal", _principal); < prop.put("permission", _permission); < prop.put("permType", _permType); < prop.put("permOrder", _permOrder); < < String response = null; < try { < response = sendDataForString(prop, null, null, 0); < } catch (Exception e) { < throw new MetacatInaccessibleException(e.getMessage()); < } < < // Check for an error condition < if (response.indexOf("") != -1) { < if (response.indexOf("does not have permission") != -1) { < throw new InsufficientKarmaException(response); < } else { < throw new MetacatException(response); < } < } < return response; < } < < /** < * When the MetacatFactory creates an instance it needs to set the < * MetacatUrl to which connections should be made. < * < * @param metacatUrl the URL for the metacat server < */ < public void setMetacatUrl(String metacatUrl) < { < this.metacatUrl = metacatUrl; < } < < /** < * Get the session identifier for this session. This is only valid if < * the login methods has been called successfully for this Metacat object < * beforehand. < * < * @returns the sessionId as a String, or null if the session is invalid < */ < public String getSessionId() < { < return this.sessionId; < } < < /** < * Set the session identifier for this session. This identifier was < * previously established with a call to login. To continue to use the < * same session, set the session id before making a call to one of the < * metacat access methods (e.g., read, query, insert, etc.). < * < * @param String the sessionId from a previously established session < */ < public void setSessionId(String sessionId) < { < this.sessionId = sessionId; < } < < /** < * The method will return the lasted revision in metacat server < * for a given document id. If some error happent, this method will throw < * a exception. < * @param docId String the given docid you want to use. the docid it self < * can have or haven't revision number < * @throws MetacatException < */ < public int getNewestDocRevision(String docId) throws MetacatException < { < int rev = 0; < //set up properties < Properties prop = new Properties(); < prop.put("action", "getrevisionanddoctype"); < prop.put("docid", docId); < < String response = null; < try < { < response = sendDataForString(prop, null, null, 0); < String revStr = parserRevisionResponse(response); < Integer revObj = new Integer(revStr); < rev = revObj.intValue(); < // Check for an error condition < if (response.indexOf("") != -1) < { < throw new MetacatException(response); < } < < } < catch (Exception e) < { < throw new MetacatException(e.getMessage()); < } < return rev; < } < < < /************************************************************************ < * PRIVATE METHODS < ************************************************************************/ < < /** < * Send a request to metacat. < * < * @param prop the properties to be URL encoded and sent < * @param filename the properties to be sent to Metacat < * in case of upload, otherwise null < * @param fileData the inputStream for the file data to be sent to Metacat < * in case of upload, otherwise null < * @param size the size of the data being sent to Metacat < * in case of upload, otherwise 0 < */ < synchronized private InputStream sendDataOnce(Properties args, < Properties filename, < InputStream fileData, < int size) < throws Exception < { < InputStream returnStream = null; < URL url = new URL(metacatUrl); < HttpMessage msg = new HttpMessage(url); < msg.setCookie("JSESSIONID="+this.sessionId); < if (filename == null){ < returnStream = msg.sendPostData(args); < } else if (fileData == null){ < returnStream = msg.sendPostData(args, filename); < } else if (size > 0) { < returnStream = msg.sendPostData(args, filename, fileData, size); < } else { < throw new MetacatException("Invalid size specified for " + < "the input stream being passed"); < } < return returnStream; < } < < /** < * Send a request to Metacat < * < * @param args the properties to be sent to Metacat < * @param filename the properties to be sent to Metacat < * in case of upload, otherwise null < * @param fileData the inputStream for the file data to be sent to Metacat < * in case of upload, otherwise null < * @param size the size of the data being sent to Metacat < * in case of upload, otherwise 0 < * @return InputStream as returned by Metacat < */ < synchronized private InputStream sendData(Properties args, < Properties filename, < InputStream fileData, < int size) < throws Exception < { < InputStream returnStream = null; < < /* < Note: The reason that there are three try statements all executing < the same code is that there is a problem with the initial connection < using the HTTPClient protocol handler. These try statements make < sure that a connection is made because it gives each connection a < 2nd and 3rd chance to work before throwing an error. < THIS IS A TOTAL HACK. THIS NEEDS TO BE LOOKED INTO AFTER THE BETA1 < RELEASE OF MORPHO!!! cwb (7/24/01) < */ < try { < return sendDataOnce(args, filename, fileData, size); < } catch (Exception e) { < try { < return sendDataOnce(args, filename, fileData, size); < } catch (Exception e2) { < try { < return sendDataOnce(args, filename, fileData, size); < } catch (Exception e3) { < System.err.println( < "Failed to send data to metacat 3 times."); < throw e3; < } < } < } < } < < /** < * Send a request to Metacat < * < * @param args the properties to be sent to Metacat < * @param filename the properties to be sent to Metacat < * in case of upload, otherwise null < * @param fileData the inputStream for the file data to be sent to Metacat < * in case of upload, otherwise null < * @param size the size of the data being sent to Metacat < * in case of upload, otherwise 0 < * @return a string as returned by Metacat < */ < synchronized private String sendDataForString(Properties args, < Properties filename, < InputStream fileData, < int size) < throws Exception < { < String response = null; < < try { < InputStreamReader returnStream = < new InputStreamReader(sendData(args, filename, < fileData, size)); < StringWriter sw = new StringWriter(); < int len; < char[] characters = new char[512]; < while ((len = returnStream.read(characters, 0, 512)) != -1) { < sw.write(characters, 0, len); < } < returnStream.close(); < response = sw.toString(); < sw.close(); < } catch (Exception e) { < throw e; < } < return response; < } < < /* < * "getversionanddoctype" action will return a string from metacat server. < * The string format is "revision;doctype"(This is bad idea, we should use xml) < * This method will get revision string from the response string < */ < private String parserRevisionResponse(String response) throws Exception < { < String revision = null; < if (response != null) < { < int firstSemiCol = response.indexOf(";"); < revision = response.substring(0, firstSemiCol); < } < return revision; < } --- > /** > * Constructor to create a new instance. Protected because instances > * should only be created by the factory MetacatFactory. > */ > protected MetacatClient() > { > this.metacatUrl = null; > this.sessionId = null; > } > > /** > * Method used to log in to a metacat server. Implementations will need > * to cache a cookie value to make the session persistent. Each time a > * call is made to one of the other methods (e.g., read), the cookie will > * need to be passed back to the metacat server along with the request. > * > * @param username the username of the user, like an LDAP DN > * @param password the password for that user for authentication > * @return the response string from metacat in XML format > * @throws MetacatAuthException when the username/password could > * not be authenticated > */ > public String login(String username, String password) > throws MetacatAuthException, MetacatInaccessibleException > { > Properties prop = new Properties(); > prop.put("action", "login"); > prop.put("qformat", "xml"); > if (username != null) prop.put("username", username); > if (password != null) prop.put("password", password); > > String response = null; > try { > response = sendDataForString(prop, null, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > if (response.indexOf("") == -1) { > setSessionId(""); > throw new MetacatAuthException(response); > } else { > int start = response.indexOf("") + 11; > int end = response.indexOf(""); > if ((start != -1) && (end != -1)) { > setSessionId(response.substring(start,end)); > } > } > return response; > } > > /** > * Not implemented -- use {@link MetacatGsiClient} instead. > * @throws UnsupportedOperationException every time > */ > public String login(GSSCredential credential) > throws MetacatAuthException, MetacatInaccessibleException > { > // be careful not to do any class-loading here, since some clients will > // not have the JARs needed to run the GSI-enabled Metacat client. > throw new UnsupportedOperationException > ("Not implemented -- use MetacatGsiClient instead."); > } > > /** > * Log in over a trusted connection (usually localhost HTTP) with just > * a username to identify the user. The server will only allow this login > * method if it is configured to fully trust incoming connections from this > * client. > * > *

This may be used, depending on the server's configuration, with > * a PKI Distinguished Name (DN), or with an LDAP name.

> */ > public String login(String username) > throws MetacatInaccessibleException, MetacatAuthException > { > return login(username, null); > } > > /** > * Method used to log out a metacat server. The Metacat server will end > * the session when this call is invoked. > * > * @return the response string from metacat in XML format > * @throws MetacatInaccessibleException when the metacat server can not be > * reached or does not respond > */ > public String logout() throws MetacatInaccessibleException, MetacatException > { > Properties prop = new Properties(); > prop.put("action", "logout"); > prop.put("qformat", "xml"); > > String response = null; > try { > response = sendDataForString(prop, null, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > if (response.indexOf("") == -1) { > throw new MetacatException(response); > } > setSessionId(""); > return response; > } > > /** > * Read an XML document from the metacat server session, accessed by docid, > * and returned as a Reader. > * > * @param docid the identifier of the document to be read > * @return a Reader for accessing the document > * @throws InsufficientKarmaException when the user has insufficent rights > * for the operation > * @throws MetacatInaccessibleException when the metacat server can not be > * reached or does not respond > * @throws MetacatException when the metacat server generates another error > */ > public Reader read(String docid) throws InsufficientKarmaException, > MetacatInaccessibleException, MetacatException > { > PushbackReader pbr = null; > > Properties prop = new Properties(); > prop.put("action", "read"); > prop.put("qformat", "xml"); > prop.put("docid", docid); > > InputStream response = null; > try { > response = sendData(prop, null, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > pbr = new PushbackReader(new InputStreamReader(response), 512); > try { > char[] characters = new char[512]; > int len = pbr.read(characters, 0, 512); > StringWriter sw = new StringWriter(); > sw.write(characters, 0, len); > String message = sw.toString(); > sw.close(); > pbr.unread(characters, 0, len); > > if (message.indexOf("") != -1) { > if (message.indexOf("does not have permission") != -1) { > throw new InsufficientKarmaException(message); > } else { > throw new MetacatException(message); > } > } > } catch (IOException ioe) { > throw new MetacatException( > "MetacatClient: Error converting Reader to String: " > + ioe.getMessage(), ioe); > } > > return pbr; > } > > > /** > * Read inline data from the metacat server session, accessed by > * inlinedataid and returned as a Reader. > * > * @param inlinedataid the identifier of the data to be read > * @return a Reader for accessing the document > * @throws InsufficientKarmaException when the user has insufficent rights > * for the operation > * @throws MetacatInaccessibleException when the metacat server can not be > * reached or does not respond > * @throws MetacatException when the metacat server generates another error > */ > public Reader readInlineData(String inlinedataid) > throws InsufficientKarmaException, > MetacatInaccessibleException, MetacatException > { > PushbackReader pbr = null; > > Properties prop = new Properties(); > prop.put("action", "readinlinedata"); > prop.put("inlinedataid", inlinedataid); > > InputStream response = null; > try { > response = sendData(prop, null, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > pbr = new PushbackReader(new InputStreamReader(response), 512); > try { > char[] characters = new char[512]; > int len = pbr.read(characters, 0, 512); > StringWriter sw = new StringWriter(); > sw.write(characters, 0, len); > String message = sw.toString(); > sw.close(); > pbr.unread(characters, 0, len); > > if (message.indexOf("") != -1) { > if (message.indexOf("does not have permission") != -1) { > throw new InsufficientKarmaException(message); > } else { > throw new MetacatException(message); > } > } > } catch (IOException ioe) { > throw new MetacatException( > "MetacatClient: Error converting Reader to String: " > + ioe.getMessage(), ioe); > } > > return pbr; > } > > /** > * Query the metacat document store with the given metacat-compatible > * query document, and return the result set as a Reader. > * > * @param xmlQuery a Reader for accessing the XML version of the query > * @return a Reader for accessing the result set > */ > public Reader query(Reader xmlQuery) throws MetacatInaccessibleException, > IOException > { > Reader reader = null; > String query = null; > try { > query = IOUtil.getAsString(xmlQuery, true); > } catch (IOException ioE) { > throw ioE; > } > > //set up properties > Properties prop = new Properties(); > prop.put("action", "squery"); > prop.put("qformat", "xml"); > prop.put("query", query); > > InputStream response = null; > try { > response = sendData(prop, null, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > reader = new InputStreamReader(response); > return reader; > } > > /** > * Insert an XML document into the repository. > * > * @param docid the docid to insert the document > * @param xmlDocument a Reader for accessing the XML document to be inserted > * @param schema a Reader for accessing the DTD or XML Schema for > * the document > * @return the metacat response message > * @throws InsufficientKarmaException when the user has insufficent rights > * for the operation > * @throws MetacatInaccessibleException when the metacat server can not be > * reached or does not respond > * @throws MetacatException when the metacat server generates another error > * @throws IOException when there is an error reading the xml document > */ > public String insert(String docid, Reader xmlDocument, Reader schema) > throws InsufficientKarmaException, MetacatException, IOException, > MetacatInaccessibleException > { > Reader reader = null; > String doctext = null; > String schematext = null; > try { > doctext = IOUtil.getAsString(xmlDocument, true); > if (schema != null) { > schematext = IOUtil.getAsString(schema, true); > } > } catch (IOException ioE) { > throw ioE; > } > > //set up properties > Properties prop = new Properties(); > prop.put("action", "insert"); > prop.put("docid", docid); > prop.put("doctext", doctext); > if (schematext != null) { > prop.put("dtdtext", schematext); > } > > String response = null; > try { > response = sendDataForString(prop, null, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > // Check for an error condition > if (response.indexOf("") != -1) { > if (response.indexOf("does not have permission") != -1) { > throw new InsufficientKarmaException(response); > } else { > throw new MetacatException(response); > } > } > > return response; > } > > /** > * Update an XML document in the repository. > * > * @param docid the docid to update > * @param xmlDocument a Reader for accessing the XML text to be updated > * @param schema a Reader for accessing the DTD or XML Schema for > * the document > * @return the metacat response message > * @throws InsufficientKarmaException when the user has insufficent rights > * for the operation > * @throws MetacatInaccessibleException when the metacat server can not be > * reached or does not respond > * @throws MetacatException when the metacat server generates another error > * @throws IOException when there is an error reading the xml document > */ > public String update(String docid, Reader xmlDocument, Reader schema) > throws InsufficientKarmaException, MetacatException, IOException, > MetacatInaccessibleException > { > Reader reader = null; > String doctext = null; > String schematext = null; > try { > doctext = IOUtil.getAsString(xmlDocument, true); > if (schema != null) { > schematext = IOUtil.getAsString(schema, true); > } > } catch (IOException ioE) { > throw ioE; > } > > //set up properties > Properties prop = new Properties(); > prop.put("action", "update"); > prop.put("docid", docid); > prop.put("doctext", doctext); > if (schematext != null) { > prop.put("dtdtext", schematext); > } > > String response = null; > try { > response = sendDataForString(prop, null, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > // Check for an error condition > if (response.indexOf("") != -1) { > if (response.indexOf("does not have permission") != -1) { > throw new InsufficientKarmaException(response); > } else { > throw new MetacatException(response); > } > } > > return response; > } > > /** > * Upload a data document into the repository. > * > * @param docid the docid to insert the document > * @param document a Reader for accessing the document to be uploaded > * @return the metacat response message > * @throws InsufficientKarmaException when the user has insufficent rights > * for the operation > * @throws MetacatInaccessibleException when the metacat server can not be > * reached or does not respond > * @throws MetacatException when the metacat server generates another error > * @throws IOException when there is an error reading the xml document > */ > public String upload(String docid, File file) > throws InsufficientKarmaException, MetacatException, IOException, > MetacatInaccessibleException > { > > //set up properties > Properties arg = new Properties(); > arg.put("action", "upload"); > arg.put("docid", docid); > > Properties filenames = new Properties(); > String filename = file.getAbsolutePath(); > filenames.put("datafile", filename); > > String response = null; > try { > response = sendDataForString(arg, filenames, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > // Check for an error condition > if (response.indexOf("") != -1) { > if (response.indexOf("does not have permission") != -1) { > throw new InsufficientKarmaException(response); > } else { > throw new MetacatException(response); > } > } > > return response; > } > > /** > * Upload a data document into the repository. > * > * @param docid the docid to insert the document > * @param document a Reader for accessing the document to be uploaded > * @return the metacat response message > * @throws InsufficientKarmaException when the user has insufficent rights > * for the operation > * @throws MetacatInaccessibleException when the metacat server can not be > * reached or does not respond > * @throws MetacatException when the metacat server generates another error > * @throws IOException when there is an error reading the xml document > */ > > > public String upload(String docid, String filename, InputStream fileData, > int size) > throws InsufficientKarmaException, MetacatException, IOException, > MetacatInaccessibleException { > > //set up properties > Properties arg = new Properties(); > arg.put("action", "upload"); > arg.put("docid", docid); > > Properties filenames = new Properties(); > filenames.put("datafile", filename); > > String response; > try { > response = sendDataForString(arg, filenames, fileData, size); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > // Check for an error condition > if (response.indexOf("") != -1) { > if (response.indexOf("does not have permission") != -1) { > throw new InsufficientKarmaException(response); > } else { > throw new MetacatException(response); > } > } > > return response; > } > > /** > * Delete an XML document in the repository. > * > * @param docid the docid to delete > * @return the metacat response message > * @throws InsufficientKarmaException when the user has insufficent rights > * for the operation > * @throws MetacatInaccessibleException when the metacat server can not be > * reached or does not respond > * @throws MetacatException when the metacat server generates another error > */ > public String delete(String docid) > throws InsufficientKarmaException, MetacatException, > MetacatInaccessibleException > { > //set up properties > Properties prop = new Properties(); > prop.put("action", "delete"); > prop.put("docid", docid); > > String response = null; > try { > response = sendDataForString(prop, null, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > // Check for an error condition > if (response.indexOf("") != -1) { > if (response.indexOf("does not have permission") != -1) { > throw new InsufficientKarmaException(response); > } else { > throw new MetacatException(response); > } > } > return response; > } > > > /** > * set the access on an XML document in the repository. > * > * @param _docid the docid of the document for which the access should be applied. > * > * @param _principal the document's principal > * > * @param _permission the access permission to be applied to the docid > * {e.g. read,write,all} > * > * @param _permType the permission type to be applied to the document > * {e.g. allow or deny} > * > * @param _permOrder the order that the document's permissions should be > * processed {e.g. denyFirst or allowFirst} > * > * > * @return the metacat response message > * > * @throws InsufficientKarmaException when the user has insufficent rights > * for the operation > * @throws MetacatInaccessibleException when the metacat server can not be > * reached or does not respond > * @throws MetacatException when the metacat server generates another error > */ > public String setAccess(String _docid, String _principal, String > _permission, String _permType, > String _permOrder ) > throws InsufficientKarmaException, MetacatException, > MetacatInaccessibleException > { > //set up properties > Properties prop = new Properties(); > prop.put("action", "setaccess"); > prop.put("docid", _docid); > prop.put("principal", _principal); > prop.put("permission", _permission); > prop.put("permType", _permType); > prop.put("permOrder", _permOrder); > > String response = null; > try { > response = sendDataForString(prop, null, null, 0); > } catch (Exception e) { > throw new MetacatInaccessibleException(e); > } > > // Check for an error condition > if (response.indexOf("") != -1) { > if (response.indexOf("does not have permission") != -1) { > throw new InsufficientKarmaException(response); > } else { > throw new MetacatException(response); > } > } > return response; > } > > /** > * When the MetacatFactory creates an instance it needs to set the > * MetacatUrl to which connections should be made. > * > * @param metacatUrl the URL for the metacat server > */ > public void setMetacatUrl(String metacatUrl) > { > this.metacatUrl = metacatUrl; > } > > /** > * The value set via {@link #setMetacatUrl(String)}. > */ > public String getMetacatUrl() > { > return metacatUrl; > } > > /** > * Get the session identifier for this session. This is only valid if > * the login methods has been called successfully for this Metacat object > * beforehand. > * > * @return the sessionId as a String, or null if the session is invalid > */ > public String getSessionId() > { > return this.sessionId; > } > > /** > * Set the session identifier for this session. This identifier was > * previously established with a call to login. To continue to use the > * same session, set the session id before making a call to one of the > * metacat access methods (e.g., read, query, insert, etc.). > * > * @param sessionId the sessionId from a previously established session > */ > public void setSessionId(String sessionId) > { > this.sessionId = sessionId; > } > > /** > * The method will return the lasted revision in metacat server > * for a given document id. If some error happent, this method will throw > * a exception. > * @param docId String the given docid you want to use. the docid it self > * can have or haven't revision number > * @throws MetacatException > */ > public int getNewestDocRevision(String docId) throws MetacatException > { > int rev = 0; > //set up properties > Properties prop = new Properties(); > prop.put("action", "getrevisionanddoctype"); > prop.put("docid", docId); > > String response = null; > try > { > response = sendDataForString(prop, null, null, 0); > String revStr = parserRevisionResponse(response); > Integer revObj = new Integer(revStr); > rev = revObj.intValue(); > // Check for an error condition > if (response.indexOf("") != -1) > { > throw new MetacatException(response); > } > > } > catch (Exception e) > { > throw new MetacatException(e); > } > return rev; > } > > > /************************************************************************ > * PRIVATE METHODS > ************************************************************************/ > > /** > * Send a request to metacat. > * > * @param args the properties to be URL encoded and sent > * @param filename the properties to be sent to Metacat > * in case of upload, otherwise null > * @param fileData the inputStream for the file data to be sent to Metacat > * in case of upload, otherwise null > * @param size the size of the data being sent to Metacat > * in case of upload, otherwise 0 > */ > synchronized protected InputStream sendDataOnce(Properties args, > Properties filename, > InputStream fileData, > int size) > throws Exception > { > HttpMessage msg = createHttpMessage(); > msg.setCookie("JSESSIONID="+this.sessionId); > return xmit(msg, args, filename, fileData, size); > } > > /** Create an HttpMessage that can send messages to the server. > * Designed to be overrideable in case a subclass connects to a server > * differently. */ > protected HttpMessage createHttpMessage() > throws IOException, MetacatInaccessibleException, MetacatAuthException > { > URL url = new URL(metacatUrl.trim()); > return new HttpMessage(url); > } > > /** Helper function to {@link #sendDataOnce}. */ > protected static InputStream xmit > (HttpMessage msg, Properties args, Properties filename, > InputStream fileData, int size) > throws MetacatException, IOException > { > if (filename == null){ > return msg.sendPostData(args); > } else if (fileData == null){ > return msg.sendPostData(args, filename); > } else if (size > 0) { > return msg.sendPostData(args, filename, fileData, size); > } else { > throw new MetacatException("Invalid size specified for " + > "the input stream being passed"); > } > } > > /** > * Send a request to Metacat > * > * @param args the properties to be sent to Metacat > * @param filename the properties to be sent to Metacat > * in case of upload, otherwise null > * @param fileData the inputStream for the file data to be sent to Metacat > * in case of upload, otherwise null > * @param size the size of the data being sent to Metacat > * in case of upload, otherwise 0 > * @return InputStream as returned by Metacat > */ > synchronized private InputStream sendData(Properties args, > Properties filename, > InputStream fileData, > int size) > throws Exception > { > InputStream returnStream = null; > > /* > Note: The reason that there are three try statements all executing > the same code is that there is a problem with the initial connection > using the HTTPClient protocol handler. These try statements make > sure that a connection is made because it gives each connection a > 2nd and 3rd chance to work before throwing an error. > THIS IS A TOTAL HACK. THIS NEEDS TO BE LOOKED INTO AFTER THE BETA1 > RELEASE OF MORPHO!!! cwb (7/24/01) > */ > try { > return sendDataOnce(args, filename, fileData, size); > } catch (Exception e) { > try { > return sendDataOnce(args, filename, fileData, size); > } catch (Exception e2) { > try { > return sendDataOnce(args, filename, fileData, size); > } catch (Exception e3) { > System.err.println( > "Failed to send data to metacat 3 times."); > throw e3; > } > } > } > } > > /** > * Send a request to Metacat > * > * @param args the properties to be sent to Metacat > * @param filename the properties to be sent to Metacat > * in case of upload, otherwise null > * @param fileData the inputStream for the file data to be sent to Metacat > * in case of upload, otherwise null > * @param size the size of the data being sent to Metacat > * in case of upload, otherwise 0 > * @return a string as returned by Metacat > */ > synchronized protected String sendDataForString(Properties args, > Properties filename, > InputStream fileData, > int size) > throws Exception > { > InputStreamReader returnStream = > new InputStreamReader(sendData(args, filename, > fileData, size)); > StringWriter sw = new StringWriter(); > int len; > char[] characters = new char[512]; > while ((len = returnStream.read(characters, 0, 512)) != -1) { > sw.write(characters, 0, len); > } > returnStream.close(); > String response = sw.toString(); > sw.close(); > return response; > } > > /* > * "getversionanddoctype" action will return a string from metacat server. > * The string format is "revision;doctype"(This is bad idea, we should use xml) > * This method will get revision string from the response string > */ > private String parserRevisionResponse(String response) throws Exception > { > String revision = null; > if (response != null) > { > int firstSemiCol = response.indexOf(";"); > revision = response.substring(0, firstSemiCol); > } > return revision; > } Index: src/edu/ucsb/nceas/metacat/client/MetacatException.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/client/MetacatException.java,v retrieving revision 1.1 diff -r1.1 MetacatException.java 39a40,47 > > public MetacatException(Throwable cause) { > super(cause); > } > > public MetacatException(String message, Throwable cause) { > super(message, cause); > } Index: src/edu/ucsb/nceas/metacat/client/MetacatFactory.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/client/MetacatFactory.java,v retrieving revision 1.1 diff -r1.1 MetacatFactory.java 27c27,31 < import java.io.Reader; --- > import java.net.URL; > import java.net.MalformedURLException; > import java.util.Map; > import java.util.HashMap; > import java.util.Collections; 35,36c39,84 < private static final String metacatClientClass = < "edu.ucsb.nceas.metacat.client.MetacatClient"; --- > /** Register Metacat client classes by protocol. */ > private static final Map PROTOCOL_CLIENT_CLASS_MAP; > static { > Map protoMap = new HashMap(); > protoMap.put("http", "edu.ucsb.nceas.metacat.client.MetacatClient"); > // protoMap.put("https", "edu.ucsb.nceas.metacat.client.MetacatClient"); > protoMap.put("https", "edu.ucsb.nceas.metacat.client.gsi.MetacatGsiClient"); > // httpg requires a special class that requires GSI libraries > protoMap.put("httpg", "edu.ucsb.nceas.metacat.client.gsi.MetacatGsiClient"); > PROTOCOL_CLIENT_CLASS_MAP = Collections.unmodifiableMap(protoMap); > } > > /** > * Create a new instance of a Metacat object of raccessing a server. > * > * @param metacatUrl the url location of the metacat server > * @throws MetacatInaccessibleException when the metacat server can not > * be reached > */ > public static Metacat createMetacatConnection(String metacatUrl) > throws MetacatInaccessibleException > { > Metacat m; > try { > URL url = new URL(metacatUrl); > String clientClass = (String) > PROTOCOL_CLIENT_CLASS_MAP.get(url.getProtocol().toLowerCase()); > if (clientClass == null) > clientClass = (String) PROTOCOL_CLIENT_CLASS_MAP.get("http"); > Class c = Class.forName(clientClass); > m = (Metacat)c.newInstance(); > } catch (InstantiationException e) { > throw new MetacatInaccessibleException(e); > } catch (IllegalAccessException e) { > throw new MetacatInaccessibleException(e); > } catch (ClassNotFoundException e) { > throw new MetacatInaccessibleException > ("Unable to instantiate metacat client for server URL \"" > + metacatUrl + "\".", e); > } catch (NoClassDefFoundError e) { > throw new MetacatInaccessibleException > ("Unable to instantiate metacat client for server URL \"" > + metacatUrl + "\".", e); > } catch (MalformedURLException e) { > throw new MetacatInaccessibleException(e); > } 38,58c86 < /** < * Create a new instance of a Metacat object of raccessing a server. < * < * @param metacatUrl the url location of the metacat server < * @throws MetacatInaccessibleException when the metacat server can not < * be reached < */ < public static Metacat createMetacatConnection(String metacatUrl) < throws MetacatInaccessibleException < { < Metacat m = null; < try { < Class c = Class.forName(metacatClientClass); < m = (Metacat)c.newInstance(); < } catch (InstantiationException e) { < throw new MetacatInaccessibleException(e.getMessage()); < } catch (IllegalAccessException e) { < throw new MetacatInaccessibleException(e.getMessage()); < } catch (ClassNotFoundException e) { < throw new MetacatInaccessibleException(e.getMessage()); < } --- > m.setMetacatUrl(metacatUrl); 60,63c88,89 < m.setMetacatUrl(metacatUrl); < < return m; < } --- > return m; > } Index: src/edu/ucsb/nceas/metacat/client/MetacatInaccessibleException.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/client/MetacatInaccessibleException.java,v retrieving revision 1.1 diff -r1.1 MetacatInaccessibleException.java 40a41,48 > > public MetacatInaccessibleException(Throwable cause) { > super(cause); > } > > public MetacatInaccessibleException(String message, Throwable cause) { > super(message, cause); > } Index: src/edu/ucsb/nceas/metacat/harvesterClient/HarvesterRegistration.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/harvesterClient/HarvesterRegistration.java,v retrieving revision 1.13 diff -r1.13 HarvesterRegistration.java 28a29,30 > import edu.ucsb.nceas.metacat.AuthInfo; > 362c364 < String ldapDN; --- > String ldapDN; 379,380c381,383 < ldapDN = (String) httpSession.getAttribute("username"); < ldapPwd = (String) httpSession.getAttribute("password"); --- > AuthInfo auth = (AuthInfo) httpSession.getAttribute("auth"); > ldapDN = auth.getUsername(); > ldapPwd = auth.getPassword(); 531,532c534,536 < ldapDN = (String) httpSession.getAttribute("username"); < ldapPwd = (String) httpSession.getAttribute("password"); --- > AuthInfo auth = (AuthInfo) httpSession.getAttribute("auth"); > ldapDN = auth.getUsername(); > ldapPwd = auth.getPassword(); Index: src/edu/ucsb/nceas/metacat/harvesterClient/HarvesterRegistrationLogin.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/harvesterClient/HarvesterRegistrationLogin.java,v retrieving revision 1.7 diff -r1.7 HarvesterRegistrationLogin.java 33a34 > import edu.ucsb.nceas.metacat.AuthInfo; 42c43 < final String LDAP_DOMAIN = ",dc=ecoinformatics,dc=org"; --- > final String LDAP_DOMAIN = ",dc=ecoinformatics,dc=org"; 44,129c45,130 < /** < * Handle "GET" method requests from HTTP clients < * < * @param req The request < * @param res The response < * @throws ServletException, java.io.IOException < */ < public void doGet(HttpServletRequest req, HttpServletResponse res) < throws ServletException, java.io.IOException { < handleGetOrPost(req, res); < } < < < /** < * Handle "POST" method requests from HTTP clients < * < * @param req The request < * @param res The response < * @throws ServletException, java.io.IOException < */ < public void doPost(HttpServletRequest req, HttpServletResponse res) < throws ServletException, java.io.IOException { < handleGetOrPost(req, res); < } < < < /** < * Handle "GET" or "POST" method requests from HTTP clients < * < * @param req The request < * @param res The response < * @throws ServletException, java.io.IOException < */ < private void handleGetOrPost(HttpServletRequest req, < HttpServletResponse res) < throws ServletException, java.io.IOException { < AuthSession authSession; < String authSessionMessage; < HttpSession httpSession; < boolean isValid; < String o = req.getParameter("o"); < String organization; < String passwd = req.getParameter("passwd"); < PrintWriter out = res.getWriter(); < String uid = req.getParameter("uid"); < String user; < < if ((uid == null) || (uid.equals(""))) { < out.println("Invalid login: no Username specified."); < return; < } < else if ((o == null) || (o.equals(""))) { < out.println("Invalid login: no Organization selected."); < return; < } < else if ((passwd == null) || (passwd.equals(""))) { < out.println("Invalid login: no Password specified."); < return; < } < else { < user = "uid=" + uid + ",o=" + o + LDAP_DOMAIN; < } < < res.setContentType("text/plain"); < < try { < authSession = new AuthSession(); < isValid = authSession.authenticate(req, user, passwd); < authSessionMessage = authSession.getMessage(); < System.out.println("authSession.authenticate(): "+authSessionMessage); < out.println("authSession.authenticate(): " + authSessionMessage); < < if (isValid) { < httpSession = req.getSession(true); < httpSession.setAttribute("username", user); < httpSession.setAttribute("password", passwd); < res.sendRedirect("harvesterRegistration"); < } < else { < out.println("Invalid login"); < } < } < catch (Exception e) { < System.out.println("Error in AuthSession()" + e.getMessage()); < } < } --- > /** > * Handle "GET" method requests from HTTP clients > * > * @param req The request > * @param res The response > * @throws ServletException, java.io.IOException > */ > public void doGet(HttpServletRequest req, HttpServletResponse res) > throws ServletException, java.io.IOException { > handleGetOrPost(req, res); > } > > > /** > * Handle "POST" method requests from HTTP clients > * > * @param req The request > * @param res The response > * @throws ServletException, java.io.IOException > */ > public void doPost(HttpServletRequest req, HttpServletResponse res) > throws ServletException, java.io.IOException { > handleGetOrPost(req, res); > } > > > /** > * Handle "GET" or "POST" method requests from HTTP clients > * > * @param req The request > * @param res The response > * @throws ServletException, java.io.IOException > */ > private void handleGetOrPost(HttpServletRequest req, > HttpServletResponse res) > throws ServletException, java.io.IOException { > AuthSession authSession; > String authSessionMessage; > HttpSession httpSession; > boolean isValid; > String o = req.getParameter("o"); > String organization; > String passwd = req.getParameter("passwd"); > PrintWriter out = res.getWriter(); > String uid = req.getParameter("uid"); > String user; > > if ((uid == null) || (uid.equals(""))) { > out.println("Invalid login: no Username specified."); > return; > } > else if ((o == null) || (o.equals(""))) { > out.println("Invalid login: no Organization selected."); > return; > } > else if ((passwd == null) || (passwd.equals(""))) { > out.println("Invalid login: no Password specified."); > return; > } > else { > user = "uid=" + uid + ",o=" + o + LDAP_DOMAIN; > } > > res.setContentType("text/plain"); > > try { > authSession = new AuthSession(); > AuthInfo auth = new AuthInfo(user, passwd); > isValid = authSession.authenticate(req, auth); > authSessionMessage = authSession.getMessage(); > System.out.println("authSession.authenticate(): "+authSessionMessage); > out.println("authSession.authenticate(): " + authSessionMessage); > > if (isValid) { > httpSession = req.getSession(true); > httpSession.setAttribute("auth", auth); > res.sendRedirect("harvesterRegistration"); > } > else { > out.println("Invalid login"); > } > } > catch (Exception e) { > System.out.println("Error in AuthSession()" + e.getMessage()); > } > } Index: src/edu/ucsb/nceas/metacat/harvesterClient/LoginServlet.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/harvesterClient/LoginServlet.java,v retrieving revision 1.6 diff -r1.6 LoginServlet.java 38a39 > import edu.ucsb.nceas.metacat.AuthInfo; 46,47c47,48 < // Close all connections < System.out.println("Destroying LoginServlet"); --- > // Close all connections > System.out.println("Destroying LoginServlet"); 58,60c59,61 < throws ServletException, java.io.IOException { < // Process the data and send back the response < handleGetOrPost(request, response); --- > throws ServletException, java.io.IOException { > // Process the data and send back the response > handleGetOrPost(request, response); 71,73c72,74 < throws ServletException, java.io.IOException { < // Process the data and send back the response < handleGetOrPost(request, response); --- > throws ServletException, java.io.IOException { > // Process the data and send back the response > handleGetOrPost(request, response); 84,115c85,116 < HttpServletResponse response) < throws ServletException, java.io.IOException { < AuthSession authSession = null; < HttpSession httpSession; < boolean isValid; < PrintWriter out = response.getWriter(); < String passwd = request.getParameter("passwd"); < String user = request.getParameter("user"); < < response.setContentType("text/plain"); < < try { < authSession = new AuthSession(); < } < catch (Exception e) { < out.println("Error creating AuthSession: " + e.getMessage()); < return; < } < < isValid = authSession.authenticate(request, user, passwd); < < if (isValid) { < System.out.println(authSession.getMessage()); < httpSession = request.getSession(true); < httpSession.setAttribute("username", user); < httpSession.setAttribute("password", passwd); < response.sendRedirect("../style/skins/dev/harvesterUpload.html"); < } < else { < out.println("Error authenticating Metacat login: " + < authSession.getMessage()); < } --- > HttpServletResponse response) > throws ServletException, java.io.IOException { > AuthSession authSession = null; > HttpSession httpSession; > boolean isValid; > PrintWriter out = response.getWriter(); > String passwd = request.getParameter("passwd"); > String user = request.getParameter("user"); > AuthInfo auth = new AuthInfo(user, passwd); > > response.setContentType("text/plain"); > > try { > authSession = new AuthSession(); > } > catch (Exception e) { > out.println("Error creating AuthSession: " + e.getMessage()); > return; > } > > isValid = authSession.authenticate(request, auth); > > if (isValid) { > System.out.println(authSession.getMessage()); > httpSession = request.getSession(true); > httpSession.setAttribute("auth", auth); > response.sendRedirect("../style/skins/dev/harvesterUpload.html"); > } > else { > out.println("Error authenticating Metacat login: " + > authSession.getMessage()); > } Index: src/edu/ucsb/nceas/metacat/harvesterClient/MetUpload.java =================================================================== RCS file: /cvs/metacat/src/edu/ucsb/nceas/metacat/harvesterClient/MetUpload.java,v retrieving revision 1.8 diff -r1.8 MetUpload.java 44a45 > import edu.ucsb.nceas.metacat.AuthInfo; 84c85 < String password = (String) sess.getAttribute("password"); --- > AuthInfo auth = (AuthInfo) sess.getAttribute("auth"); 87,88c88 < String username = (String) sess.getAttribute("username"); < --- > 124c124 < upload(out, docid, sr, username, password); --- > upload(out, docid, sr, auth); 127c127 < delete(out, docid, username, password); --- > delete(out, docid, auth); 137,138c137 < * @param username the Metacat username < * @param password the Metacat password --- > * @param auth the Metacat username and password 142,143c141 < String username, < String password --- > AuthInfo auth 155c153 < metacat.login(username, password); --- > metacat.login(auth.getUsername(), auth.getPassword()); 220,221c218 < * @param username the Metacat username < * @param password the Metacat password --- > * @param auth the Metacat username and password 226,227c223 < String username, < String password --- > AuthInfo auth 247c243 < metacat.login(username, password); --- > metacat.login(auth.getUsername(), auth.getPassword());