summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Terry2013-08-01 13:23:08 (EDT)
committer David Terry2013-08-01 13:23:08 (EDT)
commit3e2cffa8085db291463ff8ac1d9e523e005f5de1 (patch)
treef4743b473da2404bd265d7db90ce5154f53c6f1f
parentf921324741f0f3f5923986b954875d3159b10c15 (diff)
downloadorg.eclipse.lyo.testsuite-3e2cffa8085db291463ff8ac1d9e523e005f5de1.zip
org.eclipse.lyo.testsuite-3e2cffa8085db291463ff8ac1d9e523e005f5de1.tar.gz
org.eclipse.lyo.testsuite-3e2cffa8085db291463ff8ac1d9e523e005f5de1.tar.bz2
[414230] Support Basic Authentication in TRS compliance testsrefs/changes/47/15047/1
Change-Id: I260d73ca0907db5c63fc26aa0fe4d32a1d7c4962 Signed-off-by: David Terry <dgterry@us.ibm.com>
-rw-r--r--org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/oslcv2/trs/BaseTest.java4
-rw-r--r--org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/FetchUtil.java189
-rw-r--r--org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/RDFModelResponseHandler.java11
-rw-r--r--org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/messages.properties3
-rw-r--r--org.eclipse.lyo.testsuite.trs/src/main/resources/config.properties15
5 files changed, 188 insertions, 34 deletions
diff --git a/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/oslcv2/trs/BaseTest.java b/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/oslcv2/trs/BaseTest.java
index b35aca3..bfb5b88 100644
--- a/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/oslcv2/trs/BaseTest.java
+++ b/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/oslcv2/trs/BaseTest.java
@@ -148,8 +148,8 @@ public class BaseTest extends TestCore{
try {
if (iter == null || iter.hasNext() != true) {
- throw new InvalidTRSException(
- Messages.getServerString("validators.missing.rdf.type.ldp.page"));
+ System.out.println(Messages.getServerString("validators.missing.rdf.type.ldp.page"));
+ return;
}
Resource page = iter.nextResource();
diff --git a/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/FetchUtil.java b/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/FetchUtil.java
index 30e1bba..55556f3 100644
--- a/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/FetchUtil.java
+++ b/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/FetchUtil.java
@@ -16,6 +16,7 @@
package org.eclipse.lyo.testsuite.server.trsutils;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
@@ -30,11 +31,14 @@ import net.oauth.OAuthException;
import net.oauth.OAuthMessage;
import net.oauth.OAuthServiceProvider;
+import org.apache.http.Header;
import org.apache.http.HttpStatus;
+import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.protocol.HttpContext;
+import org.apache.xerces.impl.dv.util.Base64;
import org.eclipse.lyo.core.trs.HttpConstants;
import com.hp.hpl.jena.rdf.model.Model;
@@ -90,37 +94,16 @@ public class FetchUtil {
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4
get.addHeader(HttpConstants.CACHE_CONTROL, "max-age=0"); //$NON-NLS-1$
+ RDFModelResponseHandler handler = new RDFModelResponseHandler(uri);
+
+ // Try to access the uri directly. If this fails attempt to retry
+ // using authentication.
try {
- model = httpClient.execute(get, new RDFModelResponseHandler(uri), httpContext);
+ model = httpClient.execute(get, handler, httpContext);
} catch (HttpResponseException e1) {
if (e1.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
- // If authentication is required attempt OAuth authentication.
- // This uses two legged OAuth which requires a functional
- // user be already configured on the resource server.
- Properties prop = TestCore.getConfigPropertiesInstance();
- String consumerKey = prop.getProperty("consumerKey");
- String consumerSecret = prop.getProperty("consumerSecret");
- String authorizationTokenURL = prop.getProperty("OAuthURL");
- String oAuthRealm = prop.getProperty("OAuthRealm");
-
- // Using the information from the config.properties file
- // construct the authentication header to use in our GET request
- OAuthServiceProvider provider = new OAuthServiceProvider(null, authorizationTokenURL, null);
- OAuthConsumer consumer = new OAuthConsumer("",consumerKey,consumerSecret,provider);
- OAuthAccessor accessor = new OAuthAccessor(consumer);
- accessor.accessToken = "";
-
- try {
- OAuthMessage message = accessor.newRequestMessage(HttpMethod.GET, prop.getProperty("configTrsEndpoint"), null);
- String authHeader = message.getAuthorizationHeader(oAuthRealm);
- get.setHeader("Authorization",authHeader);
- get.setHeader("OSLC-Core-Version", "2.0");
-
- model = httpClient.execute(get, new RDFModelResponseHandler(uri), httpContext);
- } catch (OAuthException e) {
- TestCore.terminateTest(Messages.getServerString("fetch.util.authentication.failure"), e);
- }
- }
+ model = attemptAuthentication(uri, httpClient, httpContext, model, get, handler);
+ }
}
} catch (Exception e) {
String uriLocation = Messages.getServerString("fetch.util.uri.unidentifiable"); //$NON-NLS-1$
@@ -132,9 +115,155 @@ public class FetchUtil {
throw new FetchException(MessageFormat.format(
Messages.getServerString("fetch.util.retrieve.error"), //$NON-NLS-1$
- uriLocation));
+ uriLocation), e);
}
return model;
}
-}
+
+ /**
+ * This method performs authentication based on the config.properties'
+ * AuthType setting.
+ *
+ * @param uri
+ * @param httpClient
+ * @param httpContext
+ * @param model
+ * @param get
+ * @param handler
+ * @return
+ * @throws FileNotFoundException
+ * @throws IOException
+ * @throws ClientProtocolException
+ * @throws URISyntaxException
+ */
+ private static Model attemptAuthentication(String uri,
+ HttpClient httpClient, HttpContext httpContext, Model model,
+ HttpGet get, RDFModelResponseHandler handler)
+ throws FileNotFoundException, IOException, ClientProtocolException,
+ URISyntaxException {
+ // Check the config.properties to see if the user is overriding
+ // the WWW-Authenticate header.
+ String override = TestCore.getConfigPropertiesInstance().getProperty("AuthType");
+ AuthenticationTypes overrideType = AuthenticationTypes.valueOf(override.toUpperCase());
+
+ switch (overrideType) {
+ case OAUTH:
+ return perform2LeggedOauth(httpClient, httpContext, get, uri);
+
+ case BASIC:
+ return performBasicAuthentication(httpClient, httpContext, get, uri);
+
+ case HEADER:
+ Header authTypes[] = handler.getAuthTypes();
+
+ // Determine the authentication type to attempt based on the
+ // server's response. Attempt the first type encountered that
+ // both the server and the tests support.
+ for (Header authType : authTypes) {
+ if (authType.getValue().startsWith("OAuth ")) {
+ return perform2LeggedOauth(httpClient, httpContext, get, uri);
+ } else if (authType.getValue().startsWith("Basic ")) {
+ return performBasicAuthentication(httpClient, httpContext, get, uri);
+ }
+ }
+ }
+
+ throw new InvalidRDFResourceException(Messages.getServerString("fetch.util.authentication.unknown"));
+ }
+
+ /**
+ * This method uses the username and password specified in config.properties
+ * to attempt basic authentication against a resource server.
+ *
+ * @param httpClient
+ * @param httpContext
+ * @param get
+ * @param uri
+ * @return
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ private static Model performBasicAuthentication(HttpClient httpClient, HttpContext httpContext, HttpGet get, String uri) throws FileNotFoundException, IOException {
+ // Obtain the username and password from the config.properties file
+ Properties prop = TestCore.getConfigPropertiesInstance();
+ String username = prop.getProperty("username");
+ String password = prop.getProperty("password");
+
+ // Construct the authentication header by using Base64 encoding on the
+ // supplied username and password
+ String authString = username + ":" + password;
+ authString = new String(Base64.encode(authString.getBytes(HttpConstants.DEFAULT_ENCODING)));
+ authString = "Basic " + authString;
+
+ get.setHeader("Authorization", authString);
+ get.setHeader("OSLC-Core-Version", "2.0");
+
+ Model model = null;
+
+ try {
+ model = httpClient.execute(get, new RDFModelResponseHandler(uri), httpContext);
+ } catch (Exception e) {
+ TestCore.terminateTest(Messages.getServerString("fetch.util.authentication.failure"), e);
+ }
+
+ return model;
+ }
+
+ /**
+ * This method attempts to authenticate with a server using OAuth two
+ * legged authentication. A functional user with a consumer key and secret
+ * must have already been created on the resource server and specified in
+ * the config.properties file.
+ *
+ * @param httpClient
+ * @param httpContext
+ * @param get
+ * @param uri
+ * @return
+ * @throws ClientProtocolException
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ private static Model perform2LeggedOauth(HttpClient httpClient, HttpContext httpContext, HttpGet get, String uri) throws ClientProtocolException, IOException, URISyntaxException {
+ // Get the necessary OAuth values from the config.properties file
+ Properties prop = TestCore.getConfigPropertiesInstance();
+ String consumerKey = prop.getProperty("consumerKey");
+ String consumerSecret = prop.getProperty("consumerSecret");
+ String authorizationTokenURL = prop.getProperty("OAuthURL");
+ String oAuthRealm = prop.getProperty("OAuthRealm");
+
+ // Using the information from the config.properties file
+ // construct the authentication header to use in our GET request
+ OAuthServiceProvider provider = new OAuthServiceProvider(null, authorizationTokenURL, null);
+ OAuthConsumer consumer = new OAuthConsumer("",consumerKey,consumerSecret,provider);
+ OAuthAccessor accessor = new OAuthAccessor(consumer);
+ accessor.accessToken = "";
+
+ Model model = null;
+
+ try {
+ OAuthMessage message = accessor.newRequestMessage(HttpMethod.GET, uri, null);
+ String authHeader = message.getAuthorizationHeader(oAuthRealm);
+
+ get.setHeader("Authorization",authHeader);
+ get.setHeader("OSLC-Core-Version", "2.0");
+
+ model = httpClient.execute(get, new RDFModelResponseHandler(uri), httpContext);
+ } catch (OAuthException e) {
+ TestCore.terminateTest(Messages.getServerString("fetch.util.authentication.failure"), e);
+ }
+
+ return model;
+ }
+
+ /**
+ * A list of the currently supported authentication types. The user specifies
+ * the desired type in the config.properties' AuthType property.
+ */
+ private enum AuthenticationTypes {
+ HEADER,
+ OAUTH,
+ BASIC
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/RDFModelResponseHandler.java b/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/RDFModelResponseHandler.java
index 627788b..2941ce0 100644
--- a/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/RDFModelResponseHandler.java
+++ b/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/RDFModelResponseHandler.java
@@ -42,6 +42,7 @@ public class RDFModelResponseHandler implements ResponseHandler<Model> {
protected int statusCode = 0;
protected String reason = null;
+ protected Header[] authTypes = null;
public RDFModelResponseHandler(Node base) {
this.base = base;
@@ -53,6 +54,7 @@ public class RDFModelResponseHandler implements ResponseHandler<Model> {
@Override
public Model handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
+ authTypes = response.getHeaders("WWW-Authenticate");
statusCode = response.getStatusLine().getStatusCode();
reason = response.getStatusLine().getReasonPhrase();
Model model = ModelUtil.createDefaultModel();
@@ -127,4 +129,13 @@ public class RDFModelResponseHandler implements ResponseHandler<Model> {
public String getReasonPhrase() {
return reason;
}
+
+ /**
+ * Return the supported authentication types of the server.
+ *
+ * @return authTypes - The value of the server's WWW-Authenticate header
+ */
+ public Header[] getAuthTypes() {
+ return authTypes;
+ }
} \ No newline at end of file
diff --git a/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/messages.properties b/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/messages.properties
index 99b51ec..7af0cc9 100644
--- a/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/messages.properties
+++ b/org.eclipse.lyo.testsuite.trs/src/main/java/org/eclipse/lyo/testsuite/server/trsutils/messages.properties
@@ -19,6 +19,7 @@ model.util.inputstream.null = InputStream must not be null
model.util.outputstream.null = OutputStream must not be null
fetch.util.authentication.failure = Tests were not authorized to access TRS resource and fallback OAuth authentication failed.
+fetch.util.authentication.unknown = The authentication type specified by the resource server or config.properties is not supported.
fetch.util.uri.null = Argument uri must not be null
fetch.util.httpclient.null = Argument httpClient must not be null
fetch.util.uri.unidentifiable = Unable to identify URI Location
@@ -56,7 +57,7 @@ validators.missing.ldp.next.page = Missing ldp:nextPage property
validators.missing.ldp.page.of = Missing or invalid ldp:pageOf property
validators.missing.rdf.type.oslc.trs = Missing rdf:type trs:TrackedResourceSet
validators.missing.rdf.type.ldp.container = Missing rdf:type ldp:Container
-validators.missing.rdf.type.ldp.page = Missing rdf:type ldp:Page
+validators.missing.rdf.type.ldp.page = Missing rdf:type ldp:Page. ***Warning: Though base pagination isn't required, it is highly recommended that you implement it***
validators.missing.trs.base.property = Missing trs:base property
validators.missing.trs.changed.property = Missing trs:changed property
validators.missing.trs.changelog.property = Missing trs:changeLog property
diff --git a/org.eclipse.lyo.testsuite.trs/src/main/resources/config.properties b/org.eclipse.lyo.testsuite.trs/src/main/resources/config.properties
index 270ab9f..38c6e3f 100644
--- a/org.eclipse.lyo.testsuite.trs/src/main/resources/config.properties
+++ b/org.eclipse.lyo.testsuite.trs/src/main/resources/config.properties
@@ -12,8 +12,21 @@ consumerKey = key
#OAuth consumer secret shared with the resource server
consumerSecret = secret
+#Authentication Type: {Header, OAuth, Basic}.
+#Note: In most cases this should be set to Header to allow the resource server
+#to indicate its supported authentication types in its WWW-Authenticate header.
+#In cases where the resource server is still under development OAuth, for 2-legged
+#Oauth, or Basic, for Basic authentication, may be specified directly.
+AuthType = Header
+
#Name of the OAuth Realm
OAuthRealm = Jazz
#OAuth Authentication URL
-OAuthURL = https://localhost:9443/ccm/oauth-authorize \ No newline at end of file
+OAuthURL = https://localhost:9443/ccm/oauth-authorize
+
+#Password for Basic Authentication, ensure no trailing spaces
+password = password
+
+#Username for Basic Authentication, ensure no trailing spaces
+username = username \ No newline at end of file