Package com.google.api.adwords.lib

Source Code of com.google.api.adwords.lib.AuthToken

// Copyright 2010, Google Inc. All Rights Reserved.
//
// 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 com.google.api.adwords.lib;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

/**
* The AuthToken class creates an authentication token using
* the <a href="http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html">
* ClientLogin API</a>.
*
* @author api.arogal@gmail.com (Adam Rogal)
*/
public class AuthToken {
  public static final String CLIENT_LOGIN_SERVER = "https://www.google.com/accounts/";

  private static final String CLIENT_LOGIN_URL = CLIENT_LOGIN_SERVER + "ClientLogin";
  private static final int HTTP_CLIENT_SOCKET_TIMEOUT_IN_MS = (int) TimeUnit.SECONDS.toMillis(20);
  private static final String AUTH_TOKEN_KEY = "Auth";
  private static final String ERROR_KEY = "Error";
  private static final String INFO_KEY = "Info";
  private static final String URL_KEY = "Url";
  private static final String CAPTCHA_TOKEN_KEY = "CaptchaToken";
  private static final String CAPTCHA_URL_KEY = "CaptchaUrl";
  private static final String CAPTCHA_REQUIRED_ERROR = "CaptchaRequired";

  private final String email;
  private final String password;
  private final String captchaToken;
  private final String captchaAnswer;

  /**
   * Constructor for email and password request.
   *
   * @param email the user's login email address
   * @param password the user's password
   */
  public AuthToken(String email, String password) {
    this(email, password, null, null);
  }

  /**
   * Constructor which provides fields for CAPTCHA information.
   *
   * @param email the user's login email address
   * @param password the user's password
   * @param captchaToken the CAPTCHA token
   * @param captchaAnswer the CAPTCHA answer
   */
  public AuthToken(String email, String password, String captchaToken, String captchaAnswer) {
    this.email = email;
    this.password = password;
    this.captchaToken = captchaToken;
    this.captchaAnswer = captchaAnswer;
  }

  /**
   * Constructor used for generating a new {@code AuthToken} from an old one
   * along with CAPTCHA information.
   *
   * @param authToken the {@code AuthToken} object to get the email and password
   *     from
   * @param captchaToken the CAPTCHA token
   * @param captchaAnswer the CAPTCHA answer
   */
  public AuthToken(AuthToken authToken, String captchaToken, String captchaAnswer) {
    this.email = authToken.email;
    this.password = authToken.password;
    this.captchaToken = captchaToken;
    this.captchaAnswer = captchaAnswer;
  }

  /**
   * Retrieves an authentication token using the user's credentials.
   *
   * @return a {@code String} authentication token.
   * @throws AuthTokenException if the status from the Client Login server is
   *     anything but {@code HttpStatus.SC_OK = 200}
   */
  public String getAuthToken() throws AuthTokenException {
    try {
      PostMethod postMethod = new PostMethod(CLIENT_LOGIN_URL);

      int statusCode = postToClientLogin(postMethod);
      Properties responseProperties =
          generatePropertiesFromResponse(postMethod.getResponseBodyAsStream());

      if (statusCode == HttpStatus.SC_OK) {
        if (responseProperties.containsKey(AUTH_TOKEN_KEY)) {
          return responseProperties.getProperty(AUTH_TOKEN_KEY).toString();
        } else {
          throw new IllegalStateException("Unable to get auth token from Client Login server");
        }
      } else {
        CaptchaInformation captchaInfo = null;
        String errorCode = null;

        if (responseProperties.containsKey(ERROR_KEY)) {
          errorCode = responseProperties.getProperty(ERROR_KEY);
          if (errorCode != null && errorCode.equals(CAPTCHA_REQUIRED_ERROR)) {
            captchaInfo = extractCaptchaInfoFromProperties(responseProperties);
          }

          if (responseProperties.containsKey(INFO_KEY)) {
            errorCode += ": " + responseProperties.getProperty(INFO_KEY);
          }
        }

        throw new AuthTokenException(statusCode, postMethod.getResponseBodyAsString(), errorCode,
            captchaInfo, null);
      }
    } catch (IOException e) {
      throw new AuthTokenException(null, null, null, null, e);
    }
  }

  /**
   * Makes the POST to the client login API.
   *
   * @param postMethod the {@code PostMethod} which encapsulates the URL to
   *     post against
   * @return an HTTP status code as defined by {@code HttpStatus}
   * @throws IOException if the HTTP client could not establish a
   *     connection
   */
  private int postToClientLogin(PostMethod postMethod) throws IOException {
    HttpClient httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());

    setProxy(httpClient);

    HttpConnectionManagerParams connectionManagerParams =
        httpClient.getHttpConnectionManager().getParams();

    connectionManagerParams.setTcpNoDelay(true);
    connectionManagerParams.setSoTimeout(HTTP_CLIENT_SOCKET_TIMEOUT_IN_MS);
    postMethod.addParameter("Email", email);
    postMethod.addParameter("Passwd", password);
    postMethod.addParameter("accountType", "GOOGLE");
    postMethod.addParameter("service", "adwords");
    postMethod.addParameter("source", "google-awapi-java");

    if (captchaToken != null) {
      postMethod.addParameter("logintoken", captchaToken);
    }

    if (captchaAnswer != null) {
      postMethod.addParameter("logincaptcha", captchaAnswer);
    }

    return httpClient.executeMethod(postMethod);
  }

  /**
   * Sets the proxy for the HTTP client.
   *
   * @param httpClient the HTTP client to set the proxy for
   */
  private void setProxy(HttpClient httpClient) {
    if (System.getProperty("http.proxyHost") != null
        && System.getProperty("http.proxyPort") != null) {
      httpClient.getHostConfiguration().setProxy(System.getProperty("http.proxyHost"),
          Integer.parseInt(System.getProperty("http.proxyPort")));

      if (System.getProperty("http.proxyUser") != null
          && System.getProperty("http.proxyPassword") != null) {
        HttpState state = new HttpState();
        state.setProxyCredentials(new AuthScope(System.getProperty("http.proxyHost"),
            Integer.parseInt(System.getProperty("http.proxyPort"))),
                new UsernamePasswordCredentials(System.getProperty("http.proxyUser"),
                    System.getProperty("http.proxyPassword")));
        httpClient.setState(state);
      }
    }
  }

  /**
   * Extracts the CAPTCHA information from a response.
   *
   * @param authProperties the response from the client login API
   * @return the CAPTCHA information
   */
  private CaptchaInformation extractCaptchaInfoFromProperties(Properties authProperties) {
    String captchaUrl = CLIENT_LOGIN_SERVER + authProperties.getProperty(CAPTCHA_URL_KEY);
    String captchaToken = authProperties.getProperty(CAPTCHA_TOKEN_KEY);
    String url = authProperties.getProperty(URL_KEY);

    return new CaptchaInformation(captchaUrl, captchaToken, url);
  }

  /**
   * Generates a {@code Properties} from a client login API response
   *
   * @param responseBodyStream the response body as a stream
   * @return a {@code Properties} generated from the response body
   * @throws IOException if response body stream could not be read
   */
  private Properties generatePropertiesFromResponse(InputStream responseBodyStream)
      throws IOException {
    Properties properties = new Properties();
    properties.load(responseBodyStream);
    return properties;
  }
}
TOP

Related Classes of com.google.api.adwords.lib.AuthToken

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.