1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.components.devtools_bridge.apiary;
7 import android.util.JsonReader;
9 import org.apache.http.client.HttpClient;
10 import org.apache.http.client.methods.HttpPost;
11 import org.apache.http.entity.StringEntity;
13 import java.io.IOException;
14 import java.io.UnsupportedEncodingException;
15 import java.net.URLEncoder;
18 * Google authentication client. Fetches a pair of refresh/access tokens for a
19 * secret received while registering the instance in GCD.
21 public class OAuthClient {
22 public static final String API_BASE = "https://accounts.google.com/o/oauth2";
23 public static final String ENCODING = "UTF-8";
24 public static final String CONTENT_TYPE = "application/x-www-form-urlencoded";
26 private final HttpClient mHttpClient;
27 private final String mScope;
28 private final String mClientId;
29 private final String mClientSecret;
31 OAuthClient(HttpClient httpClient, String scope, String clientId, String clientSecret) {
32 assert httpClient != null;
34 assert clientId != null;
35 assert clientSecret != null;
37 mHttpClient = httpClient;
40 mClientSecret = clientSecret;
43 public OAuthResult authenticate(String secret) throws IOException {
44 final long startTimeMs = System.currentTimeMillis();
47 "client_id=" + urlEncode(mClientId)
48 + "&client_secret=" + urlEncode(mClientSecret)
49 + "&scope=" + urlEncode(mScope)
50 + "&code=" + urlEncode(secret)
52 + "&grant_type=authorization_code";
54 return mHttpClient.execute(
55 newHttpPost("/token", content),
56 new JsonResponseHandler<OAuthResult>() {
58 public OAuthResult readResponse(JsonReader reader) throws IOException {
59 return readResponse(reader, startTimeMs);
64 private HttpPost newHttpPost(String path, String content) throws UnsupportedEncodingException {
65 HttpPost request = new HttpPost(API_BASE + "/token");
66 request.setEntity(new StringEntity(content, ENCODING));
67 request.addHeader("Content-Type", CONTENT_TYPE);
71 private static String urlEncode(String value) {
73 return URLEncoder.encode(value, ENCODING);
74 } catch (UnsupportedEncodingException e) {
75 throw new RuntimeException(e);
79 static OAuthResult readResponse(JsonReader reader, long startTimeMs) throws IOException {
80 String refreshToken = null;
81 String accessToken = null;
82 long expiresInS = 0; // In seconds.
85 while (reader.hasNext()) {
86 String name = reader.nextName();
87 if (name.equals("refresh_token")) {
88 refreshToken = reader.nextString();
89 } else if (name.equals("access_token")) {
90 accessToken = reader.nextString();
91 } else if (name.equals("expires_in")) {
92 expiresInS = reader.nextLong();
99 return OAuthResult.create(
100 refreshToken, accessToken, startTimeMs + expiresInS * 1000);