Advertisement
Guest User

Erem Boto

a guest
Apr 28th, 2010
403
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.88 KB | None | 0 0
  1.  
  2. import groovyx.net.http.HTTPBuilder;
  3.  
  4. import java.io.IOException;
  5. import java.net.URISyntaxException;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8.  
  9. import org.apache.http.client.ClientProtocolException;
  10. import org.scribe.http.Request;
  11. import org.scribe.http.Request.Verb;
  12. import org.scribe.oauth.Scribe;
  13. import org.scribe.oauth.Token;
  14.  
  15. /**
  16.  * Adds OAuth Consumer support to HttpBuilder using Pablo Fernandez's Scribe
  17.  * library (http://github.com/fernandezpablo85/scribe).
  18.  *
  19.  * Instantiate your own Scribe and pass it to the <code>create</code> factory
  20.  * method. Provide an <code>accessToken</code> parameter in the
  21.  * <code>args</code> map of each request or use <code>setAccessToken</code> to
  22.  * use the same one repeatedly.
  23.  *
  24.  * Example: <code>
  25.  * def serviceProps = new Properties([    "consumer.key" : "myApiToken",
  26.  *                                     "consumer.secret" : "myApiSecret" ])
  27.  *
  28.  * def scribe = new Scribe(serviceProps)
  29.  *
  30.  * //Use Scribe as described on its github to get the request and access
  31.  * //tokens. We'll pretend we just have one.
  32.  *
  33.  * def access = new Token("theAccessToken","andItsSecret")
  34.  *
  35.  * def http = OAuthHttpBuilder.create(
  36.  *               "http://www.twitter.com/oauth/some_resource",
  37.  *               scribe
  38.  *            );
  39.  *
  40.  * http.get(      query : [ arg1 : "value1", arg2 : "value2" ],
  41.  *           accessToken: access );
  42.  * </code>
  43.  *
  44.  * @author Erem Boto
  45.  */
  46. @SuppressWarnings("unchecked")
  47. public class OAuthHttpBuilder {
  48.   private final Scribe signer;
  49.   private final HTTPBuilder delegate;
  50.   private Token defaultAccessToken = null;
  51.  
  52.  
  53.   /*
  54.    * Class provision
  55.    */
  56.   public static OAuthHttpBuilder create( Object defaultUri,
  57.                                          Object defaultContentType,
  58.                                          Scribe signer ) throws URISyntaxException {
  59.     return new OAuthHttpBuilder(
  60.         new HTTPBuilder(defaultUri, defaultContentType), signer);
  61.   }
  62.  
  63.   public static OAuthHttpBuilder create( Object defaultUri,
  64.                                          Scribe signer )
  65.   throws URISyntaxException {
  66.     return new OAuthHttpBuilder(new HTTPBuilder(defaultUri), signer);
  67.   }
  68.  
  69.   public OAuthHttpBuilder(HTTPBuilder delegate, Scribe signer) {
  70.     this.signer = signer;
  71.     this.delegate = delegate;
  72.   }
  73.  
  74.   /*
  75.    * Public Methods
  76.    */
  77.   /**
  78.    * Sets the default access token to use when making OAuth requests.
  79.    *
  80.    * @param token
  81.    */
  82.   public void setAccessToken(Token token) {
  83.     this.defaultAccessToken = token;
  84.   }
  85.  
  86.   /*
  87.    * Wrapped HttpBuilder Methods
  88.    */
  89.   public Object get(Map<String, ?> args)
  90.   throws ClientProtocolException, IOException, URISyntaxException {
  91.     preProcessArgsHeader(Verb.GET, args);
  92.     return delegate.get(args);
  93.   }
  94.  
  95.   public Object post(Map<String, ?> args)
  96.   throws ClientProtocolException, URISyntaxException, IOException {
  97.     preProcessArgsHeader(Verb.POST, args);
  98.     return delegate.post(args);
  99.   }
  100.  
  101.  
  102.   /*
  103.    * Private Methods
  104.    */
  105.   /**
  106.    * Uses provided "accessToken" and "uri" parameters to construct an
  107.    * Authorization header with Scribe.
  108.    *
  109.    * @param method
  110.    *          the request's HTTP method
  111.    * @param args
  112.    *          the argument map as passed to get() or post()
  113.    */
  114.   public void preProcessArgsHeader(Verb method, Map<String, ?> args) {
  115.     Token accessToken = accessTokenFromArgs(args);
  116.     String uriParam = uriParamFromArgs(args);
  117.  
  118.     // God knows what happens if they aren't strings.
  119.     Map<String, String> query = (Map<String, String>) args.get("query");
  120.  
  121.     Object bodyParams = args.get("body");
  122.  
  123.     // because we're using one map, the request won't be to spec if you have
  124.     // repeated query parameters =(
  125.     Map oauthParams = new HashMap();
  126.     if (query != null) {
  127.       oauthParams.putAll(query);
  128.     }
  129.  
  130.     boolean shouldPutBody = (method == Verb.POST && bodyParams instanceof Map);
  131.     if (shouldPutBody) {
  132.       oauthParams.putAll((Map<String, String>) bodyParams);
  133.     }
  134.  
  135.     String authHeader = makeAuthHeader( method,
  136.                                         uriParam,
  137.                                         accessToken,
  138.                                         oauthParams );
  139.     addAuthorizationHeader(authHeader, args);
  140.   }
  141.  
  142.   /**
  143.    * Grabs the Scribe access token from the provided arguments, or returns the
  144.    * default token.
  145.    *
  146.    * @param args
  147.    *          the arguments passed to either get or post.
  148.    * @return the accessToken that was provided
  149.    * @throws IllegalStateException
  150.    *           when the accessToken parameter is not provided and no default
  151.    *           accessToken was available.
  152.    */
  153.   private Token accessTokenFromArgs(Map args) throws IllegalStateException {
  154.     Token accessToken = (Token) args.get("accessToken");
  155.     if (accessToken == null) {
  156.       accessToken = defaultAccessToken;
  157.     }
  158.     if (accessToken == null) {
  159.       accessToken = new Token("", "");
  160.     }
  161.     return accessToken;
  162.   }
  163.  
  164.   /**
  165.    * Grabs the uri from the provided argument map, or returns the default URI.
  166.    *
  167.    * @param args
  168.    *          the arguments passed to either get or post
  169.    * @return the provided uri
  170.    * @throws IllegalStateException
  171.    *           when the 'uri' parameters is not provided and no default uri was
  172.    *           available.
  173.    */
  174.   private String uriParamFromArgs(Map args) throws IllegalStateException {
  175.     String uriParam = (String) args.get("uri");
  176.    
  177.     if (uriParam == null) {
  178.       uriParam = delegate.getUri().toString();
  179.     }
  180.     if (uriParam == null) {
  181.       throw new IllegalStateException(
  182.           "Default URI is null and no 'uri' parameter was provided"
  183.       );
  184.     }
  185.     return uriParam;
  186.   }
  187.  
  188.   /**
  189.    * Adds the OAuth Authorization header to the wrapped HTTPBuilder.
  190.    *
  191.    * @param authHeader
  192.    *          the authorization header value
  193.    * @param args
  194.    *          the map of arguments passed to post/get
  195.    */
  196.   private void addAuthorizationHeader(String authHeader, Map args) {
  197.     Map headers = (Map) args.get("headers");
  198.     if (headers == null) {
  199.       headers = new HashMap<String, String>();
  200.       args.put("headers", headers);
  201.     }
  202.     headers.put("Authorization", authHeader);
  203.   }
  204.  
  205.   /**
  206.    * Constructs the authorization header from OAuth parameters.
  207.    *
  208.    * @param method
  209.    *          the request's HTTP method
  210.    * @param uri
  211.    *          the request's URI
  212.    * @param accessToken
  213.    *          the token for signing: can be access token or request token.
  214.    * @param queryOrBodyParams
  215.    *          the DECODED parameters for oauth to sign. With GET these are the
  216.    *          query parameters. With POST both query parameters and body
  217.    *          parameters (if this is a form-encoded request).
  218.    * @return the signed OAuth "Authorization" header.
  219.    */
  220.   private String makeAuthHeader( Verb method,
  221.                                  String uri,
  222.                                  Token
  223.                                  accessToken,
  224.                                  Map<String, ?> queryOrBodyParams ) {
  225.     CustomRequest req = new CustomRequest(method, uri);
  226.     for (Map.Entry param : queryOrBodyParams.entrySet()) {
  227.       req.addBodyParameter( (String) param.getKey(),
  228.                             param.getValue().toString() );
  229.     }
  230.     signer.signRequest(req, accessToken);
  231.     return req.authorization;
  232.   }
  233.  
  234.   /**
  235.    * Custom Scribe Request subclass gives us access to the Authorization header
  236.    * when Scribe sets it.
  237.    */
  238.   protected static class CustomRequest extends Request {
  239.     public CustomRequest(Verb verb, String url) {
  240.       super(verb, url);
  241.     }
  242.  
  243.     public String authorization = null;
  244.  
  245.     @Override
  246.     public void addHeader(String key, String value) {
  247.       if ("Authorization".equals(key)) {
  248.         authorization = value;
  249.       }
  250.       super.addHeader(key, value);
  251.     }
  252.   }
  253. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement