Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Side by Side Diff: chrome/browser/chromeos/arc/arc_auth_context.cc

Issue 2320813002: arc: Enable silent PlayStore Sign-In. (Closed)
Patch Set: cleanup Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/arc/arc_auth_context.h" 5 #include "chrome/browser/chromeos/arc/arc_auth_context.h"
6 6
7 #include "base/json/json_string_value_serializer.h"
8 #include "base/json/json_writer.h"
7 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/values.h"
8 #include "chrome/browser/chromeos/arc/arc_auth_context_delegate.h" 11 #include "chrome/browser/chromeos/arc/arc_auth_context_delegate.h"
9 #include "chrome/browser/chromeos/arc/arc_support_host.h" 12 #include "chrome/browser/chromeos/arc/arc_support_host.h"
10 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
12 #include "chrome/browser/signin/signin_manager_factory.h" 15 #include "chrome/browser/signin/signin_manager_factory.h"
16 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
17 #include "components/signin/core/account_id/account_id.h"
13 #include "components/signin/core/browser/profile_oauth2_token_service.h" 18 #include "components/signin/core/browser/profile_oauth2_token_service.h"
14 #include "components/signin/core/browser/signin_manager_base.h" 19 #include "components/signin/core/browser/signin_manager_base.h"
20 #include "components/user_manager/known_user.h"
15 #include "content/public/browser/browser_context.h" 21 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/storage_partition.h" 22 #include "content/public/browser/storage_partition.h"
17 #include "content/public/common/url_constants.h" 23 #include "content/public/common/url_constants.h"
18 #include "google_apis/gaia/gaia_auth_fetcher.h" 24 #include "google_apis/gaia/gaia_auth_fetcher.h"
19 #include "google_apis/gaia/gaia_constants.h" 25 #include "google_apis/gaia/gaia_constants.h"
26 #include "net/base/load_flags.h"
27 #include "net/http/http_status_code.h"
20 28
21 namespace arc { 29 namespace arc {
22 30
23 namespace { 31 namespace {
24 32
25 constexpr int kRefreshTokenTimeoutSeconds = 10; 33 constexpr int kRefreshTokenTimeoutSeconds = 10;
34 constexpr int kGetAuthCodeNetworkRetry = 3;
35
36 constexpr char kConsumerName[] = "ArcAuthContext";
37 constexpr char kToken[] = "token";
38 constexpr char kDeviceId[] = "device_id";
39 constexpr char kDeviceType[] = "device_type";
40 constexpr char kDeviceTypeArc[] = "arc_plus_plus";
41 constexpr char kLoginScopedToken[] = "login_scoped_token";
42 constexpr char kGetAuthCodeHeaders[] =
43 "Content-Type: application/json; charset=utf-8";
44 constexpr char kContentTypeJSON[] = "application/json";
26 45
27 } // namespace 46 } // namespace
28 47
29 ArcAuthContext::ArcAuthContext(ArcAuthContextDelegate* delegate, 48 ArcAuthContext::ArcAuthContext(ArcAuthContextDelegate* delegate,
30 Profile* profile) 49 Profile* profile)
31 : delegate_(delegate) { 50 : OAuth2TokenService::Consumer(kConsumerName),
51 delegate_(delegate),
52 profile_(profile) {
32 // Reuse storage used in ARC OptIn platform app. 53 // Reuse storage used in ARC OptIn platform app.
33 const std::string site_url = base::StringPrintf( 54 const std::string site_url = base::StringPrintf(
34 "%s://%s/persist?%s", content::kGuestScheme, ArcSupportHost::kHostAppId, 55 "%s://%s/persist?%s", content::kGuestScheme, ArcSupportHost::kHostAppId,
35 ArcSupportHost::kStorageId); 56 ArcSupportHost::kStorageId);
36 storage_partition_ = content::BrowserContext::GetStoragePartitionForSite( 57 storage_partition_ = content::BrowserContext::GetStoragePartitionForSite(
37 profile, GURL(site_url)); 58 profile_, GURL(site_url));
38 CHECK(storage_partition_); 59 CHECK(storage_partition_);
39 60
40 // Get token service and account ID to fetch auth tokens. 61 // Get token service and account ID to fetch auth tokens.
41 token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile); 62 token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
42 const SigninManagerBase* const signin_manager = 63 const SigninManagerBase* const signin_manager =
43 SigninManagerFactory::GetForProfile(profile); 64 SigninManagerFactory::GetForProfile(profile_);
44 CHECK(token_service_ && signin_manager); 65 CHECK(token_service_ && signin_manager);
45 account_id_ = signin_manager->GetAuthenticatedAccountId(); 66 account_id_ = signin_manager->GetAuthenticatedAccountId();
46 } 67 }
47 68
48 ArcAuthContext::~ArcAuthContext() { 69 ArcAuthContext::~ArcAuthContext() {
49 token_service_->RemoveObserver(this); 70 token_service_->RemoveObserver(this);
50 } 71 }
51 72
52 void ArcAuthContext::OnRefreshTokenAvailable(const std::string& account_id) { 73 void ArcAuthContext::OnRefreshTokenAvailable(const std::string& account_id) {
53 if (account_id != account_id_) 74 if (account_id != account_id_)
54 return; 75 return;
55 OnRefreshTokensLoaded(); 76 OnRefreshTokensLoaded();
56 } 77 }
57 78
58 void ArcAuthContext::OnRefreshTokensLoaded() { 79 void ArcAuthContext::OnRefreshTokensLoaded() {
59 token_service_->RemoveObserver(this); 80 token_service_->RemoveObserver(this);
60 refresh_token_timeout_.Stop(); 81 refresh_token_timeout_.Stop();
61 StartFetchers(); 82 StartFetchers();
62 } 83 }
63 84
64 void ArcAuthContext::OnRefreshTokenTimeout() { 85 void ArcAuthContext::OnRefreshTokenTimeout() {
65 VLOG(2) << "Failed to wait for refresh token."; 86 VLOG(2) << "Failed to wait for refresh token.";
66 token_service_->RemoveObserver(this); 87 token_service_->RemoveObserver(this);
67 delegate_->OnPrepareContextFailed(); 88 delegate_->OnPrepareContextFailed();
68 } 89 }
69 90
91 void ArcAuthContext::OnGetTokenSuccess(
92 const OAuth2TokenService::Request* request,
93 const std::string& access_token,
94 const base::Time& expiration_time) {
95 ResetFetchers();
96
97 const std::string device_id = user_manager::known_user::GetDeviceId(
98 multi_user_util::GetAccountIdFromProfile(profile_));
99 DCHECK(!device_id.empty());
100
101 base::DictionaryValue request_data;
102 request_data.SetString(kLoginScopedToken, access_token);
103 request_data.SetString(kDeviceType, kDeviceTypeArc);
104 request_data.SetString(kDeviceId, device_id);
105 std::string request_string;
106 base::JSONWriter::Write(request_data, &request_string);
107
108 DCHECK(!auth_endpoint_.empty());
109 auth_code_fetcher_ = net::URLFetcher::Create(0, GURL(auth_endpoint_),
110 net::URLFetcher::POST, this);
111 auth_code_fetcher_->SetRequestContext(
112 storage_partition_->GetURLRequestContext());
113 auth_code_fetcher_->SetUploadData(kContentTypeJSON, request_string);
114 auth_code_fetcher_->SetLoadFlags(net::LOAD_NORMAL);
xiyuan 2016/09/07 21:07:55 We might want to use LOAD_DISABLE_CACHE | LOAD_BYP
khmel 2016/09/07 23:08:53 Done
115 auth_code_fetcher_->SetAutomaticallyRetryOnNetworkChanges(
116 kGetAuthCodeNetworkRetry);
117 auth_code_fetcher_->SetExtraRequestHeaders(kGetAuthCodeHeaders);
118 auth_code_fetcher_->Start();
119 }
120
121 void ArcAuthContext::OnGetTokenFailure(
122 const OAuth2TokenService::Request* request,
123 const GoogleServiceAuthError& error) {
124 VLOG(2) << "Failed to get LST " << error.ToString() << ".";
125 ResetFetchers();
126
127 delegate_->OnAuthCodeFailed();
128 }
129
130 void ArcAuthContext::OnURLFetchComplete(const net::URLFetcher* source) {
131 const int response_code = source->GetResponseCode();
132 std::string json_string;
133 source->GetResponseAsString(&json_string);
134
135 ResetFetchers();
136
137 if (response_code != net::HTTP_OK) {
138 VLOG(2) << "Server returned wrong response code: " << response_code << ".";
139 delegate_->OnAuthCodeFailed();
140 return;
141 }
142
143 JSONStringValueDeserializer deserializer(json_string);
144 std::string error_msg;
145 std::unique_ptr<base::Value> auth_code_info =
146 deserializer.Deserialize(nullptr, &error_msg);
147 if (!auth_code_info) {
148 VLOG(2) << "Unable to deserialize auth code json data: " << error_msg
149 << ".";
150 delegate_->OnAuthCodeFailed();
151 return;
152 }
153
154 std::unique_ptr<base::DictionaryValue> auth_code_dictionary =
155 base::DictionaryValue::From(std::move(auth_code_info));
156 if (!auth_code_dictionary) {
157 NOTREACHED();
158 delegate_->OnAuthCodeFailed();
159 return;
160 }
161
162 std::string auth_code;
163 if (!auth_code_dictionary->GetString(kToken, &auth_code) ||
164 auth_code.empty()) {
165 VLOG(2) << "Response does not contain auth code.";
166 delegate_->OnAuthCodeFailed();
167 return;
168 }
169
170 delegate_->OnAuthCodeRequested(auth_code);
171 }
172
70 void ArcAuthContext::OnMergeSessionSuccess(const std::string& data) { 173 void ArcAuthContext::OnMergeSessionSuccess(const std::string& data) {
71 context_prepared_ = true; 174 context_prepared_ = true;
175 ResetFetchers();
72 delegate_->OnContextReady(); 176 delegate_->OnContextReady();
73 } 177 }
74 178
75 void ArcAuthContext::OnMergeSessionFailure( 179 void ArcAuthContext::OnMergeSessionFailure(
76 const GoogleServiceAuthError& error) { 180 const GoogleServiceAuthError& error) {
77 VLOG(2) << "Failed to merge gaia session " << error.ToString() << "."; 181 VLOG(2) << "Failed to merge gaia session " << error.ToString() << ".";
182 ResetFetchers();
78 delegate_->OnPrepareContextFailed(); 183 delegate_->OnPrepareContextFailed();
79 } 184 }
80 185
81 void ArcAuthContext::OnUbertokenSuccess(const std::string& token) { 186 void ArcAuthContext::OnUbertokenSuccess(const std::string& token) {
187 ResetFetchers();
82 merger_fetcher_.reset( 188 merger_fetcher_.reset(
83 new GaiaAuthFetcher(this, GaiaConstants::kChromeOSSource, 189 new GaiaAuthFetcher(this, GaiaConstants::kChromeOSSource,
84 storage_partition_->GetURLRequestContext())); 190 storage_partition_->GetURLRequestContext()));
85 merger_fetcher_->StartMergeSession(token, std::string()); 191 merger_fetcher_->StartMergeSession(token, std::string());
86 } 192 }
87 193
88 void ArcAuthContext::OnUbertokenFailure(const GoogleServiceAuthError& error) { 194 void ArcAuthContext::OnUbertokenFailure(const GoogleServiceAuthError& error) {
89 VLOG(2) << "Failed to get ubertoken " << error.ToString() << "."; 195 VLOG(2) << "Failed to get ubertoken " << error.ToString() << ".";
196 ResetFetchers();
90 delegate_->OnPrepareContextFailed(); 197 delegate_->OnPrepareContextFailed();
91 } 198 }
92 199
93 void ArcAuthContext::PrepareContext() { 200 void ArcAuthContext::PrepareContext() {
94 if (context_prepared_) { 201 if (context_prepared_) {
95 delegate_->OnContextReady(); 202 delegate_->OnContextReady();
96 return; 203 return;
97 } 204 }
98 205
99 token_service_->RemoveObserver(this); 206 token_service_->RemoveObserver(this);
100 refresh_token_timeout_.Stop(); 207 refresh_token_timeout_.Stop();
101 208
102 if (!token_service_->RefreshTokenIsAvailable(account_id_)) { 209 if (!token_service_->RefreshTokenIsAvailable(account_id_)) {
103 token_service_->AddObserver(this); 210 token_service_->AddObserver(this);
104 refresh_token_timeout_.Start( 211 refresh_token_timeout_.Start(
105 FROM_HERE, base::TimeDelta::FromSeconds(kRefreshTokenTimeoutSeconds), 212 FROM_HERE, base::TimeDelta::FromSeconds(kRefreshTokenTimeoutSeconds),
106 this, &ArcAuthContext::OnRefreshTokenTimeout); 213 this, &ArcAuthContext::OnRefreshTokenTimeout);
107 return; 214 return;
108 } 215 }
109 216
110 StartFetchers(); 217 StartFetchers();
111 } 218 }
112 219
220 void ArcAuthContext::FetchAuthCode(const std::string& auth_endpoint) {
221 DCHECK(context_prepared_);
222
223 ResetFetchers();
224 auth_endpoint_ = auth_endpoint;
225
226 OAuth2TokenService::ScopeSet scopes;
227 scopes.insert(GaiaConstants::kOAuth1LoginScope);
228 login_token_request_.reset(
229 token_service_->StartRequest(account_id_, scopes, this).release());
230 }
231
113 void ArcAuthContext::StartFetchers() { 232 void ArcAuthContext::StartFetchers() {
114 DCHECK(!refresh_token_timeout_.IsRunning()); 233 DCHECK(!refresh_token_timeout_.IsRunning());
115 merger_fetcher_.reset(); 234 ResetFetchers();
116 ubertoken_fetcher_.reset( 235 ubertoken_fetcher_.reset(
117 new UbertokenFetcher(token_service_, this, GaiaConstants::kChromeOSSource, 236 new UbertokenFetcher(token_service_, this, GaiaConstants::kChromeOSSource,
118 storage_partition_->GetURLRequestContext())); 237 storage_partition_->GetURLRequestContext()));
119 ubertoken_fetcher_->StartFetchingToken(account_id_); 238 ubertoken_fetcher_->StartFetchingToken(account_id_);
120 } 239 }
121 240
241 void ArcAuthContext::ResetFetchers() {
242 merger_fetcher_.reset();
243 login_token_request_.reset();
244 auth_code_fetcher_.reset();
245 ubertoken_fetcher_.reset();
246 }
247
122 } // namespace arc 248 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698