Author: [email protected]
Date: Mon Jul 4 17:12:52 2011
New Revision: 1207
Log:
[AMDATUAUTH-60] Added missing files
Added:
trunk/amdatu-auth/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/MultiPartHttpClient4.java
trunk/amdatu-auth/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/OAuthAccessor.java
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthHttpRequest.java
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/internal/MultipartOAuthClient.java
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/util/OAuthResourceOwnerClient.java
Added:
trunk/amdatu-auth/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/MultiPartHttpClient4.java
==============================================================================
--- (empty file)
+++
trunk/amdatu-auth/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/MultiPartHttpClient4.java
Mon Jul 4 17:12:52 2011
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.amdatu.authentication.oauth.api;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+import net.oauth.client.ExcerptInputStream;
+import net.oauth.client.httpclient4.HttpClientPool;
+import net.oauth.client.httpclient4.HttpMethodResponse;
+import net.oauth.http.HttpMessage;
+import net.oauth.http.HttpResponseMessage;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.entity.mime.MultipartEntity;
+import org.apache.http.entity.mime.content.FileBody;
+import org.apache.http.entity.mime.content.StringBody;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
+import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
+
+/**
+ * This class implements a HTTP client based on Apache HttpComponents. The
net.oauth library provides
+ * a HTTP client 3 (based on Commons HttpClient) and HTTP client 4 (based on
Apache HttpComponents) but
+ * neither of those supports sending a multipart request. Sending multipart
request is required by
+ * certain OAuth service providers, like Twitter (for uploading profile
images).
+ * Hence this HTTP client provided an additional method to append multipart
files to a HTTP request.
+ * @author ivol
+ */
+public class MultiPartHttpClient4 implements net.oauth.http.HttpClient {
+ // Shared HTTP client pool
+ private static final HttpClientPool SHARED_CLIENT = new SingleClient();
+
+ // HTTP client pool to pull HTTP clients from
+ private final HttpClientPool m_clientPool;
+
+ /**
+ * Constructs a new multipart HTTP client.
+ */
+ public MultiPartHttpClient4() {
+ this(SHARED_CLIENT);
+ }
+
+ /**
+ * Constructs a new multipart HTTP client.
+ * @param clientPool The HTTP client pool to use
+ */
+ public MultiPartHttpClient4(HttpClientPool clientPool) {
+ m_clientPool = clientPool;
+ }
+
+ /**
+ * Execute a http request with the specified parameters.
+ */
+ public HttpResponseMessage execute(HttpMessage request, Map<String,
Object> httpParameters) throws IOException {
+ return execute(request, httpParameters, null, null);
+ }
+
+ /**
+ * Execute a http request with the specified parameters, stringparts and
fileparts.
+ */
+ public HttpResponseMessage execute(HttpMessage request, Map<String,
Object> parameters,
+ Map<String, String> stringparts, Map<String, File> fileparts) throws
IOException {
+ final String method = request.method;
+ final String url = request.url.toExternalForm();
+ final InputStream body = request.getBody();
+ final boolean isDelete = DELETE.equalsIgnoreCase(method);
+ final boolean isPost = POST.equalsIgnoreCase(method);
+ final boolean isPut = PUT.equalsIgnoreCase(method);
+ final MultipartEntity multipartEntity = toMultipartEntity(stringparts,
fileparts);
+ byte[] excerpt = null;
+ HttpRequestBase httpRequest;
+ if (isPost || isPut) {
+ HttpEntityEnclosingRequestBase entityEnclosingMethod = isPost ?
new HttpPost(url) : new HttpPut(url);
+ if (multipartEntity != null) {
+ entityEnclosingMethod.setEntity(multipartEntity);
+ }
+ else if (body != null) {
+ ExcerptInputStream e = new ExcerptInputStream(body);
+ excerpt = e.getExcerpt();
+ String length =
request.removeHeaders(HttpMessage.CONTENT_LENGTH);
+ entityEnclosingMethod
+ .setEntity(new InputStreamEntity(e, (length == null) ?
-1 : Long.parseLong(length)));
+ }
+ httpRequest = entityEnclosingMethod;
+ }
+ else if (isDelete) {
+ httpRequest = new HttpDelete(url);
+ }
+ else {
+ httpRequest = new HttpGet(url);
+ }
+ for (Map.Entry<String, String> header : request.headers) {
+ httpRequest.addHeader(header.getKey(), header.getValue());
+ }
+ HttpParams params = httpRequest.getParams();
+ for (Map.Entry<String, Object> p : parameters.entrySet()) {
+ String name = p.getKey();
+ String value = p.getValue().toString();
+ if (FOLLOW_REDIRECTS.equals(name)) {
+ params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS,
Boolean.parseBoolean(value));
+ }
+ else if (READ_TIMEOUT.equals(name)) {
+ params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
Integer.parseInt(value));
+ }
+ else if (CONNECT_TIMEOUT.equals(name)) {
+
params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
Integer.parseInt(value));
+ }
+ }
+
+ params.setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,
false);
+
+ HttpClient client = m_clientPool.getHttpClient(new
URL(httpRequest.getURI().toString()));
+ HttpResponse httpResponse = client.execute(httpRequest);
+ return new HttpMethodResponse(httpRequest, httpResponse, excerpt,
request.getContentCharset());
+ }
+
+ /**
+ * Converts the fileparts and stringparts to a multipart entity and
returns it
+ *
+ * @return
+ * @throws UnsupportedEncodingException
+ */
+ private MultipartEntity toMultipartEntity(Map<String, String> stringparts,
Map<String, File> fileparts)
+ throws UnsupportedEncodingException {
+ if (stringparts != null || fileparts != null) {
+ MultipartEntity multipartEntity = new MultipartEntity();
+ if (stringparts != null) {
+ for (String key : stringparts.keySet()) {
+ multipartEntity.addPart(key,
+ new StringBody(stringparts.get(key).toString(),
Charset.forName("UTF-8")));
+ }
+ }
+ if (fileparts != null) {
+ for (String key : fileparts.keySet()) {
+ multipartEntity.addPart(key, new FileBody((File)
fileparts.get(key)));
+ }
+ }
+ return multipartEntity;
+ }
+ else {
+ return null;
+ }
+ }
+
+ /**
+ * A pool that simply shares a single HttpClient. An HttpClient owns a pool
+ * of TCP connections. So, callers that share an HttpClient will share
+ * connections. Sharing improves performance (by avoiding the overhead of
+ * creating connections) and uses fewer resources in the client and its
+ * servers.
+ */
+ private static class SingleClient implements HttpClientPool {
+ SingleClient() {
+ HttpClient client = new DefaultHttpClient();
+ ClientConnectionManager mgr = client.getConnectionManager();
+ if (!(mgr instanceof ThreadSafeClientConnManager)) {
+ HttpParams params = client.getParams();
+ client =
+ new DefaultHttpClient(new
ThreadSafeClientConnManager(params, mgr.getSchemeRegistry()), params);
+ }
+ this.client = client;
+ }
+
+ private final HttpClient client;
+
+ public HttpClient getHttpClient(URL server) {
+ return client;
+ }
+ }
+}
Added:
trunk/amdatu-auth/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/OAuthAccessor.java
==============================================================================
--- (empty file)
+++
trunk/amdatu-auth/oauth-api/src/main/java/org/amdatu/authentication/oauth/api/OAuthAccessor.java
Mon Jul 4 17:12:52 2011
@@ -0,0 +1,57 @@
+package org.amdatu.authentication.oauth.api;
+
+import net.oauth.OAuth;
+import net.oauth.OAuthConsumer;
+
+/**
+ * The OAuthAccessor holds basically information about the user on which
behalf the service
+ * consumer is accessing resources hosted by the service provider. This
includes request and
+ * access tokens and secrets, but also 'generic' properties like the
oauth_verifier needed
+ * to prevent session fixation attacks.
+ *
+ * @author ivol
+ */
+public class OAuthAccessor extends net.oauth.OAuthAccessor {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 4678178106946442948L;
+
+ public OAuthAccessor(OAuthConsumer consumer) {
+ super(consumer);
+ }
+
+ public String getRequestToken() {
+ return requestToken;
+ }
+
+ public String getAccessToken() {
+ return accessToken;
+ }
+
+ public String getTokenSecret() {
+ return tokenSecret;
+ }
+
+ public void setRequestToken(String aRequestToken, String aTokenSecret) {
+ requestToken = aRequestToken;
+ tokenSecret = aTokenSecret;
+ }
+
+ public void setAccessToken(String aAccessToken, String aTokenSecret) {
+ accessToken = aAccessToken;
+ tokenSecret = aTokenSecret;
+ }
+
+ public String toString() {
+ String result = "";
+ result += OAuth.OAUTH_TOKEN + "=" + getProperty(OAuth.OAUTH_TOKEN) + "
";
+ result += OAuth.OAUTH_CONSUMER_KEY + "=" +
getProperty(OAuth.OAUTH_CONSUMER_KEY) + " ";
+ result += OAuth.OAUTH_SIGNATURE_METHOD + "=" +
getProperty(OAuth.OAUTH_SIGNATURE_METHOD) + " ";
+ result += OAuth.OAUTH_TIMESTAMP + "=" +
getProperty(OAuth.OAUTH_TIMESTAMP) + " ";
+ result += OAuth.OAUTH_NONCE + "=" + getProperty(OAuth.OAUTH_NONCE) + "
";
+ result += OAuth.OAUTH_VERSION + "=" + getProperty(OAuth.OAUTH_VERSION);
+ return result;
+ }
+}
Added:
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthHttpRequest.java
==============================================================================
--- (empty file)
+++
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/OAuthHttpRequest.java
Mon Jul 4 17:12:52 2011
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.amdatu.authentication.oauth.client;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.oauth.ParameterStyle;
+
+import org.amdatu.authentication.oauth.api.OAuthAccessor;
+
+/**
+ * This is a helper class for Http Requests that are signed with OAuth.
+ *
+ * @author ivol
+ */
+public class OAuthHttpRequest {
+ private OAuthAccessor m_accessor;
+ private String m_httpMethod;
+ private String m_url;
+ private Map<String, String> m_parameters;
+ private Map<String, String> m_headers;
+ private InputStream m_body;
+ private Map<String, String> m_stringParts;
+ private Map<String, File> m_fileParts;
+ private ParameterStyle m_parameterStyle;
+
+ public OAuthHttpRequest() {
+ }
+
+ /**
+ * Returns the accessor holding the access token and token secret.
+ *
+ * @return the accessor holding the access token and token secret.
+ */
+ public OAuthAccessor getAccessor() {
+ return m_accessor;
+ }
+
+ /**
+ * Sets the accessor holding the access token and token secret
+ *
+ * @param accessor
+ * the accessor to set
+ * @return this object
+ */
+ public OAuthHttpRequest setAccessor(OAuthAccessor accessor) {
+ m_accessor = accessor;
+ return this;
+ }
+
+ /**
+ * Returns the HTTP method to use in the HTTP request.
+ *
+ * @return the HTTP method to use in the HTTP request.
+ */
+ public String getHttpMethod() {
+ return m_httpMethod;
+ }
+
+ /**
+ * Sets the HTTP method to use in the HTTP request.
+ *
+ * @param httpMethod
+ * the HTTP method to use in the HTTP request
+ * @return this object
+ */
+ public OAuthHttpRequest setHttpMethod(String httpMethod) {
+ m_httpMethod = httpMethod;
+ return this;
+ }
+
+ /**
+ * The URL of the HTTP request.
+ *
+ * @return The URL of the HTTP request.
+ */
+ public String getUrl() {
+ return m_url;
+ }
+
+ /**
+ * Sets the URL of the HTTP request.
+ *
+ * @param url
+ * The URL of the HTTP request
+ * @return this object
+ */
+ public OAuthHttpRequest setUrl(String url) {
+ m_url = url;
+ return this;
+ }
+
+ /**
+ * Returns the parameters to send along with the request. See
setParameters.
+ *
+ * @return The parameters to send along with the request.
+ */
+ public Map<String, String> getParameters() {
+ return m_parameters;
+ }
+
+ /**
+ * Sets the parameters to send along with the request. Parameters may be
send as query arguments of the URL
+ * (QUERY_STRING), as request body with content type
application/x-www-form-urlencoded (BODY) or using
+ * a http request header named "Authorization" (AUTHORIZATION_HEADER). How
the parameters are attached
+ * to the HTTP request depends on the parameter style defined by the
service consumer. This can be
+ * QUERY_STRING, BODY or AUTHORIZATION_HEADER.
+ *
+ * QUERY_STRING - the parameters are combined with the OAuth parameters
and appended to the query string
+ * of the URL.
+ * BODY - the parameters are combined with the OAuth parameters and send
using the request body with
+ * content type application/x-www-form-urlencoded
+ * AUTHORIZATION_HEADER - OAuth parameters (which are all parameters
prefixed with oauth_, like
+ * oauth_token and oauth_nonce) are send using the Authorization header.
In case the HTTP request is a
+ * POST request and both the body and multiparts are empty, the remaining
parameters are send using the
+ * request body with content type application/x-www-form-urlencoded. In
all other cases the remaining
+ * parameters are appended to the query string of the URL.
+ *
+ * @param parameters
+ * The parameters to send along with the request.
+ * @return this object
+ */
+ public OAuthHttpRequest setParameters(Map<String, String> parameters) {
+ m_parameters = parameters;
+ return this;
+ }
+
+ public OAuthHttpRequest addParameter(String key, String value) {
+ if (m_parameters == null) {
+ m_parameters = new HashMap<String, String>();
+ }
+ m_parameters.put(key, value);
+ return this;
+ }
+
+ /**
+ * The HTTP headers to append to the HTTP request.
+ *
+ * @return The HTTP headers to append to the HTTP request
+ */
+ public Map<String, String> getHeaders() {
+ return m_headers;
+ }
+
+ /**
+ * Sets HTTP headers to append to the HTTP request.
+ *
+ * @param headers
+ * The HTTP headers to append to the HTTP request
+ * @return this object
+ */
+ public OAuthHttpRequest setHeaders(Map<String, String> headers) {
+ m_headers = headers;
+ return this;
+ }
+
+ public OAuthHttpRequest addHeader(String name, String value) {
+ if (m_headers == null) {
+ m_headers = new HashMap<String, String>();
+ }
+ m_headers.put(name, value);
+ return this;
+ }
+
+ /**
+ * The stream to send along with the HTTP request.
+ *
+ * @return The stream to send along with the HTTP request
+ */
+ public InputStream getBody() {
+ return m_body;
+ }
+
+ /**
+ * Sets the stream to send along with the HTTP request
+ *
+ * @param body
+ * The stream to send along with the HTTP request
+ * @return this object
+ */
+ public OAuthHttpRequest setBody(InputStream body) {
+ m_body = body;
+ return this;
+ }
+
+ /**
+ * Returns if this is a multi part request (that is, if it contains string
or file parts).
+ *
+ * @return if this is a multi part request
+ */
+ public boolean isMultipartRequest() {
+ return m_stringParts != null || m_fileParts != null;
+ }
+
+ /**
+ * Adds a String part to this request, making it a multipart request.
+ *
+ * @param name
+ * Name of the string part
+ * @param value
+ * Value of the string part
+ */
+ public void addStringPart(String name, String value) {
+ if (m_stringParts == null) {
+ m_stringParts = new HashMap<String, String>();
+ }
+ m_stringParts.put(name, value);
+ }
+
+ /**
+ * Adds a String part to this request, making it a multipart request.
+ *
+ * @param name
+ * Name of the file part
+ * @param value
+ * Value of the file part
+ */
+ public void addFilePart(String name, File file) {
+ if (m_fileParts == null) {
+ m_fileParts = new HashMap<String, File>();
+ }
+ m_fileParts.put(name, file);
+ }
+
+ /**
+ * Returns the fileparts send along with this request.
+ *
+ * @return the fileparts send along with this request.
+ */
+ public Map<String, File> getFileParts() {
+ return m_fileParts;
+ }
+
+ /**
+ * Returns the stringparts send along with this request.
+ *
+ * @return the stringparts send along with this request.
+ */
+ public Map<String, String> getStringParts() {
+ return m_stringParts;
+ }
+
+ /**
+ * Returns the parameter style to use for this particular request. By
default, the
+ * parameter style is determined by the
OAuthServiceConsumer.PARAMETER_STYLE property
+ * of the OAuth service consumer. When this value is not-null, it
overrules that property.
+ * Parameters may be send as query arguments of the URL
+ * (QUERY_STRING), as request body with content type
application/x-www-form-urlencoded (BODY) or using
+ * a http request header named "Authorization" (AUTHORIZATION_HEADER).
+ * @return the parameter style to apply.
+ */
+ public ParameterStyle getParameterStyle() {
+ return m_parameterStyle;
+ }
+
+ /**
+ * Overrules the parameter style defined by the OAuth service consumer for
this request.
+ * @param parameterStyle
+ */
+ public void setParameterStyle(ParameterStyle parameterStyle) {
+ m_parameterStyle = parameterStyle;
+ }
+}
Added:
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/internal/MultipartOAuthClient.java
==============================================================================
--- (empty file)
+++
trunk/amdatu-auth/oauth-client/src/main/java/org/amdatu/authentication/oauth/client/internal/MultipartOAuthClient.java
Mon Jul 4 17:12:52 2011
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.amdatu.authentication.oauth.client.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import net.oauth.OAuth;
+import net.oauth.OAuthException;
+import net.oauth.OAuthMessage;
+import net.oauth.OAuthProblemException;
+import net.oauth.ParameterStyle;
+import net.oauth.client.OAuthClient;
+import net.oauth.client.OAuthResponseMessage;
+import net.oauth.http.HttpMessage;
+import net.oauth.http.HttpMessageDecoder;
+import net.oauth.http.HttpResponseMessage;
+import net.oauth.signature.OAuthSignatureMethod;
+
+import org.amdatu.authentication.oauth.api.MultiPartHttpClient4;
+
+/**
+ * This class extends the regular OAuthClient and adds multipart support,
which is
+ * not supported by the net.oauth library but needed by some OAuth services,
like Twitter.
+ *
+ * @author ivol
+ */
+public class MultipartOAuthClient extends OAuthClient {
+ public MultipartOAuthClient(MultiPartHttpClient4 http) {
+ super(http);
+ }
+
+ public OAuthMessage invoke(OAuthMessage request, ParameterStyle style,
Map<String, String> stringParts, Map<String, File> fileParts)
+ throws IOException, OAuthException {
+ OAuthResponseMessage response = access(request, style, stringParts,
fileParts);
+ if ((response.getHttpResponse().getStatusCode() / 100) != 2) {
+ OAuthProblemException problem = response.toOAuthProblemException();
+ try {
+
problem.setParameter(OAuthProblemException.SIGNATURE_BASE_STRING,
+ OAuthSignatureMethod.getBaseString(request));
+ }
+ catch (Exception ignored) {}
+ throw problem;
+ }
+ return response;
+ }
+
+ /**
+ * Send a request and return the response. Don't try to decide whether the
+ * response indicates success; merely return it.
+ */
+ public OAuthResponseMessage access(OAuthMessage request, ParameterStyle
style, Map<String, String> stringParts, Map<String, File> fileParts)
+ throws IOException {
+ HttpMessage httpRequest = newRequest(request, style, stringParts,
fileParts);
+ HttpResponseMessage httpResponse =
+ ((MultiPartHttpClient4) getHttpClient()).execute(httpRequest,
httpParameters, stringParts, fileParts);
+ httpResponse = HttpMessageDecoder.decode(httpResponse);
+
+ try {
+ // We must use reflection here to instantiate the response
message, the OAuthResponseMessage class does
+ // not have a public constructor
+ Constructor<OAuthResponseMessage> con =
OAuthResponseMessage.class.getDeclaredConstructor(HttpResponseMessage.class);
+ con.setAccessible(true);
+ OAuthResponseMessage responseMessage =
con.newInstance(httpResponse);
+ con.setAccessible(false);
+ return responseMessage;
+ }
+ catch (Exception e) {}
+ return null;
+ }
+
+ private static HttpMessage newRequest(OAuthMessage from, ParameterStyle
style, Map<String, String> stringParts, Map<String, File> fileParts) throws
IOException {
+ final boolean isPost = OAuthMessage.POST.equalsIgnoreCase(from.method);
+ InputStream body = from.getBodyAsStream();
+ if (style == ParameterStyle.BODY && !(isPost && body == null)) {
+ style = ParameterStyle.QUERY_STRING;
+ }
+ String url = from.URL;
+ final List<Map.Entry<String, String>> headers = new
ArrayList<Map.Entry<String, String>>(from.getHeaders());
+ switch (style) {
+ case QUERY_STRING:
+ url = OAuth.addParameters(url, from.getParameters());
+ break;
+ case BODY: {
+ byte[] form =
OAuth.formEncode(from.getParameters()).getBytes(from.getBodyEncoding());
+ headers.add(new OAuth.Parameter(HttpMessage.CONTENT_TYPE,
OAuth.FORM_ENCODED));
+ headers.add(new OAuth.Parameter(HttpMessage.CONTENT_LENGTH,
form.length + ""));
+ body = new ByteArrayInputStream(form);
+ break;
+ }
+ case AUTHORIZATION_HEADER:
+ headers.add(new OAuth.Parameter("Authorization",
from.getAuthorizationHeader(null)));
+ // Find the non-OAuth parameters:
+ List<Map.Entry<String, String>> others = from.getParameters();
+ if (others != null && !others.isEmpty()) {
+ others = new ArrayList<Map.Entry<String, String>>(others);
+ for (Iterator<Map.Entry<String, String>> p =
others.iterator(); p.hasNext();) {
+ if (p.next().getKey().startsWith("oauth_")) {
+ p.remove();
+ }
+ }
+ // Place the non-OAuth parameters elsewhere in the request:
+ if (!others.isEmpty()) {
+ if (isPost && body == null && stringParts == null &&
fileParts == null) {
+ byte[] form =
OAuth.formEncode(others).getBytes(from.getBodyEncoding());
+ headers.add(new
OAuth.Parameter(HttpMessage.CONTENT_TYPE, OAuth.FORM_ENCODED));
+ headers.add(new
OAuth.Parameter(HttpMessage.CONTENT_LENGTH, form.length + ""));
+ body = new ByteArrayInputStream(form);
+ } else {
+ url = OAuth.addParameters(url, others);
+ }
+ }
+ }
+ break;
+ }
+ HttpMessage httpRequest = new HttpMessage(from.method, new URL(url),
body);
+ httpRequest.headers.addAll(headers);
+ return httpRequest;
+ }
+}
Added:
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/util/OAuthResourceOwnerClient.java
==============================================================================
--- (empty file)
+++
trunk/amdatu-auth/test-integration/tests/src/test/java/org/amdatu/auth/test/integration/tests/util/OAuthResourceOwnerClient.java
Mon Jul 4 17:12:52 2011
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.amdatu.auth.test.integration.tests.util;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.oauth.OAuthException;
+import net.oauth.OAuthMessage;
+
+import org.amdatu.authentication.oauth.api.OAuthAccessor;
+import org.amdatu.authentication.oauth.api.OAuthServiceConsumer;
+import org.amdatu.authentication.oauth.api.OAuthServiceProvider;
+import org.amdatu.authentication.oauth.client.OAuthHttpRequest;
+import org.amdatu.authentication.oauth.client.OAuthServiceConsumerClient;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.methods.PostMethod;
+
+/**
+ * This class provides a client API to be used by resource owners for invoking
a OAuth server.
+ * Note that the only actual task of a resource owner (in other words: user)
is authorizing
+ * the request token in a three-legged oAuth dance. Therefore this client API
only provides
+ * one method, which can be used to authorize a request token for a specific
user id.
+ *
+ * @author ivol
+ */
+public class OAuthResourceOwnerClient {
+ private OAuthServiceProvider m_oAuthServiceProvider;
+ private OAuthServiceConsumer m_oAuthServiceConsumer;
+
+ /**
+ * Create a new oAuth resource owner client for the specified service
consumer and service provider.
+ * Once created, using this API only tokens can be authorized for this
specified service consumer
+ * and service provider. If you need to authorize different tokens, you
will need to construct a
+ * new resource client.
+ *
+ * @param provider
+ * The oAuth service provider that provides the request token to be
authorized by
+ * this client
+ * @param consumer
+ * The oAuth service consumer for which tokens are authorized such
that the
+ * service consumer can retrieve an access token from the service
provider
+ */
+ public OAuthResourceOwnerClient(final OAuthServiceProvider provider, final
OAuthServiceConsumer consumer) {
+ m_oAuthServiceConsumer = consumer;
+ m_oAuthServiceProvider = provider;
+ }
+
+ /**
+ * Authorizes a request token for a user that is currently logged in. Note
that it is required that this
+ * method is invoked after the user has already logged in in Amdatu, using
the REST login service for example.
+ * This method only grants access to the specified service consumer on
behalf of the user currently logged in.
+ *
+ * @param accessor
+ * The OAuth accessor which contains the request token to be
authorized. The
+ * accessor is returned when the request token is received using
the service consumer client API.
+ * @param requestHeaders
+ * Map of request headers which should be send along with the
request. This may be necessary
+ * for example to pass a site authentication cookie (i.e.
JSESSIONID).
+ * @return The callback URL of the service consumer.
+ * @throws IOException
+ * In case a I/O exception occurred
+ * @throws URISyntaxException
+ * In case some URL could not be parsed
+ * @throws OAuthException
+ * If the received request token is invalid
+ * @return The callback URL, if the service consumer provided it
+ */
+ public String authorizeToken(final OAuthAccessor accessor, final
Map<String, String> requestHeaders)
+ throws IOException,
+ URISyntaxException,
+ OAuthException {
+ Map<String, String> paramProps = new HashMap<String, String>();
+ paramProps.put("oauth_token", accessor.requestToken);
+
+ OAuthServiceConsumerClient client =
+ new OAuthServiceConsumerClient(m_oAuthServiceProvider,
m_oAuthServiceConsumer);
+ OAuthHttpRequest httpRequest = new OAuthHttpRequest()
+ .setHttpMethod(OAuthMessage.GET)
+ .setUrl(m_oAuthServiceProvider.getAuthorizeTokenURL())
+ .setAccessor(accessor);
+ httpRequest.setParameters(paramProps);
+
+ OAuthMessage response = client.invoke(httpRequest);
+
+ // Now the result is an authorization page containing an HTML form we
are supposed to submit
+ // First read the token and callback from this form
+ String sResponseBody = response.readBodyAsString();
+ String tokenStart = "<input type=\"hidden\" name=\"oauth_token\"
value=\"";
+ String token =
sResponseBody.substring(sResponseBody.indexOf(tokenStart) +
tokenStart.length());
+ token = token.substring(0, token.indexOf("\""));
+
+ String callbackStart = "<input type=\"hidden\" name=\"oauth_callback\"
value=\"";
+ String callback =
sResponseBody.substring(sResponseBody.indexOf(callbackStart) +
callbackStart.length());
+ callback = callback.substring(0, callback.indexOf("\""));
+
+ // Now build the post request
+ HttpClient httpClient = new HttpClient();
+ NameValuePair[] data = {
+ new NameValuePair("oauth_token", token),
+ new NameValuePair("oauth_callback", callback)
+ };
+ PostMethod postMethod = null;
+ try {
+ postMethod = new
PostMethod(m_oAuthServiceProvider.getAuthorizeTokenURL());
+ postMethod.setRequestBody(data);
+ if (requestHeaders != null) {
+ for (String headerName : requestHeaders.keySet()) {
+ String headerValue = requestHeaders.get(headerName);
+ postMethod.setRequestHeader(headerName, headerValue);
+ }
+ }
+
+ int status = httpClient.executeMethod(postMethod);
+ if (status == HttpStatus.SC_OK) {
+ // Status 200 means authorize token went OK, but service
consumer did not specify a callback URL
+ return null;
+ }
+ else if (status == HttpStatus.SC_MOVED_TEMPORARILY) {
+ // Status 302 means that we are being redirected to the
callback URL provided by the service consumer
+ return postMethod.getResponseHeader("Location").getValue();
+ }
+ else {
+ throw new OAuthException("Authorize token form returned " +
status);
+ }
+ }
+ finally {
+ // Release the connection.
+ if (postMethod != null) {
+ postMethod.releaseConnection();
+ }
+ }
+ }
+}
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits