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

Reply via email to