Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / policy / policy_oauth2_token_fetcher.cc
1 // Copyright (c) 2013 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 #include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "google_apis/gaia/gaia_auth_fetcher.h"
14 #include "google_apis/gaia/gaia_constants.h"
15 #include "google_apis/gaia/gaia_urls.h"
16 #include "google_apis/gaia/google_service_auth_error.h"
17 #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
18 #include "net/url_request/url_request_context_getter.h"
19
20 using content::BrowserThread;
21
22 namespace policy {
23
24 namespace {
25
26 // Max retry count for token fetching requests.
27 const int kMaxRequestAttemptCount = 5;
28
29 // OAuth token request retry delay in milliseconds.
30 const int kRequestRestartDelay = 3000;
31
32 }  // namespace
33
34 PolicyOAuth2TokenFetcher::PolicyOAuth2TokenFetcher(
35     net::URLRequestContextGetter* auth_context_getter,
36     net::URLRequestContextGetter* system_context_getter,
37     const TokenCallback& callback)
38     : auth_context_getter_(auth_context_getter),
39       system_context_getter_(system_context_getter),
40       retry_count_(0),
41       failed_(false),
42       callback_(callback) {}
43
44 PolicyOAuth2TokenFetcher::~PolicyOAuth2TokenFetcher() {}
45
46 void PolicyOAuth2TokenFetcher::Start() {
47   retry_count_ = 0;
48   StartFetchingRefreshToken();
49 }
50
51 void PolicyOAuth2TokenFetcher::StartFetchingRefreshToken() {
52   refresh_token_fetcher_.reset(new GaiaAuthFetcher(
53       this, GaiaConstants::kChromeSource, auth_context_getter_.get()));
54   refresh_token_fetcher_->StartCookieForOAuthLoginTokenExchange(std::string());
55 }
56
57 void PolicyOAuth2TokenFetcher::StartFetchingAccessToken() {
58   std::vector<std::string> scopes;
59   scopes.push_back(GaiaConstants::kDeviceManagementServiceOAuth);
60   scopes.push_back(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
61   scopes.push_back(GaiaConstants::kGoogleUserInfoEmail);
62   scopes.push_back(GaiaConstants::kGoogleUserInfoProfile);
63   access_token_fetcher_.reset(
64       new OAuth2AccessTokenFetcherImpl(this,
65                                        system_context_getter_.get(),
66                                        oauth2_refresh_token_));
67   access_token_fetcher_->Start(
68       GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
69       GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
70       scopes);
71 }
72
73 void PolicyOAuth2TokenFetcher::OnClientOAuthSuccess(
74     const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) {
75   VLOG(1) << "OAuth2 tokens for policy fetching succeeded.";
76   oauth2_tokens_ = oauth2_tokens;
77   oauth2_refresh_token_ = oauth2_tokens.refresh_token;
78   retry_count_ = 0;
79   StartFetchingAccessToken();
80 }
81
82 void PolicyOAuth2TokenFetcher::OnClientOAuthFailure(
83     const GoogleServiceAuthError& error) {
84   VLOG(1) << "OAuth2 tokens fetch for policy fetch failed!";
85   RetryOnError(error,
86                base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingRefreshToken,
87                           AsWeakPtr()));
88 }
89
90 void PolicyOAuth2TokenFetcher::OnGetTokenSuccess(
91     const std::string& access_token,
92     const base::Time& expiration_time) {
93   VLOG(1) << "OAuth2 access token (device management) fetching succeeded.";
94   oauth2_access_token_ = access_token;
95   ForwardPolicyToken(access_token,
96                      GoogleServiceAuthError(GoogleServiceAuthError::NONE));
97 }
98
99 void PolicyOAuth2TokenFetcher::OnGetTokenFailure(
100     const GoogleServiceAuthError& error) {
101   LOG(ERROR) << "OAuth2 access token (device management) fetching failed!";
102   RetryOnError(error,
103                base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingAccessToken,
104                           AsWeakPtr()));
105 }
106
107 void PolicyOAuth2TokenFetcher::RetryOnError(const GoogleServiceAuthError& error,
108                                             const base::Closure& task) {
109   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
110   if ((error.state() == GoogleServiceAuthError::CONNECTION_FAILED ||
111        error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE ||
112        error.state() == GoogleServiceAuthError::REQUEST_CANCELED) &&
113       retry_count_ < kMaxRequestAttemptCount) {
114     retry_count_++;
115     BrowserThread::PostDelayedTask(
116         BrowserThread::UI, FROM_HERE, task,
117         base::TimeDelta::FromMilliseconds(kRequestRestartDelay));
118     return;
119   }
120   LOG(ERROR) << "Unrecoverable error or retry count max reached.";
121   failed_ = true;
122   // Invoking the |callback_| signals to the owner of this object that it has
123   // completed, and the owner may delete this object on the callback method.
124   // So don't rely on |this| still being valid after ForwardPolicyToken()
125   // returns i.e. don't write to |failed_| or other fields.
126   ForwardPolicyToken(std::string(), error);
127 }
128
129 void PolicyOAuth2TokenFetcher::ForwardPolicyToken(
130     const std::string& token,
131     const GoogleServiceAuthError& error) {
132   if (!callback_.is_null())
133     callback_.Run(token, error);
134 }
135
136 }  // namespace policy