Package com.k42b3.neodym.oauth

Source Code of com.k42b3.neodym.oauth.Oauth

/**
* $Id: Oauth.java 207 2011-12-18 21:09:32Z k42b3.x@gmail.com $
*
* neodym
* A java library to access the REST API of amun
*
* Copyright (c) 2011 Christoph Kappestein <k42b3.x@gmail.com>
*
* This file is part of neodym. neodym is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or at any later version.
*
* neodym is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with neodym. If not, see <http://www.gnu.org/licenses/>.
*/

package com.k42b3.neodym.oauth;

import java.awt.Desktop;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.logging.Logger;

import javax.swing.JOptionPane;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

import com.k42b3.neodym.Http;
import com.k42b3.neodym.TrafficItem;
import com.k42b3.neodym.TrafficListenerInterface;

/**
* Oauth
*
* @author     Christoph Kappestein <k42b3.x@gmail.com>
* @license    http://www.gnu.org/licenses/gpl.html GPLv3
* @link       http://code.google.com/p/delta-quadrant
* @version    $Revision: 207 $
*/
public class Oauth
{
  private Http http;
  private OauthProvider provider;

  private String token;
  private String tokenSecret;
  private boolean callbackConfirmed;
  private String verificationCode;

  private boolean authed = false;
  private TrafficListenerInterface trafficListener;

  private Logger logger = Logger.getLogger("com.k42b3.neodym");

  public Oauth(Http http, OauthProvider provider)
  {
    this.http = http;
    this.provider = provider;

    if((provider.getToken() != null && !provider.getToken().isEmpty()) && (provider.getTokenSecret() != null && !provider.getTokenSecret().isEmpty()))
    {
      this.auth(provider.getToken(), provider.getTokenSecret());
    }
  }

  public void auth(String token, String tokenSecret)
  {
    this.setToken(token);
    this.setTokenSecret(tokenSecret);

    this.authed = true;
  }

  public void setToken(String token)
  {
    this.token = token;
  }
 
  public void setTokenSecret(String tokenSecret)
  {
    this.tokenSecret = tokenSecret;
  }

  public String getToken()
  {
    return token;
  }

  public String getTokenSecret()
  {
    return tokenSecret;
  }

  public boolean isAuthed()
  {
    return authed;
  }

  public boolean requestToken() throws Exception
  {
    // add values
    HashMap<String, String> values = new HashMap<String, String>();

    String requestMethod = "GET";

    values.put("oauth_consumer_key", this.provider.getConsumerKey());
    values.put("oauth_signature_method", provider.getMethod());
    values.put("oauth_timestamp", this.getTimestamp());
    values.put("oauth_nonce", this.getNonce());
    values.put("oauth_version", this.getVersion());
    values.put("oauth_callback", "oob");


    // add get vars to values
    URL requestUrl = new URL(provider.getRequestUrl());
    values.putAll(parseQuery(requestUrl.getQuery()));


    // build base string
    String baseString = this.buildBaseString(requestMethod, provider.getRequestUrl(), values);


    // get signature
    SignatureInterface signature = this.getSignature();

    if(signature == null)
    {
      throw new Exception("Invalid signature method");
    }


    // build signature
    values.put("oauth_signature", signature.build(baseString, provider.getConsumerSecret(), ""));


    // add header to request
    HashMap<String, String> header = new HashMap<String, String>();
    header.put("Authorization", "OAuth realm=\"neodym\", " + this.buildAuthString(values));

    String responseContent = http.request(Http.GET, provider.getRequestUrl(), header);


    // parse response
    this.token = null;
    this.tokenSecret = null;
    this.callbackConfirmed = false;

    HashMap<String, String> response = parseQuery(responseContent);
    Set<String> keys = response.keySet();

    for(String key : keys)
    {
      if(key.equals("oauth_token"))
      {
        this.token = response.get(key);

        logger.info("Received token: " + this.token);
      }

      if(key.equals("oauth_token_secret"))
      {
        this.tokenSecret = response.get(key);

        logger.info("Received token secret: " + this.tokenSecret);
      }

      if(key.equals("oauth_callback_confirmed"))
      {
        this.tokenSecret = response.get(key);

        this.callbackConfirmed = response.get(key).equals("1");
      }
    }

    if(this.token == null)
    {
      throw new Exception("No oauth token received");
    }

    if(this.tokenSecret == null)
    {
      throw new Exception("No oauth token secret received");
    }

    if(this.callbackConfirmed != true)
    {
      throw new Exception("Callback was not confirmed");
    }

    return true;
  }

  public boolean authorizeToken() throws Exception
  {
    String url;

    if(this.provider.getAuthorizationUrl().indexOf('?') == -1)
    {
      url = this.provider.getAuthorizationUrl() + "?oauth_token=" + this.token;
    }
    else
    {
      url = this.provider.getAuthorizationUrl() + "&oauth_token=" + this.token;
    }

    URI authUrl = new URI(url);

    if(Desktop.isDesktopSupported())
    {
      Desktop desktop = Desktop.getDesktop();

      if(desktop.isSupported(Desktop.Action.BROWSE))
      {
        desktop.browse(authUrl);
      }
      else
      {
        JOptionPane.showMessageDialog(null, "Visit the following URL: " + authUrl);
      }
    }
    else
    {
      JOptionPane.showMessageDialog(null, "Visit the following URL: " + authUrl);
    }

    verificationCode = JOptionPane.showInputDialog("Please enter the verification Code");

    return true;
  }

  public boolean accessToken() throws Exception
  {
    // add values
    HashMap<String, String> values = new HashMap<String, String>();

    String requestMethod = "GET";

    values.put("oauth_consumer_key", this.provider.getConsumerKey());
    values.put("oauth_token", this.token);
    values.put("oauth_signature_method", provider.getMethod());
    values.put("oauth_timestamp", this.getTimestamp());
    values.put("oauth_nonce", this.getNonce());
    values.put("oauth_verifier", this.verificationCode);


    // add get vars to values
    URL accessUrl = new URL(provider.getAccessUrl());
    values.putAll(parseQuery(accessUrl.getQuery()));


    // build base string
    String baseString = this.buildBaseString(requestMethod, provider.getAccessUrl(), values);


    // get signature
    SignatureInterface signature = this.getSignature();

    if(signature == null)
    {
      throw new Exception("Invalid signature method");
    }


    // build signature
    values.put("oauth_signature", signature.build(baseString, provider.getConsumerSecret(), this.tokenSecret));


    // add header to request
    HashMap<String, String> header = new HashMap<String, String>();
    header.put("Authorization", "OAuth realm=\"neodym\", " + this.buildAuthString(values));

    String responseContent = http.request(Http.GET, provider.getAccessUrl(), header);


    // parse response
    this.token = null;
    this.tokenSecret = null;

    HashMap<String, String> response = parseQuery(responseContent);
    Set<String> keys = response.keySet();

    for(String key : keys)
    {
      if(key.equals("oauth_token"))
      {
        this.token = response.get(key);

        logger.info("Received token: " + this.token);
      }

      if(key.equals("oauth_token_secret"))
      {
        this.tokenSecret = response.get(key);

        logger.info("Received token secret: " + this.tokenSecret);
      }
    }

    if(this.token == null)
    {
      throw new Exception("No oauth token received");
    }

    if(this.tokenSecret == null)
    {
      throw new Exception("No oauth token secret received");
    }

    return true;
  }

  @SuppressWarnings("unchecked")
  public void signRequest(HttpRequestBase request) throws Exception
  {
    // add values
    HashMap<String, String> values = new HashMap<String, String>();
    HashMap<String, String> auth;

    values.put("oauth_consumer_key", this.provider.getConsumerKey());
    values.put("oauth_token", this.token);
    values.put("oauth_signature_method", provider.getMethod());
    values.put("oauth_timestamp", this.getTimestamp());
    values.put("oauth_nonce", this.getNonce());


    auth = (HashMap<String, String>) values.clone();


    // add get vars to values
    values.putAll(parseQuery(request.getURI().getQuery()));


    // build base string
    String baseString = this.buildBaseString(request.getMethod(), request.getURI().toString(), values);


    // get signature
    SignatureInterface signature = this.getSignature();

    if(signature == null)
    {
      throw new Exception("Invalid signature method");
    }


    // build signature
    auth.put("oauth_signature", signature.build(baseString, provider.getConsumerSecret(), this.tokenSecret));


    // add header to request
    request.addHeader("Authorization", "OAuth realm=\"neodym\", " + this.buildAuthString(auth));
  }

  private String buildAuthString(HashMap<String, String> values)
  {
    StringBuilder authString = new StringBuilder();

    Iterator<Entry<String, String>> it = values.entrySet().iterator();

    while(it.hasNext())
    {
      Entry<String, String> e = it.next();

      authString.append(urlEncode(e.getKey()) + "=\"" + urlEncode(e.getValue()) + "\", ");
    }

    String str = authString.toString();


    // remove ", " from string
    str = str.substring(0, str.length() - 2);


    return str;
  }

  private String buildBaseString(String requestMethod, String url, HashMap<String, String> params) throws Exception
  {
    StringBuilder base = new StringBuilder();

    base.append(urlEncode(this.getNormalizedMethod(requestMethod)));

    base.append('&');
   
    base.append(urlEncode(this.getNormalizedUrl(url)));

    base.append('&');
   
    base.append(urlEncode(this.getNormalizedParameters(params)));

    logger.fine("BaseString: " + base.toString());

    return base.toString();
  }

  private String getNormalizedParameters(HashMap<String, String> params)
  {
    Iterator<Entry<String, String>> it = params.entrySet().iterator();

    List<String> keys = new ArrayList<String>();

    while(it.hasNext())
    {
      Entry<String, String> e = it.next();

      keys.add(e.getKey());
    }


    // sort params
    Collections.sort(keys);


    // build normalized params
    StringBuilder normalizedParams = new StringBuilder();

    for(int i = 0; i < keys.size(); i++)
    {
      normalizedParams.append(urlEncode(keys.get(i)) + "=" + urlEncode(params.get(keys.get(i))) + "&");
    }

    String str = normalizedParams.toString();


    // remove trailing &
    str = str.substring(0, str.length() - 1);


    return str;
  }

  private String getNormalizedUrl(String rawUrl) throws Exception
  {
    rawUrl = rawUrl.toLowerCase();

    URL url = new URL(rawUrl);

    int port = url.getPort();

    if(port == -1 || port == 80 || port == 443)
    {
      return url.getProtocol() + "://" + url.getHost() + url.getPath();
    }
    else
    {
      return url.getProtocol() + "://" + url.getHost() + ":" + port + url.getPath();
    }
  }

  private String getNormalizedMethod(String method)
  {
    return method.toUpperCase();
  }

  private String getTimestamp()
  {
    return "" + (System.currentTimeMillis() / 1000);
  }

  private String getNonce()
  {
    try
    {
      byte[] nonce = new byte[32];

      Random rand;

      rand = SecureRandom.getInstance("SHA1PRNG");

      rand.nextBytes(nonce);


      return DigestUtils.md5Hex(rand.toString());
    }
    catch(Exception e)
    {
      return DigestUtils.md5Hex("" + System.currentTimeMillis());
    }
  }

  private String getVersion()
  {
    return "1.0";
  }

  @SuppressWarnings("unused")
  private HttpEntity httpRequest(String method, String url, Map<String, String> header, String body) throws Exception
  {
    // build request
    HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, 6000);
    DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);


    HttpRequestBase request;

    if(method.equals("GET"))
    {
      request = new HttpGet(url);
    }
    else if(method.equals("POST"))
    {
      MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
      entity.addPart("text", new StringBody(body));

      request = new HttpPost(url);

      ((HttpPost) request).setEntity(entity);
    }
    else
    {
      throw new Exception("Invalid request method");
    }


    // header
    Set<String> keys = header.keySet();

    for(String key : keys)
    {
      request.setHeader(key, header.get(key));
    }


        // execute HTTP Get Request
    logger.info("Request: " + request.getRequestLine());

    HttpResponse httpResponse = httpClient.execute(request);

    HttpEntity entity = httpResponse.getEntity();

    String responseContent = EntityUtils.toString(entity);
   

    // log traffic
    if(trafficListener != null)
    {
      TrafficItem trafficItem = new TrafficItem();

      trafficItem.setRequest(request);
      trafficItem.setResponse(httpResponse);
      trafficItem.setResponseContent(responseContent);

      trafficListener.handleRequest(trafficItem);
    }


    // check status code
    int statusCode = httpResponse.getStatusLine().getStatusCode();

    if(!(statusCode >= 200 && statusCode < 300))
    {
      JOptionPane.showMessageDialog(null, responseContent);

      throw new Exception("No successful status code");
    }


    return entity;
  }

  private SignatureInterface getSignature() throws Exception
  {
    String cls;

    if(provider.getMethod().equals("HMAC-SHA1"))
    {
      cls = "com.k42b3.neodym.oauth.HMACSHA1";
    }
    else if(provider.getMethod().equals("PLAINTEXT"))
    {
      cls = "com.k42b3.neodym.oauth.PLAINTEXT";
    }
    else
    {
      throw new Exception("Invalid signature method");
    }

    return (SignatureInterface) Class.forName(cls).newInstance();
  }

  public static String urlEncode(String content)
  {
    try
    {
      if(!content.isEmpty())
      {
        String encoded = URLEncoder.encode(content, "UTF8");

        encoded = encoded.replaceAll("%7E", "~");

        return encoded;
      }
      else
      {
        return "";
      }
    }
    catch(Exception e)
    {
      return "";
    }
  }

  public static HashMap<String, String> parseQuery(String query) throws Exception
  {
    HashMap<String, String> map = new HashMap<String, String>();

    if(query != null)
    {
      String[] params = query.split("&");

      for(int i = 0; i < params.length; i++)
      {
        String[] pair = params[i].split("=");

        if(pair.length >= 1)
        {
          String name  = URLDecoder.decode(pair[0], "UTF-8");
          String value = pair.length == 2 ? URLDecoder.decode(pair[1], "UTF-8") : "";

          map.put(name, value);
        }
      }
    }

    return map;
  }
}
TOP

Related Classes of com.k42b3.neodym.oauth.Oauth

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.