Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / components / devtools_bridge / android / java / src / org / chromium / components / devtools_bridge / apiary / OAuthClient.java
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.
4
5 package org.chromium.components.devtools_bridge.apiary;
6
7 import android.util.JsonReader;
8
9 import org.apache.http.client.HttpClient;
10 import org.apache.http.client.methods.HttpPost;
11 import org.apache.http.entity.StringEntity;
12
13 import java.io.IOException;
14 import java.io.UnsupportedEncodingException;
15 import java.net.URLEncoder;
16
17 /**
18  * Google authentication client. Fetches a pair of refresh/access tokens for a
19  * secret received while registering the instance in GCD.
20  */
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";
25
26     private final HttpClient mHttpClient;
27     private final String mScope;
28     private final String mClientId;
29     private final String mClientSecret;
30
31     OAuthClient(HttpClient httpClient, String scope, String clientId, String clientSecret) {
32         assert httpClient != null;
33         assert scope != null;
34         assert clientId != null;
35         assert clientSecret != null;
36
37         mHttpClient = httpClient;
38         mScope = scope;
39         mClientId = clientId;
40         mClientSecret = clientSecret;
41     }
42
43     public OAuthResult authenticate(String secret) throws IOException {
44         final long startTimeMs = System.currentTimeMillis();
45
46         String content =
47                 "client_id=" + urlEncode(mClientId)
48                 + "&client_secret=" + urlEncode(mClientSecret)
49                 + "&scope=" + urlEncode(mScope)
50                 + "&code=" + urlEncode(secret)
51                 + "&redirect_uri=oob"
52                 + "&grant_type=authorization_code";
53
54         return mHttpClient.execute(
55                 newHttpPost("/token", content),
56                 new JsonResponseHandler<OAuthResult>() {
57                     @Override
58                     public OAuthResult readResponse(JsonReader reader) throws IOException {
59                         return readResponse(reader, startTimeMs);
60                     }
61                 });
62     }
63
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);
68         return request;
69     }
70
71     private static String urlEncode(String value) {
72         try {
73             return URLEncoder.encode(value, ENCODING);
74         } catch (UnsupportedEncodingException e) {
75             throw new RuntimeException(e);
76         }
77     }
78
79     static OAuthResult readResponse(JsonReader reader, long startTimeMs) throws IOException {
80         String refreshToken = null;
81         String accessToken = null;
82         long expiresInS = 0; // In seconds.
83
84         reader.beginObject();
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();
93             } else {
94                 reader.skipValue();
95             }
96         }
97         reader.endObject();
98
99         return OAuthResult.create(
100                 refreshToken, accessToken, startTimeMs + expiresInS * 1000);
101     }
102 }