Index: chrome/browser/chromeos/arc/arc_auth_context.cc |
diff --git a/chrome/browser/chromeos/arc/arc_auth_context.cc b/chrome/browser/chromeos/arc/arc_auth_context.cc |
index a7d7747fde8a9a083dd71b317979e411e68b02d5..5236f5eed6bda4dc7a0ef42b9c69f4e9ae2a914a 100644 |
--- a/chrome/browser/chromeos/arc/arc_auth_context.cc |
+++ b/chrome/browser/chromeos/arc/arc_auth_context.cc |
@@ -4,43 +4,64 @@ |
#include "chrome/browser/chromeos/arc/arc_auth_context.h" |
+#include "base/json/json_string_value_serializer.h" |
+#include "base/json/json_writer.h" |
#include "base/strings/stringprintf.h" |
+#include "base/values.h" |
#include "chrome/browser/chromeos/arc/arc_auth_context_delegate.h" |
#include "chrome/browser/chromeos/arc/arc_support_host.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
#include "chrome/browser/signin/signin_manager_factory.h" |
+#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" |
+#include "components/signin/core/account_id/account_id.h" |
#include "components/signin/core/browser/profile_oauth2_token_service.h" |
#include "components/signin/core/browser/signin_manager_base.h" |
+#include "components/user_manager/known_user.h" |
#include "content/public/browser/browser_context.h" |
#include "content/public/browser/storage_partition.h" |
#include "content/public/common/url_constants.h" |
#include "google_apis/gaia/gaia_auth_fetcher.h" |
#include "google_apis/gaia/gaia_constants.h" |
+#include "net/base/load_flags.h" |
+#include "net/http/http_status_code.h" |
namespace arc { |
namespace { |
constexpr int kRefreshTokenTimeoutSeconds = 10; |
+constexpr int kGetAuthCodeNetworkRetry = 3; |
+ |
+constexpr char kConsumerName[] = "ArcAuthContext"; |
+constexpr char kToken[] = "token"; |
+constexpr char kDeviceId[] = "device_id"; |
+constexpr char kDeviceType[] = "device_type"; |
+constexpr char kDeviceTypeArc[] = "arc_plus_plus"; |
+constexpr char kLoginScopedToken[] = "login_scoped_token"; |
+constexpr char kGetAuthCodeHeaders[] = |
+ "Content-Type: application/json; charset=utf-8"; |
+constexpr char kContentTypeJSON[] = "application/json"; |
} // namespace |
ArcAuthContext::ArcAuthContext(ArcAuthContextDelegate* delegate, |
Profile* profile) |
- : delegate_(delegate) { |
+ : OAuth2TokenService::Consumer(kConsumerName), |
+ delegate_(delegate), |
+ profile_(profile) { |
// Reuse storage used in ARC OptIn platform app. |
const std::string site_url = base::StringPrintf( |
"%s://%s/persist?%s", content::kGuestScheme, ArcSupportHost::kHostAppId, |
ArcSupportHost::kStorageId); |
storage_partition_ = content::BrowserContext::GetStoragePartitionForSite( |
- profile, GURL(site_url)); |
+ profile_, GURL(site_url)); |
CHECK(storage_partition_); |
// Get token service and account ID to fetch auth tokens. |
- token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile); |
+ token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
const SigninManagerBase* const signin_manager = |
- SigninManagerFactory::GetForProfile(profile); |
+ SigninManagerFactory::GetForProfile(profile_); |
CHECK(token_service_ && signin_manager); |
account_id_ = signin_manager->GetAuthenticatedAccountId(); |
} |
@@ -67,18 +88,103 @@ void ArcAuthContext::OnRefreshTokenTimeout() { |
delegate_->OnPrepareContextFailed(); |
} |
+void ArcAuthContext::OnGetTokenSuccess( |
+ const OAuth2TokenService::Request* request, |
+ const std::string& access_token, |
+ const base::Time& expiration_time) { |
+ ResetFetchers(); |
+ |
+ const std::string device_id = user_manager::known_user::GetDeviceId( |
+ multi_user_util::GetAccountIdFromProfile(profile_)); |
+ DCHECK(!device_id.empty()); |
+ |
+ base::DictionaryValue request_data; |
+ request_data.SetString(kLoginScopedToken, access_token); |
+ request_data.SetString(kDeviceType, kDeviceTypeArc); |
+ request_data.SetString(kDeviceId, device_id); |
+ std::string request_string; |
+ base::JSONWriter::Write(request_data, &request_string); |
+ |
+ DCHECK(!auth_endpoint_.empty()); |
+ auth_code_fetcher_ = net::URLFetcher::Create(0, GURL(auth_endpoint_), |
+ net::URLFetcher::POST, this); |
+ auth_code_fetcher_->SetRequestContext( |
+ storage_partition_->GetURLRequestContext()); |
+ auth_code_fetcher_->SetUploadData(kContentTypeJSON, request_string); |
+ 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
|
+ auth_code_fetcher_->SetAutomaticallyRetryOnNetworkChanges( |
+ kGetAuthCodeNetworkRetry); |
+ auth_code_fetcher_->SetExtraRequestHeaders(kGetAuthCodeHeaders); |
+ auth_code_fetcher_->Start(); |
+} |
+ |
+void ArcAuthContext::OnGetTokenFailure( |
+ const OAuth2TokenService::Request* request, |
+ const GoogleServiceAuthError& error) { |
+ VLOG(2) << "Failed to get LST " << error.ToString() << "."; |
+ ResetFetchers(); |
+ |
+ delegate_->OnAuthCodeFailed(); |
+} |
+ |
+void ArcAuthContext::OnURLFetchComplete(const net::URLFetcher* source) { |
+ const int response_code = source->GetResponseCode(); |
+ std::string json_string; |
+ source->GetResponseAsString(&json_string); |
+ |
+ ResetFetchers(); |
+ |
+ if (response_code != net::HTTP_OK) { |
+ VLOG(2) << "Server returned wrong response code: " << response_code << "."; |
+ delegate_->OnAuthCodeFailed(); |
+ return; |
+ } |
+ |
+ JSONStringValueDeserializer deserializer(json_string); |
+ std::string error_msg; |
+ std::unique_ptr<base::Value> auth_code_info = |
+ deserializer.Deserialize(nullptr, &error_msg); |
+ if (!auth_code_info) { |
+ VLOG(2) << "Unable to deserialize auth code json data: " << error_msg |
+ << "."; |
+ delegate_->OnAuthCodeFailed(); |
+ return; |
+ } |
+ |
+ std::unique_ptr<base::DictionaryValue> auth_code_dictionary = |
+ base::DictionaryValue::From(std::move(auth_code_info)); |
+ if (!auth_code_dictionary) { |
+ NOTREACHED(); |
+ delegate_->OnAuthCodeFailed(); |
+ return; |
+ } |
+ |
+ std::string auth_code; |
+ if (!auth_code_dictionary->GetString(kToken, &auth_code) || |
+ auth_code.empty()) { |
+ VLOG(2) << "Response does not contain auth code."; |
+ delegate_->OnAuthCodeFailed(); |
+ return; |
+ } |
+ |
+ delegate_->OnAuthCodeRequested(auth_code); |
+} |
+ |
void ArcAuthContext::OnMergeSessionSuccess(const std::string& data) { |
context_prepared_ = true; |
+ ResetFetchers(); |
delegate_->OnContextReady(); |
} |
void ArcAuthContext::OnMergeSessionFailure( |
const GoogleServiceAuthError& error) { |
VLOG(2) << "Failed to merge gaia session " << error.ToString() << "."; |
+ ResetFetchers(); |
delegate_->OnPrepareContextFailed(); |
} |
void ArcAuthContext::OnUbertokenSuccess(const std::string& token) { |
+ ResetFetchers(); |
merger_fetcher_.reset( |
new GaiaAuthFetcher(this, GaiaConstants::kChromeOSSource, |
storage_partition_->GetURLRequestContext())); |
@@ -87,6 +193,7 @@ void ArcAuthContext::OnUbertokenSuccess(const std::string& token) { |
void ArcAuthContext::OnUbertokenFailure(const GoogleServiceAuthError& error) { |
VLOG(2) << "Failed to get ubertoken " << error.ToString() << "."; |
+ ResetFetchers(); |
delegate_->OnPrepareContextFailed(); |
} |
@@ -110,13 +217,32 @@ void ArcAuthContext::PrepareContext() { |
StartFetchers(); |
} |
+void ArcAuthContext::FetchAuthCode(const std::string& auth_endpoint) { |
+ DCHECK(context_prepared_); |
+ |
+ ResetFetchers(); |
+ auth_endpoint_ = auth_endpoint; |
+ |
+ OAuth2TokenService::ScopeSet scopes; |
+ scopes.insert(GaiaConstants::kOAuth1LoginScope); |
+ login_token_request_.reset( |
+ token_service_->StartRequest(account_id_, scopes, this).release()); |
+} |
+ |
void ArcAuthContext::StartFetchers() { |
DCHECK(!refresh_token_timeout_.IsRunning()); |
- merger_fetcher_.reset(); |
+ ResetFetchers(); |
ubertoken_fetcher_.reset( |
new UbertokenFetcher(token_service_, this, GaiaConstants::kChromeOSSource, |
storage_partition_->GetURLRequestContext())); |
ubertoken_fetcher_->StartFetchingToken(account_id_); |
} |
+void ArcAuthContext::ResetFetchers() { |
+ merger_fetcher_.reset(); |
+ login_token_request_.reset(); |
+ auth_code_fetcher_.reset(); |
+ ubertoken_fetcher_.reset(); |
+} |
+ |
} // namespace arc |