summaryrefslogtreecommitdiff
path: root/chromium/components/signin
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-09-18 14:34:04 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-10-04 11:15:27 +0000
commite6430e577f105ad8813c92e75c54660c4985026e (patch)
tree88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/components/signin
parent53d399fe6415a96ea6986ec0d402a9c07da72453 (diff)
downloadqtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/components/signin')
-rw-r--r--chromium/components/signin/core/account_id/account_id.cc10
-rw-r--r--chromium/components/signin/core/account_id/account_id.h7
-rw-r--r--chromium/components/signin/core/browser/BUILD.gn48
-rw-r--r--chromium/components/signin/core/browser/about_signin_internals.cc58
-rw-r--r--chromium/components/signin/core/browser/about_signin_internals.h3
-rw-r--r--chromium/components/signin/core/browser/access_token_fetcher.cc3
-rw-r--r--chromium/components/signin/core/browser/access_token_fetcher.h3
-rw-r--r--chromium/components/signin/core/browser/account_fetcher_service.cc9
-rw-r--r--chromium/components/signin/core/browser/account_fetcher_service.h7
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor.cc7
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor.h3
-rw-r--r--chromium/components/signin/core/browser/account_tracker_service.cc1
-rw-r--r--chromium/components/signin/core/browser/account_tracker_service.h8
-rw-r--r--chromium/components/signin/core/browser/android/BUILD.gn6
-rw-r--r--chromium/components/signin/core/browser/child_account_info_fetcher_android.cc5
-rw-r--r--chromium/components/signin/core/browser/child_account_info_fetcher_android.h3
-rw-r--r--chromium/components/signin/core/browser/chrome_connected_header_helper.cc171
-rw-r--r--chromium/components/signin/core/browser/chrome_connected_header_helper.h55
-rw-r--r--chromium/components/signin/core/browser/dice_header_helper.cc147
-rw-r--r--chromium/components/signin/core/browser/dice_header_helper.h44
-rw-r--r--chromium/components/signin/core/browser/fake_signin_manager.cc10
-rw-r--r--chromium/components/signin/core/browser/fake_signin_manager.h8
-rw-r--r--chromium/components/signin/core/browser/profile_identity_provider.cc3
-rw-r--r--chromium/components/signin/core/browser/profile_identity_provider.h3
-rw-r--r--chromium/components/signin/core/browser/profile_oauth2_token_service.cc10
-rw-r--r--chromium/components/signin/core/browser/profile_oauth2_token_service.h18
-rw-r--r--chromium/components/signin/core/browser/refresh_token_annotation_request.cc44
-rw-r--r--chromium/components/signin/core/browser/refresh_token_annotation_request.h9
-rw-r--r--chromium/components/signin/core/browser/resources/signin_index.html2
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper.cc307
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper.h131
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper_unittest.cc296
-rw-r--r--chromium/components/signin/core/browser/signin_manager.cc35
-rw-r--r--chromium/components/signin/core/browser/signin_manager.h10
-rw-r--r--chromium/components/signin/core/browser/signin_manager_base.cc4
-rw-r--r--chromium/components/signin/core/browser/signin_manager_base.h44
-rw-r--r--chromium/components/signin/core/browser/signin_metrics.h1
-rw-r--r--chromium/components/signin/core/browser/signin_status_metrics_provider.cc3
-rw-r--r--chromium/components/signin/core/browser/signin_status_metrics_provider.h3
-rw-r--r--chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc6
-rw-r--r--chromium/components/signin/core/browser/signin_tracker.cc6
-rw-r--r--chromium/components/signin/core/browser/signin_tracker.h2
-rw-r--r--chromium/components/signin/core/common/BUILD.gn15
-rw-r--r--chromium/components/signin/core/common/profile_management_switches.cc47
-rw-r--r--chromium/components/signin/core/common/profile_management_switches.h28
-rw-r--r--chromium/components/signin/core/common/signin_switches.cc14
-rw-r--r--chromium/components/signin/core/common/signin_switches.h12
-rw-r--r--chromium/components/signin/features.gni9
-rw-r--r--chromium/components/signin/ios/browser/BUILD.gn5
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service.h9
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service.mm22
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service_unittest.mm34
-rw-r--r--chromium/components/signin/ios/browser/merge_session_observer_bridge.h2
-rw-r--r--chromium/components/signin/ios/browser/merge_session_observer_bridge.mm4
-rw-r--r--chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.h3
-rw-r--r--chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.mm4
-rw-r--r--chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm4
-rw-r--r--chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm4
-rw-r--r--chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_provider.mm4
59 files changed, 1304 insertions, 469 deletions
diff --git a/chromium/components/signin/core/account_id/account_id.cc b/chromium/components/signin/core/account_id/account_id.cc
index 1ffac80db1e..e232ecb965c 100644
--- a/chromium/components/signin/core/account_id/account_id.cc
+++ b/chromium/components/signin/core/account_id/account_id.cc
@@ -319,6 +319,16 @@ bool AccountId::Deserialize(const std::string& serialized,
return false;
}
+std::ostream& operator<<(std::ostream& stream, const AccountId& account_id) {
+ stream << "{id: " << account_id.id_ << ", email: " << account_id.user_email_
+ << ", type: "
+ << static_cast<
+ std::underlying_type<decltype(account_id.account_type_)>::type>(
+ account_id.account_type_)
+ << "}";
+ return stream;
+}
+
const AccountId& EmptyAccountId() {
return AccountId::EmptyAccountId::GetInstance()->user_id;
}
diff --git a/chromium/components/signin/core/account_id/account_id.h b/chromium/components/signin/core/account_id/account_id.h
index 81082b5fe04..a263178d13d 100644
--- a/chromium/components/signin/core/account_id/account_id.h
+++ b/chromium/components/signin/core/account_id/account_id.h
@@ -7,7 +7,9 @@
#include <stddef.h>
+#include <ostream>
#include <string>
+
#include "base/containers/hash_tables.h"
enum class AccountType { UNKNOWN, GOOGLE, ACTIVE_DIRECTORY };
@@ -97,6 +99,8 @@ class AccountId {
AccountId* out_account_id);
private:
+ friend std::ostream& operator<<(std::ostream&, const AccountId&);
+
AccountId(const std::string& id,
const std::string& user_email,
const AccountType& account_type);
@@ -106,6 +110,9 @@ class AccountId {
AccountType account_type_ = AccountType::UNKNOWN;
};
+// Overload << operator to allow logging of AccountIds.
+std::ostream& operator<<(std::ostream& stream, const AccountId& account_id);
+
// Returns a reference to a singleton.
const AccountId& EmptyAccountId();
diff --git a/chromium/components/signin/core/browser/BUILD.gn b/chromium/components/signin/core/browser/BUILD.gn
index 5265026b314..b900638e0cf 100644
--- a/chromium/components/signin/core/browser/BUILD.gn
+++ b/chromium/components/signin/core/browser/BUILD.gn
@@ -2,10 +2,23 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//components/signin/features.gni")
+
if (is_android) {
import("//build/config/android/rules.gni")
}
+# Split into its own target to allow the Identity Service to depend on it in
+# typemaps without introducing a dependency on all of
+# //components/signin/core/browser, which is undesirable. In the long term
+# this file will move to be part of the Identity Service client library.
+static_library("account_info") {
+ sources = [
+ "account_info.cc",
+ "account_info.h",
+ ]
+}
+
static_library("browser") {
sources = [
"about_signin_internals.cc",
@@ -14,8 +27,6 @@ static_library("browser") {
"access_token_fetcher.h",
"account_fetcher_service.cc",
"account_fetcher_service.h",
- "account_info.cc",
- "account_info.h",
"account_info_fetcher.cc",
"account_info_fetcher.h",
"account_investigator.cc",
@@ -24,14 +35,16 @@ static_library("browser") {
"account_reconcilor.h",
"account_tracker_service.cc",
"account_tracker_service.h",
- "android/component_jni_registrar.cc",
- "android/component_jni_registrar.h",
"child_account_info_fetcher.cc",
"child_account_info_fetcher.h",
"child_account_info_fetcher_android.cc",
"child_account_info_fetcher_android.h",
"child_account_info_fetcher_impl.cc",
"child_account_info_fetcher_impl.h",
+ "chrome_connected_header_helper.cc",
+ "chrome_connected_header_helper.h",
+ "dice_header_helper.cc",
+ "dice_header_helper.h",
"gaia_cookie_manager_service.cc",
"gaia_cookie_manager_service.h",
"profile_identity_provider.cc",
@@ -75,26 +88,29 @@ static_library("browser") {
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
public_deps = [
+ ":account_info",
+ "//base",
+ "//components/content_settings/core/browser",
+ "//components/content_settings/core/common",
+ "//components/invalidation/public",
+ "//components/keyed_service/core",
+ "//components/prefs",
"//components/signin/core/account_id",
"//components/signin/core/common",
+ "//components/signin/core/common:signin_features",
+ "//google_apis",
+ "//net",
+ "//url",
]
deps = [
- "//base",
"//base:i18n",
- "//components/content_settings/core/browser",
- "//components/content_settings/core/common",
"//components/data_use_measurement/core",
"//components/google/core/browser",
- "//components/invalidation/public",
- "//components/keyed_service/core",
"//components/metrics",
"//components/os_crypt",
"//components/pref_registry",
- "//components/prefs",
"//components/webdata/common",
"//crypto",
- "//google_apis",
- "//net",
"//sql",
"//third_party/icu",
]
@@ -107,6 +123,13 @@ static_library("browser") {
]
}
+ if (!enable_dice_support) {
+ sources -= [
+ "dice_header_helper.cc",
+ "dice_header_helper.h",
+ ]
+ }
+
if (is_android) {
sources -= [
"child_account_info_fetcher_impl.cc",
@@ -167,6 +190,7 @@ source_set("unit_tests") {
"//components/os_crypt:test_support",
"//components/pref_registry:pref_registry",
"//components/signin/core/common",
+ "//components/signin/core/common:signin_features",
"//components/sync_preferences:test_support",
"//testing/gmock",
]
diff --git a/chromium/components/signin/core/browser/about_signin_internals.cc b/chromium/components/signin/core/browser/about_signin_internals.cc
index da7be07b13c..fca6fbe2507 100644
--- a/chromium/components/signin/core/browser/about_signin_internals.cc
+++ b/chromium/components/signin/core/browser/about_signin_internals.cc
@@ -42,11 +42,11 @@ std::string GetTimeStr(base::Time time) {
base::ListValue* AddSection(base::ListValue* parent_list,
const std::string& title) {
- std::unique_ptr<base::DictionaryValue> section(new base::DictionaryValue());
- base::ListValue* section_contents = new base::ListValue();
+ auto section = base::MakeUnique<base::DictionaryValue>();
section->SetString("title", title);
- section->Set("data", section_contents);
+ base::ListValue* section_contents =
+ section->SetList("data", base::MakeUnique<base::ListValue>());
parent_list->Append(std::move(section));
return section_contents;
}
@@ -393,8 +393,7 @@ void AboutSigninInternals::GoogleSigninFailed(
}
void AboutSigninInternals::GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) {
+ const std::string& username) {
NotifyObservers();
}
@@ -410,24 +409,21 @@ void AboutSigninInternals::OnGaiaAccountsInCookieUpdated(
if (error.state() != GoogleServiceAuthError::NONE)
return;
- base::DictionaryValue cookie_status;
- base::ListValue* cookie_info = new base::ListValue();
- cookie_status.Set("cookie_info", cookie_info);
+ auto cookie_info = base::MakeUnique<base::ListValue>();
for (size_t i = 0; i < gaia_accounts.size(); ++i) {
- AddCookieEntry(cookie_info,
- gaia_accounts[i].raw_email,
+ AddCookieEntry(cookie_info.get(), gaia_accounts[i].raw_email,
gaia_accounts[i].gaia_id,
gaia_accounts[i].valid ? "Valid" : "Invalid");
}
if (gaia_accounts.size() == 0) {
- AddCookieEntry(cookie_info,
- "No Accounts Present.",
- std::string(),
+ AddCookieEntry(cookie_info.get(), "No Accounts Present.", std::string(),
std::string());
}
+ base::DictionaryValue cookie_status;
+ cookie_status.Set("cookie_info", std::move(cookie_info));
// Update the observers that the cookie's accounts are updated.
for (auto& observer : signin_observers_)
observer.OnCookieAccountsFetched(&cookie_status);
@@ -529,16 +525,16 @@ AboutSigninInternals::SigninStatus::ToValue(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
"422460 AboutSigninInternals::SigninStatus::ToValue1"));
- std::unique_ptr<base::DictionaryValue> signin_status(
- new base::DictionaryValue());
- base::ListValue* signin_info = new base::ListValue();
- signin_status->Set("signin_info", signin_info);
+ auto signin_status = base::MakeUnique<base::DictionaryValue>();
+ auto signin_info = base::MakeUnique<base::ListValue>();
// A summary of signin related info first.
- base::ListValue* basic_info = AddSection(signin_info, "Basic Information");
+ base::ListValue* basic_info =
+ AddSection(signin_info.get(), "Basic Information");
AddSectionEntry(basic_info, "Chrome Version", product_version);
- AddSectionEntry(basic_info, "Account Consistency?",
- switches::IsEnableAccountConsistency() == true ? "On" : "Off");
+ AddSectionEntry(
+ basic_info, "Account Consistency?",
+ switches::IsAccountConsistencyMirrorEnabled() == true ? "On" : "Off");
AddSectionEntry(basic_info, "Signin Status",
signin_manager->IsAuthenticated() ? "Signed In" : "Not Signed In");
OAuth2TokenServiceDelegate::LoadCredentialsState load_tokens_state =
@@ -589,7 +585,8 @@ AboutSigninInternals::SigninStatus::ToValue(
// Time and status information of the possible sign in types.
base::ListValue* detailed_info =
- AddSection(signin_info, "Last Signin Details");
+ AddSection(signin_info.get(), "Last Signin Details");
+ signin_status->Set("signin_info", std::move(signin_info));
for (int i = TIMED_FIELDS_BEGIN; i < TIMED_FIELDS_END; ++i) {
const std::string status_field_label =
SigninStatusFieldToLabel(static_cast<TimedSigninStatusField>(i));
@@ -644,8 +641,7 @@ AboutSigninInternals::SigninStatus::ToValue(
"422460 AboutSigninInternals::SigninStatus::ToValue4"));
// Token information for all services.
- base::ListValue* token_info = new base::ListValue();
- signin_status->Set("token_info", token_info);
+ auto token_info = base::MakeUnique<base::ListValue>();
for (auto it = token_info_map.begin(); it != token_info_map.end(); ++it) {
// TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460
// is fixed.
@@ -653,7 +649,7 @@ AboutSigninInternals::SigninStatus::ToValue(
FROM_HERE_WITH_EXPLICIT_FUNCTION(
"422460 AboutSigninInternals::SigninStatus::ToValue41"));
- base::ListValue* token_details = AddSection(token_info, it->first);
+ base::ListValue* token_details = AddSection(token_info.get(), it->first);
// TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460
// is fixed.
@@ -674,24 +670,24 @@ AboutSigninInternals::SigninStatus::ToValue(
token_details->Append(token->ToValue());
}
}
+ signin_status->Set("token_info", std::move(token_info));
- base::ListValue* account_info = new base::ListValue();
- signin_status->Set("accountInfo", account_info);
+ auto account_info = base::MakeUnique<base::ListValue>();
const std::vector<std::string>& accounts_in_token_service =
token_service->GetAccounts();
- if(accounts_in_token_service.size() == 0) {
- std::unique_ptr<base::DictionaryValue> no_token_entry(
- new base::DictionaryValue());
+ if (accounts_in_token_service.size() == 0) {
+ auto no_token_entry = base::MakeUnique<base::DictionaryValue>();
no_token_entry->SetString("accountId", "No token in Token Service.");
account_info->Append(std::move(no_token_entry));
}
- for(const std::string& account_id : accounts_in_token_service) {
- std::unique_ptr<base::DictionaryValue> entry(new base::DictionaryValue());
+ for (const std::string& account_id : accounts_in_token_service) {
+ auto entry = base::MakeUnique<base::DictionaryValue>();
entry->SetString("accountId", account_id);
account_info->Append(std::move(entry));
}
+ signin_status->Set("accountInfo", std::move(account_info));
return signin_status;
}
diff --git a/chromium/components/signin/core/browser/about_signin_internals.h b/chromium/components/signin/core/browser/about_signin_internals.h
index 8e42feab409..46d11da5fe1 100644
--- a/chromium/components/signin/core/browser/about_signin_internals.h
+++ b/chromium/components/signin/core/browser/about_signin_internals.h
@@ -191,8 +191,7 @@ class AboutSigninInternals
// SigninManagerBase::Observer implementations.
void GoogleSigninFailed(const GoogleServiceAuthError& error) override;
void GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) override;
+ const std::string& username) override;
void GoogleSignedOut(const std::string& account_id,
const std::string& username) override;
diff --git a/chromium/components/signin/core/browser/access_token_fetcher.cc b/chromium/components/signin/core/browser/access_token_fetcher.cc
index d301d3708da..de834072eed 100644
--- a/chromium/components/signin/core/browser/access_token_fetcher.cc
+++ b/chromium/components/signin/core/browser/access_token_fetcher.cc
@@ -76,8 +76,7 @@ void AccessTokenFetcher::StartAccessTokenRequest() {
}
void AccessTokenFetcher::GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) {
+ const std::string& username) {
DCHECK(waiting_for_sign_in_);
DCHECK(!waiting_for_refresh_token_);
DCHECK(signin_manager_->IsAuthenticated());
diff --git a/chromium/components/signin/core/browser/access_token_fetcher.h b/chromium/components/signin/core/browser/access_token_fetcher.h
index 2963ab8b797..cfa84724e48 100644
--- a/chromium/components/signin/core/browser/access_token_fetcher.h
+++ b/chromium/components/signin/core/browser/access_token_fetcher.h
@@ -51,8 +51,7 @@ class AccessTokenFetcher : public SigninManagerBase::Observer,
// SigninManagerBase::Observer implementation.
void GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) override;
+ const std::string& username) override;
void GoogleSigninFailed(const GoogleServiceAuthError& error) override;
// OAuth2TokenService::Observer implementation.
diff --git a/chromium/components/signin/core/browser/account_fetcher_service.cc b/chromium/components/signin/core/browser/account_fetcher_service.cc
index 7f25b2d377c..6203942dac4 100644
--- a/chromium/components/signin/core/browser/account_fetcher_service.cc
+++ b/chromium/components/signin/core/browser/account_fetcher_service.cc
@@ -65,6 +65,7 @@ AccountFetcherService::AccountFetcherService()
child_info_request_(nullptr) {}
AccountFetcherService::~AccountFetcherService() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(shutdown_called_);
}
@@ -142,7 +143,7 @@ void AccountFetcherService::RefreshAllAccountInfo(bool only_fetch_if_invalid) {
// account. This is possible since we only support a single account to be a
// child anyway.
void AccountFetcherService::UpdateChildInfo() {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
std::vector<std::string> accounts = token_service_->GetAccounts();
if (accounts.size() == 1) {
const std::string& candidate = accounts[0];
@@ -160,7 +161,7 @@ void AccountFetcherService::UpdateChildInfo() {
}
void AccountFetcherService::MaybeEnableNetworkFetches() {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!profile_loaded_ || !refresh_tokens_loaded_)
return;
if (!network_fetches_enabled_) {
@@ -199,7 +200,7 @@ void AccountFetcherService::ScheduleNextRefresh() {
// Starts fetching user information. This is called periodically to refresh.
void AccountFetcherService::StartFetchingUserInfo(
const std::string& account_id) {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(network_fetches_enabled_);
std::unique_ptr<AccountInfoFetcher>& request =
@@ -341,7 +342,7 @@ void AccountFetcherService::OnRefreshTokenRevoked(
}
void AccountFetcherService::OnRefreshTokensLoaded() {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
refresh_tokens_loaded_ = true;
MaybeEnableNetworkFetches();
}
diff --git a/chromium/components/signin/core/browser/account_fetcher_service.h b/chromium/components/signin/core/browser/account_fetcher_service.h
index 5ca34f1fc8a..aefdcdd3a92 100644
--- a/chromium/components/signin/core/browser/account_fetcher_service.h
+++ b/chromium/components/signin/core/browser/account_fetcher_service.h
@@ -11,7 +11,7 @@
#include <unordered_map>
#include "base/macros.h"
-#include "base/threading/non_thread_safe.h"
+#include "base/sequence_checker.h"
#include "base/timer/timer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "google_apis/gaia/oauth2_token_service.h"
@@ -32,8 +32,7 @@ class PrefRegistrySyncable;
}
class AccountFetcherService : public KeyedService,
- public OAuth2TokenService::Observer,
- public base::NonThreadSafe {
+ public OAuth2TokenService::Observer {
public:
// Name of the preference that tracks the int64_t representation of the last
// time the AccountTrackerService was updated.
@@ -139,6 +138,8 @@ class AccountFetcherService : public KeyedService,
std::unique_ptr<RefreshTokenAnnotationRequest>>
refresh_token_annotation_requests_;
+ SEQUENCE_CHECKER(sequence_checker_);
+
DISALLOW_COPY_AND_ASSIGN(AccountFetcherService);
};
diff --git a/chromium/components/signin/core/browser/account_reconcilor.cc b/chromium/components/signin/core/browser/account_reconcilor.cc
index 5a0170eb3f6..3393ef7333e 100644
--- a/chromium/components/signin/core/browser/account_reconcilor.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor.cc
@@ -222,8 +222,7 @@ void AccountReconcilor::OnEndBatchChanges() {
}
void AccountReconcilor::GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) {
+ const std::string& username) {
VLOG(1) << "AccountReconcilor::GoogleSigninSucceeded: signed in";
RegisterWithCookieManagerService();
RegisterWithContentSettings();
@@ -241,7 +240,7 @@ void AccountReconcilor::GoogleSignedOut(const std::string& account_id,
}
void AccountReconcilor::PerformMergeAction(const std::string& account_id) {
- if (!switches::IsEnableAccountConsistency()) {
+ if (!switches::IsAccountConsistencyMirrorEnabled()) {
MarkAccountAsAddedToCookie(account_id);
return;
}
@@ -250,7 +249,7 @@ void AccountReconcilor::PerformMergeAction(const std::string& account_id) {
}
void AccountReconcilor::PerformLogoutAllAccountsAction() {
- if (!switches::IsEnableAccountConsistency())
+ if (!switches::IsAccountConsistencyMirrorEnabled())
return;
VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction";
cookie_manager_service_->LogOutAllAccounts(kSource);
diff --git a/chromium/components/signin/core/browser/account_reconcilor.h b/chromium/components/signin/core/browser/account_reconcilor.h
index 6217588d974..285e6f51cf1 100644
--- a/chromium/components/signin/core/browser/account_reconcilor.h
+++ b/chromium/components/signin/core/browser/account_reconcilor.h
@@ -151,8 +151,7 @@ class AccountReconcilor : public KeyedService,
// Overriden from SigninManagerBase::Observer.
void GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) override;
+ const std::string& username) override;
void GoogleSignedOut(const std::string& account_id,
const std::string& username) override;
diff --git a/chromium/components/signin/core/browser/account_tracker_service.cc b/chromium/components/signin/core/browser/account_tracker_service.cc
index 129b124288c..dc4dba0b394 100644
--- a/chromium/components/signin/core/browser/account_tracker_service.cc
+++ b/chromium/components/signin/core/browser/account_tracker_service.cc
@@ -60,6 +60,7 @@ const char AccountTrackerService::kNoPictureURLFound[] = "NO_PICTURE_URL";
AccountTrackerService::AccountTrackerService() : signin_client_(nullptr) {}
AccountTrackerService::~AccountTrackerService() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
// static
diff --git a/chromium/components/signin/core/browser/account_tracker_service.h b/chromium/components/signin/core/browser/account_tracker_service.h
index b92e0a9515d..cc4035c4db4 100644
--- a/chromium/components/signin/core/browser/account_tracker_service.h
+++ b/chromium/components/signin/core/browser/account_tracker_service.h
@@ -13,13 +13,12 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
-#include "base/threading/non_thread_safe.h"
+#include "base/sequence_checker.h"
#include "base/timer/timer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/core/browser/account_info.h"
#include "google_apis/gaia/gaia_auth_util.h"
-
class PrefService;
class SigninClient;
@@ -33,8 +32,7 @@ class PrefRegistrySyncable;
// AccountTrackerService is a KeyedService that retrieves and caches GAIA
// information about Google Accounts.
-class AccountTrackerService : public KeyedService,
- public base::NonThreadSafe {
+class AccountTrackerService : public KeyedService {
public:
// Name of the preference property that persists the account information
// tracked by this service.
@@ -157,6 +155,8 @@ class AccountTrackerService : public KeyedService,
std::map<std::string, AccountState> accounts_;
base::ObserverList<Observer> observer_list_;
+ SEQUENCE_CHECKER(sequence_checker_);
+
DISALLOW_COPY_AND_ASSIGN(AccountTrackerService);
};
diff --git a/chromium/components/signin/core/browser/android/BUILD.gn b/chromium/components/signin/core/browser/android/BUILD.gn
index f9f482b6a91..d7d0c958299 100644
--- a/chromium/components/signin/core/browser/android/BUILD.gn
+++ b/chromium/components/signin/core/browser/android/BUILD.gn
@@ -21,10 +21,13 @@ android_library("java") {
java_files = [
"java/src/org/chromium/components/signin/AccountManagerDelegate.java",
+ "java/src/org/chromium/components/signin/AccountManagerFacade.java",
"java/src/org/chromium/components/signin/AccountManagerHelper.java",
+ "java/src/org/chromium/components/signin/AccountsChangeObserver.java",
"java/src/org/chromium/components/signin/AuthException.java",
"java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java",
"java/src/org/chromium/components/signin/ChromeSigninController.java",
+ "java/src/org/chromium/components/signin/AccountManagerDelegateException.java",
"java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java",
]
}
@@ -39,7 +42,7 @@ android_library("javatests") {
"//third_party/android_support_test_runner:runner_java",
]
- java_files = [ "javatests/src/org/chromium/components/signin/test/AccountManagerHelperTest.java" ]
+ java_files = [ "javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java" ]
}
android_library("signin_java_test_support") {
@@ -50,6 +53,7 @@ android_library("signin_java_test_support") {
"//base:base_java_test_support",
"//third_party/android_tools:android_support_annotations_java",
"//third_party/jsr-305:jsr_305_javalib",
+ "//third_party/junit",
]
java_files = [
diff --git a/chromium/components/signin/core/browser/child_account_info_fetcher_android.cc b/chromium/components/signin/core/browser/child_account_info_fetcher_android.cc
index 34446dad77e..2fbdd2a0076 100644
--- a/chromium/components/signin/core/browser/child_account_info_fetcher_android.cc
+++ b/chromium/components/signin/core/browser/child_account_info_fetcher_android.cc
@@ -50,11 +50,6 @@ ChildAccountInfoFetcherAndroid::~ChildAccountInfoFetcherAndroid() {
j_child_account_info_fetcher_.obj());
}
-// static
-bool ChildAccountInfoFetcherAndroid::Register(JNIEnv* env) {
- return RegisterNativesImpl(env);
-}
-
void SetIsChildAccount(JNIEnv* env,
const JavaParamRef<jclass>& caller,
jlong native_service,
diff --git a/chromium/components/signin/core/browser/child_account_info_fetcher_android.h b/chromium/components/signin/core/browser/child_account_info_fetcher_android.h
index 05f30a177fc..aee7ed9a473 100644
--- a/chromium/components/signin/core/browser/child_account_info_fetcher_android.h
+++ b/chromium/components/signin/core/browser/child_account_info_fetcher_android.h
@@ -22,9 +22,6 @@ class ChildAccountInfoFetcherAndroid : public ChildAccountInfoFetcher {
static void InitializeForTests();
- // Register JNI methods.
- static bool Register(JNIEnv* env);
-
private:
ChildAccountInfoFetcherAndroid(AccountFetcherService* service,
const std::string& account_id,
diff --git a/chromium/components/signin/core/browser/chrome_connected_header_helper.cc b/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
new file mode 100644
index 00000000000..12486b67317
--- /dev/null
+++ b/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
@@ -0,0 +1,171 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/signin/core/browser/chrome_connected_header_helper.h"
+
+#include <vector>
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "components/google/core/browser/google_util.h"
+#include "components/signin/core/common/profile_management_switches.h"
+#include "google_apis/gaia/gaia_auth_util.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "url/gurl.h"
+
+namespace signin {
+
+namespace {
+
+const char kContinueUrlAttrName[] = "continue_url";
+const char kEmailAttrName[] = "email";
+const char kEnableAccountConsistencyAttrName[] = "enable_account_consistency";
+const char kGaiaIdAttrName[] = "id";
+const char kIsSameTabAttrName[] = "is_same_tab";
+const char kIsSamlAttrName[] = "is_saml";
+const char kProfileModeAttrName[] = "mode";
+const char kServiceTypeAttrName[] = "action";
+
+// Determines the service type that has been passed from Gaia in the header.
+GAIAServiceType GetGAIAServiceTypeFromHeader(const std::string& header_value) {
+ if (header_value == "SIGNOUT")
+ return GAIA_SERVICE_TYPE_SIGNOUT;
+ else if (header_value == "INCOGNITO")
+ return GAIA_SERVICE_TYPE_INCOGNITO;
+ else if (header_value == "ADDSESSION")
+ return GAIA_SERVICE_TYPE_ADDSESSION;
+ else if (header_value == "REAUTH")
+ return GAIA_SERVICE_TYPE_REAUTH;
+ else if (header_value == "SIGNUP")
+ return GAIA_SERVICE_TYPE_SIGNUP;
+ else if (header_value == "DEFAULT")
+ return GAIA_SERVICE_TYPE_DEFAULT;
+ else
+ return GAIA_SERVICE_TYPE_NONE;
+}
+
+} // namespace
+
+// static
+std::string ChromeConnectedHeaderHelper::BuildRequestCookieIfPossible(
+ const GURL& url,
+ const std::string& account_id,
+ const content_settings::CookieSettings* cookie_settings,
+ int profile_mode_mask) {
+ ChromeConnectedHeaderHelper chrome_connected_helper;
+ if (!chrome_connected_helper.ShouldBuildRequestHeader(url, cookie_settings))
+ return "";
+ return chrome_connected_helper.BuildRequestHeader(
+ false /* is_header_request */, url, account_id, profile_mode_mask);
+}
+
+// static
+ManageAccountsParams ChromeConnectedHeaderHelper::BuildManageAccountsParams(
+ const std::string& header_value) {
+ DCHECK(!header_value.empty());
+ ManageAccountsParams params;
+ ResponseHeaderDictionary header_dictionary =
+ ParseAccountConsistencyResponseHeader(header_value);
+ ResponseHeaderDictionary::const_iterator it = header_dictionary.begin();
+ for (; it != header_dictionary.end(); ++it) {
+ const std::string key_name(it->first);
+ const std::string value(it->second);
+ if (key_name == kServiceTypeAttrName) {
+ params.service_type = GetGAIAServiceTypeFromHeader(value);
+ } else if (key_name == kEmailAttrName) {
+ params.email = value;
+ } else if (key_name == kIsSamlAttrName) {
+ params.is_saml = value == "true";
+ } else if (key_name == kContinueUrlAttrName) {
+ params.continue_url = value;
+ } else if (key_name == kIsSameTabAttrName) {
+ params.is_same_tab = value == "true";
+ } else {
+ DLOG(WARNING) << "Unexpected Gaia header attribute '" << key_name << "'.";
+ }
+ }
+ return params;
+}
+
+bool ChromeConnectedHeaderHelper::IsUrlEligibleToIncludeGaiaId(
+ const GURL& url,
+ bool is_header_request) {
+ if (is_header_request) {
+ // Gaia ID is only necessary for Drive. Don't set it otherwise.
+ return IsDriveOrigin(url.GetOrigin());
+ }
+
+ // Cookie requests don't have the granularity to only include the Gaia ID for
+ // Drive origin. Set it on all google.com instead.
+ if (!url.SchemeIsCryptographic())
+ return false;
+
+ const std::string kGoogleDomain = "google.com";
+ std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
+ url, net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
+ return domain == kGoogleDomain;
+}
+
+bool ChromeConnectedHeaderHelper::IsDriveOrigin(const GURL& url) {
+ if (!url.SchemeIsCryptographic())
+ return false;
+
+ const GURL kGoogleDriveURL("https://drive.google.com");
+ const GURL kGoogleDocsURL("https://docs.google.com");
+ return url == kGoogleDriveURL || url == kGoogleDocsURL;
+}
+
+bool ChromeConnectedHeaderHelper::IsUrlEligibleForRequestHeader(
+ const GURL& url) {
+ // Only set the header for Drive and Gaia always, and other Google properties
+ // if account consistency is enabled. Vasquette, which is integrated with most
+ // Google properties, needs the header to redirect certain user actions to
+ // Chrome native UI. Drive and Gaia need the header to tell if the current
+ // user is connected.
+
+ // Consider the account ID sensitive and limit it to secure domains.
+ if (!url.SchemeIsCryptographic())
+ return false;
+
+ GURL origin(url.GetOrigin());
+ bool is_enable_account_consistency =
+ switches::IsAccountConsistencyMirrorEnabled();
+ bool is_google_url = is_enable_account_consistency &&
+ (google_util::IsGoogleDomainUrl(
+ url, google_util::ALLOW_SUBDOMAIN,
+ google_util::DISALLOW_NON_STANDARD_PORTS) ||
+ google_util::IsYoutubeDomainUrl(
+ url, google_util::ALLOW_SUBDOMAIN,
+ google_util::DISALLOW_NON_STANDARD_PORTS));
+ return is_google_url || IsDriveOrigin(origin) ||
+ gaia::IsGaiaSignonRealm(origin);
+}
+
+std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
+ bool is_header_request,
+ const GURL& url,
+ const std::string& account_id,
+ int profile_mode_mask) {
+ if (account_id.empty())
+ return std::string();
+
+ std::vector<std::string> parts;
+ if (IsUrlEligibleToIncludeGaiaId(url, is_header_request)) {
+ // Only set the Gaia ID on domains that actually requires it.
+ parts.push_back(
+ base::StringPrintf("%s=%s", kGaiaIdAttrName, account_id.c_str()));
+ }
+ parts.push_back(
+ base::StringPrintf("%s=%s", kProfileModeAttrName,
+ base::IntToString(profile_mode_mask).c_str()));
+ parts.push_back(base::StringPrintf(
+ "%s=%s", kEnableAccountConsistencyAttrName,
+ switches::IsAccountConsistencyMirrorEnabled() ? "true" : "false"));
+
+ return base::JoinString(parts, is_header_request ? "," : ":");
+}
+
+} // namespace signin
diff --git a/chromium/components/signin/core/browser/chrome_connected_header_helper.h b/chromium/components/signin/core/browser/chrome_connected_header_helper.h
new file mode 100644
index 00000000000..72ea404e3e0
--- /dev/null
+++ b/chromium/components/signin/core/browser/chrome_connected_header_helper.h
@@ -0,0 +1,55 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_CHROME_CONNECTED_HEADER_HELPER_H_
+#define COMPONENTS_SIGNIN_CORE_BROWSER_CHROME_CONNECTED_HEADER_HELPER_H_
+
+#include <string>
+
+#include "components/signin/core/browser/signin_header_helper.h"
+
+class GURL;
+
+namespace signin {
+
+// SigninHeaderHelper implementation managing the "X-Chrome-Connected" header.
+class ChromeConnectedHeaderHelper : public SigninHeaderHelper {
+ public:
+ ChromeConnectedHeaderHelper() {}
+ ~ChromeConnectedHeaderHelper() override {}
+
+ // Returns the Chrome-Connected cookie, or an empty string if it should not be
+ // added to the request to |url|.
+ static std::string BuildRequestCookieIfPossible(
+ const GURL& url,
+ const std::string& account_id,
+ const content_settings::CookieSettings* cookie_settings,
+ int profile_mode_mask);
+
+ // Returns the parameters contained in the X-Chrome-Manage-Accounts response
+ // header.
+ static ManageAccountsParams BuildManageAccountsParams(
+ const std::string& header_value);
+
+ // Returns the value for the Chrome-Connected request header. May return the
+ // empty string, in this case the header must not be added.
+ std::string BuildRequestHeader(bool is_header_request,
+ const GURL& url,
+ const std::string& account_id,
+ int profile_mode_mask);
+
+ private:
+ // Returns whether the URL is eligible for the Gaia ID parameter.
+ bool IsUrlEligibleToIncludeGaiaId(const GURL& url, bool is_header_request);
+
+ // Returns whether the URL has a Google Drive origin.
+ bool IsDriveOrigin(const GURL& url);
+
+ // SigninHeaderHelper implementation:
+ bool IsUrlEligibleForRequestHeader(const GURL& url) override;
+};
+
+} // namespace signin
+
+#endif // COMPONENTS_SIGNIN_CORE_BROWSER_CHROME_CONNECTED_HEADER_HELPER_H_
diff --git a/chromium/components/signin/core/browser/dice_header_helper.cc b/chromium/components/signin/core/browser/dice_header_helper.cc
new file mode 100644
index 00000000000..4d8aade04f2
--- /dev/null
+++ b/chromium/components/signin/core/browser/dice_header_helper.cc
@@ -0,0 +1,147 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/signin/core/browser/dice_header_helper.h"
+
+#include <vector>
+
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "components/signin/core/common/profile_management_switches.h"
+#include "google_apis/gaia/gaia_auth_util.h"
+#include "google_apis/gaia/gaia_urls.h"
+
+namespace signin {
+
+namespace {
+
+const char kSigninActionAttrName[] = "action";
+const char kSigninAuthUserAttrName[] = "authuser";
+const char kSigninAuthorizationCodeAttrName[] = "authorization_code";
+const char kSigninEmailAttrName[] = "email";
+const char kSigninIdAttrName[] = "id";
+const char kSignoutEmailAttrName[] = "email";
+const char kSignoutSessionIndexAttrName[] = "sessionindex";
+const char kSignoutObfuscatedIDAttrName[] = "obfuscatedid";
+
+// Determines the Dice action that has been passed from Gaia in the header.
+DiceAction GetDiceActionFromHeader(const std::string& value) {
+ if (value == "SIGNIN")
+ return DiceAction::SIGNIN;
+ else if (value == "SIGNOUT")
+ return DiceAction::SIGNOUT;
+ else
+ return DiceAction::NONE;
+}
+
+} // namespace
+
+// static
+DiceResponseParams DiceHeaderHelper::BuildDiceSigninResponseParams(
+ const std::string& header_value) {
+ DCHECK(!header_value.empty());
+ DiceResponseParams params;
+ DiceResponseParams::SigninInfo& info = params.signin_info;
+ ResponseHeaderDictionary header_dictionary =
+ ParseAccountConsistencyResponseHeader(header_value);
+ ResponseHeaderDictionary::const_iterator it = header_dictionary.begin();
+ for (; it != header_dictionary.end(); ++it) {
+ const std::string key_name(it->first);
+ const std::string value(it->second);
+ if (key_name == kSigninActionAttrName) {
+ params.user_intention = GetDiceActionFromHeader(value);
+ } else if (key_name == kSigninIdAttrName) {
+ info.gaia_id = value;
+ } else if (key_name == kSigninEmailAttrName) {
+ info.email = value;
+ } else if (key_name == kSigninAuthUserAttrName) {
+ bool parse_success = base::StringToInt(value, &info.session_index);
+ if (!parse_success)
+ info.session_index = -1;
+ } else if (key_name == kSigninAuthorizationCodeAttrName) {
+ info.authorization_code = value;
+ } else {
+ DLOG(WARNING) << "Unexpected Gaia header attribute '" << key_name << "'.";
+ }
+ }
+
+ if (params.user_intention != DiceAction::SIGNIN) {
+ DLOG(WARNING)
+ << "Only SIGNIN is supported through X-Chrome-ID-Consistency-Response :"
+ << header_value;
+ params.user_intention = DiceAction::NONE;
+ }
+
+ if (info.gaia_id.empty() || info.email.empty() || info.session_index == -1 ||
+ info.authorization_code.empty()) {
+ DLOG(WARNING) << "Missing header parameters for Dice SIGNIN: "
+ << header_value;
+ params.user_intention = DiceAction::NONE;
+ }
+
+ return params;
+}
+
+// static
+DiceResponseParams DiceHeaderHelper::BuildDiceSignoutResponseParams(
+ const std::string& header_value) {
+ // Google internal documentation of this header at:
+ // http://go/gaia-response-headers
+ DCHECK(!header_value.empty());
+ DiceResponseParams params;
+ params.user_intention = DiceAction::SIGNOUT;
+ DiceResponseParams::SignoutInfo& info = params.signout_info;
+ ResponseHeaderDictionary header_dictionary =
+ ParseAccountConsistencyResponseHeader(header_value);
+ ResponseHeaderDictionary::const_iterator it = header_dictionary.begin();
+ for (; it != header_dictionary.end(); ++it) {
+ const std::string key_name(it->first);
+ const std::string value(it->second);
+ if (key_name == kSignoutObfuscatedIDAttrName) {
+ info.gaia_id.push_back(value);
+ // The Gaia ID is wrapped in quotes.
+ base::TrimString(value, "\"", &info.gaia_id.back());
+ } else if (key_name == kSignoutEmailAttrName) {
+ // The email is wrapped in quotes.
+ info.email.push_back(value);
+ base::TrimString(value, "\"", &info.email.back());
+ } else if (key_name == kSignoutSessionIndexAttrName) {
+ int session_index = -1;
+ bool parse_success = base::StringToInt(value, &session_index);
+ if (parse_success)
+ info.session_index.push_back(session_index);
+ } else {
+ DLOG(WARNING) << "Unexpected Gaia header attribute '" << key_name << "'.";
+ }
+ }
+
+ if ((info.gaia_id.size() != info.email.size()) ||
+ (info.gaia_id.size() != info.session_index.size())) {
+ DLOG(WARNING) << "Invalid parameter count for Dice SIGNOUT header: "
+ << header_value;
+ params.user_intention = DiceAction::NONE;
+ }
+
+ return params;
+}
+
+bool DiceHeaderHelper::IsUrlEligibleForRequestHeader(const GURL& url) {
+ if (switches::GetAccountConsistencyMethod() !=
+ switches::AccountConsistencyMethod::kDice) {
+ return false;
+ }
+ return gaia::IsGaiaSignonRealm(url.GetOrigin());
+}
+
+std::string DiceHeaderHelper::BuildRequestHeader(const std::string& account_id,
+ bool sync_enabled) {
+ std::vector<std::string> parts;
+ parts.push_back("client_id=" +
+ GaiaUrls::GetInstance()->oauth2_chrome_client_id());
+ if (sync_enabled)
+ parts.push_back("sync_account_id=" + account_id);
+ return base::JoinString(parts, ",");
+}
+
+} // namespace signin
diff --git a/chromium/components/signin/core/browser/dice_header_helper.h b/chromium/components/signin/core/browser/dice_header_helper.h
new file mode 100644
index 00000000000..d83fa037693
--- /dev/null
+++ b/chromium/components/signin/core/browser/dice_header_helper.h
@@ -0,0 +1,44 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_DICE_HEADER_HELPER_H_
+#define COMPONENTS_SIGNIN_CORE_BROWSER_DICE_HEADER_HELPER_H_
+
+#include <string>
+
+#include "components/signin/core/browser/signin_header_helper.h"
+
+class GURL;
+
+namespace signin {
+
+// SigninHeaderHelper implementation managing the Dice header.
+class DiceHeaderHelper : public SigninHeaderHelper {
+ public:
+ DiceHeaderHelper() {}
+ ~DiceHeaderHelper() override {}
+
+ // Returns the parameters contained in the X-Chrome-ID-Consistency-Response
+ // response header.
+ static DiceResponseParams BuildDiceSigninResponseParams(
+ const std::string& header_value);
+
+ // Returns the parameters contained in the Google-Accounts-SignOut response
+ // header.
+ static DiceResponseParams BuildDiceSignoutResponseParams(
+ const std::string& header_value);
+
+ // Returns the header value for Dice requests. Returns the empty string when
+ // the header must not be added.
+ std::string BuildRequestHeader(const std::string& account_id,
+ bool sync_enabled);
+
+ private:
+ // SigninHeaderHelper implementation:
+ bool IsUrlEligibleForRequestHeader(const GURL& url) override;
+};
+
+} // namespace signin
+
+#endif // COMPONENTS_SIGNIN_CORE_BROWSER_DICE_HEADER_HELPER_H_
diff --git a/chromium/components/signin/core/browser/fake_signin_manager.cc b/chromium/components/signin/core/browser/fake_signin_manager.cc
index 32caba99d7b..104d8ea429c 100644
--- a/chromium/components/signin/core/browser/fake_signin_manager.cc
+++ b/chromium/components/signin/core/browser/fake_signin_manager.cc
@@ -31,7 +31,8 @@ FakeSigninManager::FakeSigninManager(
: SigninManager(client,
token_service,
account_tracker_service,
- cookie_manager_service) {}
+ cookie_manager_service),
+ token_service_(token_service) {}
FakeSigninManager::~FakeSigninManager() {}
@@ -57,8 +58,9 @@ void FakeSigninManager::CompletePendingSignin() {
SetAuthenticatedAccountId(GetAccountIdForAuthInProgress());
set_auth_in_progress(std::string());
for (auto& observer : observer_list_) {
- observer.GoogleSigninSucceeded(authenticated_account_id_, username_,
- password_);
+ observer.GoogleSigninSucceeded(authenticated_account_id_, username_);
+ observer.GoogleSigninSucceededWithPassword(authenticated_account_id_,
+ username_, password_);
}
}
@@ -91,6 +93,8 @@ void FakeSigninManager::SignOut(
const std::string account_id = GetAuthenticatedAccountId();
const std::string username = GetAuthenticatedAccountInfo().email;
authenticated_account_id_.clear();
+ if (token_service_)
+ token_service_->RevokeAllCredentials();
for (auto& observer : observer_list_)
observer.GoogleSignedOut(account_id, username);
diff --git a/chromium/components/signin/core/browser/fake_signin_manager.h b/chromium/components/signin/core/browser/fake_signin_manager.h
index 5ba63b81e53..b3943e0f256 100644
--- a/chromium/components/signin/core/browser/fake_signin_manager.h
+++ b/chromium/components/signin/core/browser/fake_signin_manager.h
@@ -13,9 +13,7 @@
#include "components/signin/core/browser/signin_manager.h"
#include "components/signin/core/browser/signin_metrics.h"
-// SigninManager to use for testing. Tests should use the type
-// SigninManagerForTesting to ensure that the right type for their platform is
-// used.
+// SigninManager to use for testing.
class FakeSigninManagerBase : public SigninManagerBase {
public:
@@ -44,7 +42,7 @@ class FakeSigninManager : public SigninManager {
void set_password(const std::string& password) { password_ = password; }
- void SignIn(const std::string& account_id,
+ void SignIn(const std::string& gaia_id,
const std::string& username,
const std::string& password);
@@ -66,6 +64,8 @@ class FakeSigninManager : public SigninManager {
// Username specified in StartSignInWithRefreshToken() call.
std::string username_;
+
+ ProfileOAuth2TokenService* token_service_;
};
#endif // !defined (OS_CHROMEOS)
diff --git a/chromium/components/signin/core/browser/profile_identity_provider.cc b/chromium/components/signin/core/browser/profile_identity_provider.cc
index 3be796e2d64..a537d4b718a 100644
--- a/chromium/components/signin/core/browser/profile_identity_provider.cc
+++ b/chromium/components/signin/core/browser/profile_identity_provider.cc
@@ -42,8 +42,7 @@ bool ProfileIdentityProvider::RequestLogin() {
void ProfileIdentityProvider::GoogleSigninSucceeded(
const std::string& account_id,
- const std::string& username,
- const std::string& password) {
+ const std::string& username) {
FireOnActiveAccountLogin();
}
diff --git a/chromium/components/signin/core/browser/profile_identity_provider.h b/chromium/components/signin/core/browser/profile_identity_provider.h
index ca3e1a590a3..eef7e346787 100644
--- a/chromium/components/signin/core/browser/profile_identity_provider.h
+++ b/chromium/components/signin/core/browser/profile_identity_provider.h
@@ -32,8 +32,7 @@ class ProfileIdentityProvider : public IdentityProvider,
// SigninManagerBase::Observer:
void GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) override;
+ const std::string& username) override;
void GoogleSignedOut(const std::string& account_id,
const std::string& username) override;
diff --git a/chromium/components/signin/core/browser/profile_oauth2_token_service.cc b/chromium/components/signin/core/browser/profile_oauth2_token_service.cc
index 7e8eb2a22c9..8cf2fd90b28 100644
--- a/chromium/components/signin/core/browser/profile_oauth2_token_service.cc
+++ b/chromium/components/signin/core/browser/profile_oauth2_token_service.cc
@@ -6,7 +6,7 @@
ProfileOAuth2TokenService::ProfileOAuth2TokenService(
std::unique_ptr<OAuth2TokenServiceDelegate> delegate)
- : OAuth2TokenService(std::move(delegate)) {
+ : OAuth2TokenService(std::move(delegate)), all_credentials_loaded_(false) {
AddObserver(this);
}
@@ -24,6 +24,10 @@ void ProfileOAuth2TokenService::LoadCredentials(
GetDelegate()->LoadCredentials(primary_account_id);
}
+bool ProfileOAuth2TokenService::AreAllCredentialsLoaded() {
+ return all_credentials_loaded_;
+}
+
void ProfileOAuth2TokenService::UpdateCredentials(
const std::string& account_id,
const std::string& refresh_token) {
@@ -50,3 +54,7 @@ void ProfileOAuth2TokenService::OnRefreshTokenRevoked(
CancelRequestsForAccount(account_id);
ClearCacheForAccount(account_id);
}
+
+void ProfileOAuth2TokenService::OnRefreshTokensLoaded() {
+ all_credentials_loaded_ = true;
+}
diff --git a/chromium/components/signin/core/browser/profile_oauth2_token_service.h b/chromium/components/signin/core/browser/profile_oauth2_token_service.h
index fadf1417bd1..3372a924c99 100644
--- a/chromium/components/signin/core/browser/profile_oauth2_token_service.h
+++ b/chromium/components/signin/core/browser/profile_oauth2_token_service.h
@@ -42,13 +42,13 @@ class ProfileOAuth2TokenService : public OAuth2TokenService,
// Loads credentials from a backing persistent store to make them available
// after service is used between profile restarts.
//
- // Only call this method if there is at least one account connected to the
- // profile, otherwise startup will cause unneeded work on the IO thread. The
- // primary account is specified with the |primary_account_id| argument. If
- // empty, no credentials will be loaded. For a regular profile, the primary
- // account id comes from SigninManager. For a supervised user, the id comes
- // from SupervisedUserService.
- virtual void LoadCredentials(const std::string& primary_account_id);
+ // The primary account is specified with the |primary_account_id| argument.
+ // For a regular profile, the primary account id comes from SigninManager.
+ // For a supervised user, the id comes from SupervisedUserService.
+ void LoadCredentials(const std::string& primary_account_id);
+
+ // Returns true iff all credentials have been loaded from disk.
+ bool AreAllCredentialsLoaded();
// Updates a |refresh_token| for an |account_id|. Credentials are persisted,
// and available through |LoadCredentials| after service is restarted.
@@ -64,6 +64,10 @@ class ProfileOAuth2TokenService : public OAuth2TokenService,
private:
void OnRefreshTokenAvailable(const std::string& account_id) override;
void OnRefreshTokenRevoked(const std::string& account_id) override;
+ void OnRefreshTokensLoaded() override;
+
+ // Whether all credentials have been loaded.
+ bool all_credentials_loaded_;
DISALLOW_COPY_AND_ASSIGN(ProfileOAuth2TokenService);
};
diff --git a/chromium/components/signin/core/browser/refresh_token_annotation_request.cc b/chromium/components/signin/core/browser/refresh_token_annotation_request.cc
index 191dab8ebf4..15c43148f56 100644
--- a/chromium/components/signin/core/browser/refresh_token_annotation_request.cc
+++ b/chromium/components/signin/core/browser/refresh_token_annotation_request.cc
@@ -17,6 +17,7 @@
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/base/escape.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_context_getter.h"
namespace {
@@ -41,7 +42,7 @@ RefreshTokenAnnotationRequest::RefreshTokenAnnotationRequest(
}
RefreshTokenAnnotationRequest::~RefreshTokenAnnotationRequest() {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
// static
@@ -102,7 +103,7 @@ bool RefreshTokenAnnotationRequest::ShouldSendNow(PrefService* pref_service) {
void RefreshTokenAnnotationRequest::RequestAccessToken(
OAuth2TokenService* token_service,
const std::string& account_id) {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
OAuth2TokenService::ScopeSet scopes;
scopes.insert(GaiaConstants::kOAuth1LoginScope);
access_token_request_ = token_service->StartRequest(account_id, scopes, this);
@@ -112,7 +113,7 @@ void RefreshTokenAnnotationRequest::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(2) << "Got access token";
Start(request_context_getter_.get(), access_token);
}
@@ -120,7 +121,7 @@ void RefreshTokenAnnotationRequest::OnGetTokenSuccess(
void RefreshTokenAnnotationRequest::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(2) << "Failed to get access token";
RecordRequestStatusHistogram(false);
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, request_callback_);
@@ -156,7 +157,7 @@ std::string RefreshTokenAnnotationRequest::CreateApiCallBody() {
void RefreshTokenAnnotationRequest::ProcessApiCallSuccess(
const net::URLFetcher* source) {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(2) << "Request succeeded";
RecordRequestStatusHistogram(true);
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, request_callback_);
@@ -165,9 +166,40 @@ void RefreshTokenAnnotationRequest::ProcessApiCallSuccess(
void RefreshTokenAnnotationRequest::ProcessApiCallFailure(
const net::URLFetcher* source) {
- DCHECK(CalledOnValidThread());
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(2) << "Request failed";
RecordRequestStatusHistogram(false);
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, request_callback_);
request_callback_.Reset();
}
+
+net::PartialNetworkTrafficAnnotationTag
+RefreshTokenAnnotationRequest::GetNetworkTrafficAnnotationTag() {
+ return net::DefinePartialNetworkTrafficAnnotation(
+ "refresh_token_annotation_request", "oauth2_api_call_flow", R"(
+ semantics {
+ sender: "Account Fetcher Service"
+ description:
+ "Sends request to /IssueToken endpoint with device_id to backfill "
+ "device info for refresh tokens issued pre-M38."
+ trigger:
+ "When refreshing account information in AccountFetcherService. On "
+ "chrome startup and at most once per day."
+ data:
+ "OAuth 2.0 access token, Chrome's client id and version number, and "
+ "a single signin scoped, randomly generated device id for Chrome "
+ "profile."
+ destination: GOOGLE_OWNED_SERVICE
+ }
+ policy {
+ setting:
+ "This feature cannot be disabled by settings, however the request is "
+ "made only for signed-in users."
+ chrome_policy {
+ SigninAllowed {
+ policy_options {mode: MANDATORY}
+ SigninAllowed: false
+ }
+ }
+ })");
+}
diff --git a/chromium/components/signin/core/browser/refresh_token_annotation_request.h b/chromium/components/signin/core/browser/refresh_token_annotation_request.h
index 483830bfea4..2e0868c43ca 100644
--- a/chromium/components/signin/core/browser/refresh_token_annotation_request.h
+++ b/chromium/components/signin/core/browser/refresh_token_annotation_request.h
@@ -10,7 +10,7 @@
#include "base/callback.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
-#include "base/threading/non_thread_safe.h"
+#include "base/sequence_checker.h"
#include "google_apis/gaia/oauth2_api_call_flow.h"
#include "google_apis/gaia/oauth2_token_service.h"
@@ -22,8 +22,7 @@ class SigninClient;
// important to keep server QPS low therefore this request is sent on average
// once per 10 days per profile.
// This code shold be removed once majority of refresh tokens are updated.
-class RefreshTokenAnnotationRequest : public base::NonThreadSafe,
- public OAuth2TokenService::Consumer,
+class RefreshTokenAnnotationRequest : public OAuth2TokenService::Consumer,
public OAuth2ApiCallFlow {
public:
~RefreshTokenAnnotationRequest() override;
@@ -59,6 +58,8 @@ class RefreshTokenAnnotationRequest : public base::NonThreadSafe,
std::string CreateApiCallBody() override;
void ProcessApiCallSuccess(const net::URLFetcher* source) override;
void ProcessApiCallFailure(const net::URLFetcher* source) override;
+ net::PartialNetworkTrafficAnnotationTag GetNetworkTrafficAnnotationTag()
+ override;
private:
FRIEND_TEST_ALL_PREFIXES(RefreshTokenAnnotationRequestTest, ShouldSendNow);
@@ -84,6 +85,8 @@ class RefreshTokenAnnotationRequest : public base::NonThreadSafe,
std::unique_ptr<OAuth2TokenService::Request> access_token_request_;
+ SEQUENCE_CHECKER(sequence_checker_);
+
DISALLOW_COPY_AND_ASSIGN(RefreshTokenAnnotationRequest);
};
diff --git a/chromium/components/signin/core/browser/resources/signin_index.html b/chromium/components/signin/core/browser/resources/signin_index.html
index 7965ffe6e38..513a934658d 100644
--- a/chromium/components/signin/core/browser/resources/signin_index.html
+++ b/chromium/components/signin/core/browser/resources/signin_index.html
@@ -1,5 +1,5 @@
<!doctype html>
-<html i18n-values="dir:textdirection;lang:language">
+<html dir="$i18n{textdirection}" lang="$i18n{language}">
<head>
<meta charset="utf-8">
<title>Signin Internals</title>
diff --git a/chromium/components/signin/core/browser/signin_header_helper.cc b/chromium/components/signin/core/browser/signin_header_helper.cc
index 668d25d4492..0a326c1f807 100644
--- a/chromium/components/signin/core/browser/signin_header_helper.cc
+++ b/chromium/components/signin/core/browser/signin_header_helper.cc
@@ -6,143 +6,26 @@
#include <stddef.h>
+#include "base/logging.h"
#include "base/macros.h"
-#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "build/build_config.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/google/core/browser/google_util.h"
+#include "components/signin/core/browser/chrome_connected_header_helper.h"
#include "components/signin/core/common/profile_management_switches.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/base/escape.h"
-#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
-#include "url/gurl.h"
-namespace {
-
-// Dictionary of fields in a mirror response header.
-typedef std::map<std::string, std::string> MirrorResponseHeaderDictionary;
-
-const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts";
-const char kContinueUrlAttrName[] = "continue_url";
-const char kEmailAttrName[] = "email";
-const char kEnableAccountConsistencyAttrName[] = "enable_account_consistency";
-const char kGaiaIdAttrName[] = "id";
-const char kProfileModeAttrName[] = "mode";
-const char kIsSameTabAttrName[] = "is_same_tab";
-const char kIsSamlAttrName[] = "is_saml";
-const char kServiceTypeAttrName[] = "action";
-
-bool IsDriveOrigin(const GURL& url) {
- if (!url.SchemeIsCryptographic())
- return false;
-
- const GURL kGoogleDriveURL("https://drive.google.com");
- const GURL kGoogleDocsURL("https://docs.google.com");
- return url == kGoogleDriveURL || url == kGoogleDocsURL;
-}
-
-bool IsUrlEligibleToIncludeGaiaId(const GURL& url, bool is_header_request) {
- if (is_header_request) {
- // GAIA Id is only necessary for Drive. Don't set it otherwise.
- return IsDriveOrigin(url.GetOrigin());
- }
-
- // Cookie requests don't have the granularity to only include the GAIA Id for
- // Drive origin. Set it on all google.com instead.
- if (!url.SchemeIsCryptographic())
- return false;
-
- const std::string kGoogleDomain = "google.com";
- std::string domain = net::registry_controlled_domains::GetDomainAndRegistry(
- url, net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
- return domain == kGoogleDomain;
-}
-
-// Determines the service type that has been passed from GAIA in the header.
-signin::GAIAServiceType GetGAIAServiceTypeFromHeader(
- const std::string& header_value) {
- if (header_value == "SIGNOUT")
- return signin::GAIA_SERVICE_TYPE_SIGNOUT;
- else if (header_value == "INCOGNITO")
- return signin::GAIA_SERVICE_TYPE_INCOGNITO;
- else if (header_value == "ADDSESSION")
- return signin::GAIA_SERVICE_TYPE_ADDSESSION;
- else if (header_value == "REAUTH")
- return signin::GAIA_SERVICE_TYPE_REAUTH;
- else if (header_value == "SIGNUP")
- return signin::GAIA_SERVICE_TYPE_SIGNUP;
- else if (header_value == "DEFAULT")
- return signin::GAIA_SERVICE_TYPE_DEFAULT;
- else
- return signin::GAIA_SERVICE_TYPE_NONE;
-}
-
-// Parses the mirror response header. Its expected format is
-// "key1=value1,key2=value2,...".
-MirrorResponseHeaderDictionary ParseMirrorResponseHeader(
- const std::string& header_value) {
- MirrorResponseHeaderDictionary dictionary;
- for (const base::StringPiece& field :
- base::SplitStringPiece(header_value, ",", base::KEEP_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY)) {
- size_t delim = field.find_first_of('=');
- if (delim == std::string::npos) {
- DLOG(WARNING) << "Unexpected GAIA header field '" << field << "'.";
- continue;
- }
- dictionary[field.substr(0, delim).as_string()] = net::UnescapeURLComponent(
- field.substr(delim + 1).as_string(),
- net::UnescapeRule::PATH_SEPARATORS |
- net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS);
- }
- return dictionary;
-}
-
-std::string BuildMirrorRequestIfPossible(
- bool is_header_request,
- const GURL& url,
- const std::string& account_id,
- const content_settings::CookieSettings* cookie_settings,
- int profile_mode_mask) {
- if (account_id.empty())
- return std::string();
-
- // If signin cookies are not allowed, don't add the header.
- if (!signin::SettingsAllowSigninCookies(cookie_settings)) {
- return std::string();
- }
-
- // Check if url is elligible for the header.
- if (!signin::IsUrlEligibleForXChromeConnectedHeader(url))
- return std::string();
-
- std::vector<std::string> parts;
- if (IsUrlEligibleToIncludeGaiaId(url, is_header_request)) {
- // Only set the GAIA Id on domains that actually requires it.
- parts.push_back(
- base::StringPrintf("%s=%s", kGaiaIdAttrName, account_id.c_str()));
- }
- parts.push_back(
- base::StringPrintf("%s=%s", kProfileModeAttrName,
- base::IntToString(profile_mode_mask).c_str()));
- parts.push_back(base::StringPrintf(
- "%s=%s", kEnableAccountConsistencyAttrName,
- switches::IsEnableAccountConsistency() ? "true" : "false"));
-
- return base::JoinString(parts, is_header_request ? "," : ":");
-}
-
-} // namespace
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+#include "components/signin/core/browser/dice_header_helper.h"
+#endif
namespace signin {
extern const char kChromeConnectedHeader[] = "X-Chrome-Connected";
+extern const char kDiceRequestHeader[] = "X-Chrome-ID-Consistency-Request";
ManageAccountsParams::ManageAccountsParams()
: service_type(GAIA_SERVICE_TYPE_NONE),
@@ -150,15 +33,22 @@ ManageAccountsParams::ManageAccountsParams()
is_saml(false),
continue_url(""),
is_same_tab(false) {
-#if !defined(OS_IOS)
- child_id = 0;
- route_id = 0;
-#endif // !defined(OS_IOS)
}
-ManageAccountsParams::ManageAccountsParams(const ManageAccountsParams& other) =
+ManageAccountsParams::ManageAccountsParams(const ManageAccountsParams&) =
default;
+// Trivial constructors and destructors.
+DiceResponseParams::DiceResponseParams() : user_intention(DiceAction::NONE) {}
+DiceResponseParams::~DiceResponseParams() {}
+DiceResponseParams::DiceResponseParams(const DiceResponseParams&) = default;
+DiceResponseParams::SigninInfo::SigninInfo() {}
+DiceResponseParams::SigninInfo::~SigninInfo() {}
+DiceResponseParams::SigninInfo::SigninInfo(const SigninInfo&) = default;
+DiceResponseParams::SignoutInfo::SignoutInfo() {}
+DiceResponseParams::SignoutInfo::~SignoutInfo() {}
+DiceResponseParams::SignoutInfo::SignoutInfo(const SignoutInfo&) = default;
+
bool SettingsAllowSigninCookies(
const content_settings::CookieSettings* cookie_settings) {
GURL gaia_url = GaiaUrls::GetInstance()->gaia_url();
@@ -173,110 +63,113 @@ std::string BuildMirrorRequestCookieIfPossible(
const std::string& account_id,
const content_settings::CookieSettings* cookie_settings,
int profile_mode_mask) {
- return BuildMirrorRequestIfPossible(false /* is_header_request */, url,
- account_id, cookie_settings,
- profile_mode_mask);
+ return signin::ChromeConnectedHeaderHelper::BuildRequestCookieIfPossible(
+ url, account_id, cookie_settings, profile_mode_mask);
}
-bool AppendOrRemoveMirrorRequestHeaderIfPossible(
+bool SigninHeaderHelper::AppendOrRemoveRequestHeader(
net::URLRequest* request,
const GURL& redirect_url,
- const std::string& account_id,
- const content_settings::CookieSettings* cookie_settings,
- int profile_mode_mask) {
- const GURL& url = redirect_url.is_empty() ? request->url() : redirect_url;
- std::string header_value = BuildMirrorRequestIfPossible(
- true /* is_header_request */, url, account_id, cookie_settings,
- profile_mode_mask);
+ const char* header_name,
+ const std::string& header_value) {
if (header_value.empty()) {
- // If the request is being redirected, and it has the x-chrome-connected
+ // If the request is being redirected, and it has the account consistency
// header, and current url is a Google URL, and the redirected one is not,
// remove the header.
if (!redirect_url.is_empty() &&
- request->extra_request_headers().HasHeader(
- signin::kChromeConnectedHeader) &&
- signin::IsUrlEligibleForXChromeConnectedHeader(request->url()) &&
- !signin::IsUrlEligibleForXChromeConnectedHeader(redirect_url)) {
- request->RemoveRequestHeaderByName(signin::kChromeConnectedHeader);
+ request->extra_request_headers().HasHeader(header_name) &&
+ IsUrlEligibleForRequestHeader(request->url()) &&
+ !IsUrlEligibleForRequestHeader(redirect_url)) {
+ request->RemoveRequestHeaderByName(header_name);
}
return false;
}
- request->SetExtraRequestHeaderByName(kChromeConnectedHeader, header_value,
- false);
+ request->SetExtraRequestHeaderByName(header_name, header_value, false);
return true;
}
-ManageAccountsParams BuildManageAccountsParams(
+// static
+SigninHeaderHelper::ResponseHeaderDictionary
+SigninHeaderHelper::ParseAccountConsistencyResponseHeader(
const std::string& header_value) {
- signin::ManageAccountsParams params;
- MirrorResponseHeaderDictionary header_dictionary =
- ParseMirrorResponseHeader(header_value);
- MirrorResponseHeaderDictionary::const_iterator it = header_dictionary.begin();
- for (; it != header_dictionary.end(); ++it) {
- const std::string key_name(it->first);
- if (key_name == kServiceTypeAttrName) {
- params.service_type =
- GetGAIAServiceTypeFromHeader(header_dictionary[kServiceTypeAttrName]);
- } else if (key_name == kEmailAttrName) {
- params.email = header_dictionary[kEmailAttrName];
- } else if (key_name == kIsSamlAttrName) {
- params.is_saml = header_dictionary[kIsSamlAttrName] == "true";
- } else if (key_name == kContinueUrlAttrName) {
- params.continue_url = header_dictionary[kContinueUrlAttrName];
- } else if (key_name == kIsSameTabAttrName) {
- params.is_same_tab = header_dictionary[kIsSameTabAttrName] == "true";
- } else {
- DLOG(WARNING) << "Unexpected GAIA header attribute '" << key_name << "'.";
+ ResponseHeaderDictionary dictionary;
+ for (const base::StringPiece& field :
+ base::SplitStringPiece(header_value, ",", base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_NONEMPTY)) {
+ size_t delim = field.find_first_of('=');
+ if (delim == std::string::npos) {
+ DLOG(WARNING) << "Unexpected Gaia header field '" << field << "'.";
+ continue;
}
+ dictionary.insert(
+ {field.substr(0, delim).as_string(),
+ net::UnescapeURLComponent(
+ field.substr(delim + 1).as_string(),
+ net::UnescapeRule::PATH_SEPARATORS |
+ net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS)});
}
- return params;
+ return dictionary;
}
-ManageAccountsParams BuildManageAccountsParamsIfExists(net::URLRequest* request,
- bool is_off_the_record) {
- ManageAccountsParams empty_params;
- empty_params.service_type = GAIA_SERVICE_TYPE_NONE;
- if (!gaia::IsGaiaSignonRealm(request->url().GetOrigin()))
- return empty_params;
+bool SigninHeaderHelper::ShouldBuildRequestHeader(
+ const GURL& url,
+ const content_settings::CookieSettings* cookie_settings) {
+ // If signin cookies are not allowed, don't add the header.
+ if (!SettingsAllowSigninCookies(cookie_settings))
+ return false;
- std::string header_value;
- net::HttpResponseHeaders* response_headers = request->response_headers();
- if (!response_headers ||
- !response_headers->GetNormalizedHeader(
- kChromeManageAccountsHeader, &header_value)) {
- return empty_params;
- }
+ // Check if url is eligible for the header.
+ if (!IsUrlEligibleForRequestHeader(url))
+ return false;
- DCHECK(switches::IsEnableAccountConsistency() && !is_off_the_record);
- return BuildManageAccountsParams(header_value);
+ return true;
}
-// Checks if the url has the required properties to have an
-// X-Chrome-Connected header.
-bool IsUrlEligibleForXChromeConnectedHeader(const GURL& url) {
- // Only set the header for Drive and Gaia always, and other Google properties
- // if account consistency is enabled.
- // Vasquette, which is integrated with most Google properties, needs the
- // header to redirect certain user actions to Chrome native UI. Drive and Gaia
- // need the header to tell if the current user is connected. The drive path is
- // a temporary workaround until the more generic chrome.principals API is
- // available.
+void AppendOrRemoveAccountConsistentyRequestHeader(
+ net::URLRequest* request,
+ const GURL& redirect_url,
+ const std::string& account_id,
+ bool sync_enabled,
+ const content_settings::CookieSettings* cookie_settings,
+ int profile_mode_mask) {
+ const GURL& url = redirect_url.is_empty() ? request->url() : redirect_url;
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+ DiceHeaderHelper dice_helper;
+ std::string dice_header_value;
+ if (dice_helper.ShouldBuildRequestHeader(url, cookie_settings)) {
+ dice_header_value =
+ dice_helper.BuildRequestHeader(account_id, sync_enabled);
+ }
+ dice_helper.AppendOrRemoveRequestHeader(
+ request, redirect_url, kDiceRequestHeader, dice_header_value);
+#endif
+
+ ChromeConnectedHeaderHelper chrome_connected_helper;
+ std::string chrome_connected_header_value;
+ if (chrome_connected_helper.ShouldBuildRequestHeader(url, cookie_settings)) {
+ chrome_connected_header_value = chrome_connected_helper.BuildRequestHeader(
+ true /* is_header_request */, url, account_id, profile_mode_mask);
+ }
+ chrome_connected_helper.AppendOrRemoveRequestHeader(
+ request, redirect_url, kChromeConnectedHeader,
+ chrome_connected_header_value);
+}
- // Consider the account id sensitive and limit it to secure domains.
- if (!url.SchemeIsCryptographic())
- return false;
+ManageAccountsParams BuildManageAccountsParams(
+ const std::string& header_value) {
+ return ChromeConnectedHeaderHelper::BuildManageAccountsParams(header_value);
+}
- GURL origin(url.GetOrigin());
- bool is_enable_account_consistency = switches::IsEnableAccountConsistency();
- bool is_google_url = is_enable_account_consistency &&
- (google_util::IsGoogleDomainUrl(
- url, google_util::ALLOW_SUBDOMAIN,
- google_util::DISALLOW_NON_STANDARD_PORTS) ||
- google_util::IsYoutubeDomainUrl(
- url, google_util::ALLOW_SUBDOMAIN,
- google_util::DISALLOW_NON_STANDARD_PORTS));
- return is_google_url || IsDriveOrigin(origin) ||
- gaia::IsGaiaSignonRealm(origin);
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+DiceResponseParams BuildDiceSigninResponseParams(
+ const std::string& header_value) {
+ return DiceHeaderHelper::BuildDiceSigninResponseParams(header_value);
+}
+
+DiceResponseParams BuildDiceSignoutResponseParams(
+ const std::string& header_value) {
+ return DiceHeaderHelper::BuildDiceSignoutResponseParams(header_value);
}
+#endif
} // namespace signin
diff --git a/chromium/components/signin/core/browser/signin_header_helper.h b/chromium/components/signin/core/browser/signin_header_helper.h
index 9f000bc6411..06b72cb3ad6 100644
--- a/chromium/components/signin/core/browser/signin_header_helper.h
+++ b/chromium/components/signin/core/browser/signin_header_helper.h
@@ -5,9 +5,12 @@
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_HEADER_HELPER_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_HEADER_HELPER_H_
+#include <map>
#include <string>
+#include <vector>
-#include "build/build_config.h" // For OS_IOS
+#include "components/signin/core/common/signin_features.h"
+#include "url/gurl.h"
namespace content_settings {
class CookieSettings;
@@ -17,8 +20,6 @@ namespace net {
class URLRequest;
}
-class GURL;
-
namespace signin {
// Profile mode flags.
@@ -31,12 +32,13 @@ enum ProfileMode {
};
extern const char kChromeConnectedHeader[];
+extern const char kDiceRequestHeader[];
-// The ServiceType specified by GAIA in the response header accompanying the 204
+// The ServiceType specified by Gaia in the response header accompanying the 204
// response. This indicates the action Chrome is supposed to lead the user to
// perform.
enum GAIAServiceType {
- GAIA_SERVICE_TYPE_NONE = 0, // No GAIA response header.
+ GAIA_SERVICE_TYPE_NONE = 0, // No Gaia response header.
GAIA_SERVICE_TYPE_SIGNOUT, // Logout all existing sessions.
GAIA_SERVICE_TYPE_INCOGNITO, // Open an incognito tab.
GAIA_SERVICE_TYPE_ADDSESSION, // Add a secondary account.
@@ -45,7 +47,13 @@ enum GAIAServiceType {
GAIA_SERVICE_TYPE_DEFAULT, // All other cases.
};
-// Struct describing the paramters received in the manage account header.
+enum class DiceAction {
+ NONE,
+ SIGNIN, // Sign in an account.
+ SIGNOUT, // Sign out of all sessions.
+};
+
+// Struct describing the parameters received in the manage account header.
struct ManageAccountsParams {
// The requested service type such as "ADDSESSION".
GAIAServiceType service_type;
@@ -59,26 +67,87 @@ struct ManageAccountsParams {
// Whether the continue URL should be loaded in the same tab.
bool is_same_tab;
-// iOS has no notion of route and child IDs.
-#if !defined(OS_IOS)
- // The child id associated with the web content of the request.
- int child_id;
- // The route id associated with the web content of the request.
- int route_id;
-#endif // !defined(OS_IOS)
-
ManageAccountsParams();
ManageAccountsParams(const ManageAccountsParams& other);
};
+// Struct describing the parameters received in the Dice response header.
+struct DiceResponseParams {
+ struct SigninInfo {
+ SigninInfo();
+ SigninInfo(const SigninInfo&);
+ ~SigninInfo();
+ // Gaia ID of the account signed in.
+ std::string gaia_id;
+ // Email of the account signed in.
+ std::string email;
+ // Session index for the account signed in.
+ int session_index;
+ // Authorization code to fetch a refresh token.
+ std::string authorization_code;
+ };
+
+ struct SignoutInfo {
+ SignoutInfo();
+ SignoutInfo(const SignoutInfo&);
+ ~SignoutInfo();
+ // Gaia IDs of the accounts signed out.
+ std::vector<std::string> gaia_id;
+ // Emails of the accounts signed out.
+ std::vector<std::string> email;
+ // Session indices for the accounts signed out.
+ std::vector<int> session_index;
+ };
+
+ DiceResponseParams();
+ ~DiceResponseParams();
+ DiceResponseParams(const DiceResponseParams& other);
+
+ DiceAction user_intention;
+
+ // Populated when |user_intention| is SIGNIN.
+ SigninInfo signin_info;
+
+ // Populated when |user_intention| is SIGNOUT.
+ SignoutInfo signout_info;
+};
+
+// Base class for managing the signin headers (Dice and Chrome-Connected).
+class SigninHeaderHelper {
+ public:
+ // Appends or remove the header to a network request if necessary.
+ bool AppendOrRemoveRequestHeader(net::URLRequest* request,
+ const GURL& redirect_url,
+ const char* header_name,
+ const std::string& header_value);
+
+ // Returns wether an account consistency header should be built for this
+ // request.
+ bool ShouldBuildRequestHeader(
+ const GURL& url,
+ const content_settings::CookieSettings* cookie_settings);
+
+ protected:
+ SigninHeaderHelper() {}
+ virtual ~SigninHeaderHelper() {}
+
+ // Dictionary of fields in a account consistency response header.
+ using ResponseHeaderDictionary = std::multimap<std::string, std::string>;
+
+ // Parses the account consistency response header. Its expected format is
+ // "key1=value1,key2=value2,...".
+ static ResponseHeaderDictionary ParseAccountConsistencyResponseHeader(
+ const std::string& header_value);
+
+ private:
+ // Returns whether the url is eligible for the request header.
+ virtual bool IsUrlEligibleForRequestHeader(const GURL& url) = 0;
+};
+
// Returns true if signin cookies are allowed.
bool SettingsAllowSigninCookies(
const content_settings::CookieSettings* cookie_settings);
-// Checks if the url has the required properties to have an
-// X-Chrome-Connected header.
-bool IsUrlEligibleForXChromeConnectedHeader(const GURL& url);
-
// Returns the CHROME_CONNECTED cookie, or an empty string if it should not be
// added to the request to |url|.
std::string BuildMirrorRequestCookieIfPossible(
@@ -87,13 +156,14 @@ std::string BuildMirrorRequestCookieIfPossible(
const content_settings::CookieSettings* cookie_settings,
int profile_mode_mask);
-// Adds X-Chrome-Connected header to all Gaia requests from a connected profile,
-// with the exception of requests from gaia webview.
+// Adds account consistency header to all Gaia requests from a connected
+// profile, with the exception of requests from gaia webview.
// Removes the header in case it should not be transfered to a redirected url.
-bool AppendOrRemoveMirrorRequestHeaderIfPossible(
+void AppendOrRemoveAccountConsistentyRequestHeader(
net::URLRequest* request,
const GURL& redirect_url,
const std::string& account_id,
+ bool sync_enabled,
const content_settings::CookieSettings* cookie_settings,
int profile_mode_mask);
@@ -101,12 +171,21 @@ bool AppendOrRemoveMirrorRequestHeaderIfPossible(
// header.
ManageAccountsParams BuildManageAccountsParams(const std::string& header_value);
-// Returns the parameters contained in the X-Chrome-Manage-Accounts response
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+// Returns the parameters contained in the X-Chrome-ID-Consistency-Response
+// response header.
+// Returns DiceAction::NONE in case of error (such as missing or malformed
+// parameters).
+DiceResponseParams BuildDiceSigninResponseParams(
+ const std::string& header_value);
+
+// Returns the parameters contained in the Google-Accounts-SignOut response
// header.
-// If the request does not have a response header or if the header contains
-// garbage, then |service_type| is set to |GAIA_SERVICE_TYPE_NONE|.
-ManageAccountsParams BuildManageAccountsParamsIfExists(net::URLRequest* request,
- bool is_off_the_record);
+// Returns DiceAction::NONE in case of error (such as missing or malformed
+// parameters).
+DiceResponseParams BuildDiceSignoutResponseParams(
+ const std::string& header_value);
+#endif
} // namespace signin
diff --git a/chromium/components/signin/core/browser/signin_header_helper_unittest.cc b/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
index 5141e3d3f0b..bade766e6fb 100644
--- a/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
+++ b/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
@@ -2,19 +2,31 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "components/signin/core/browser/signin_header_helper.h"
+
#include <memory>
+#include <string>
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
+#include "base/strings/stringprintf.h"
#include "components/content_settings/core/browser/cookie_settings.h"
-#include "components/signin/core/browser/signin_header_helper.h"
+#include "components/signin/core/browser/chrome_connected_header_helper.h"
#include "components/signin/core/common/profile_management_switches.h"
+#include "components/signin/core/common/signin_features.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
+#include "google_apis/gaia/gaia_urls.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+#include "components/signin/core/browser/dice_header_helper.h"
+#endif
+
+namespace signin {
+
class SigninHeaderHelperTest : public testing::Test {
protected:
void SetUp() override {
@@ -33,32 +45,62 @@ class SigninHeaderHelperTest : public testing::Test {
void CheckMirrorCookieRequest(const GURL& url,
const std::string& account_id,
const std::string& expected_request) {
- EXPECT_EQ(signin::BuildMirrorRequestCookieIfPossible(
- url, account_id, cookie_settings_.get(),
- signin::PROFILE_MODE_DEFAULT),
- expected_request);
+ EXPECT_EQ(
+ BuildMirrorRequestCookieIfPossible(
+ url, account_id, cookie_settings_.get(), PROFILE_MODE_DEFAULT),
+ expected_request);
}
- void CheckMirrorHeaderRequest(const GURL& url,
- const std::string& account_id,
- const std::string& expected_request) {
- bool expected_result = !expected_request.empty();
+ std::unique_ptr<net::URLRequest> CreateRequest(const GURL& url,
+ const std::string& account_id,
+ bool sync_enabled) {
std::unique_ptr<net::URLRequest> url_request =
url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS);
- EXPECT_EQ(signin::AppendOrRemoveMirrorRequestHeaderIfPossible(
- url_request.get(), GURL(), account_id, cookie_settings_.get(),
- signin::PROFILE_MODE_DEFAULT),
- expected_result);
+ AppendOrRemoveAccountConsistentyRequestHeader(
+ url_request.get(), GURL(), account_id, sync_enabled,
+ cookie_settings_.get(), PROFILE_MODE_DEFAULT);
+ return url_request;
+ }
+
+ void CheckAccountConsistencyHeaderRequest(
+ net::URLRequest* url_request,
+ const char* header_name,
+ const std::string& expected_request) {
+ bool expected_result = !expected_request.empty();
std::string request;
- EXPECT_EQ(url_request->extra_request_headers().GetHeader(
- signin::kChromeConnectedHeader, &request),
- expected_result);
+ EXPECT_EQ(
+ url_request->extra_request_headers().GetHeader(header_name, &request),
+ expected_result);
if (expected_result) {
EXPECT_EQ(expected_request, request);
}
}
+ void CheckMirrorHeaderRequest(const GURL& url,
+ const std::string& account_id,
+ const std::string& expected_request) {
+ std::unique_ptr<net::URLRequest> url_request =
+ CreateRequest(url, account_id, false /* sync_enabled */);
+ CheckAccountConsistencyHeaderRequest(
+ url_request.get(), kChromeConnectedHeader, expected_request);
+ }
+
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+ void CheckDiceHeaderRequest(const GURL& url,
+ const std::string& account_id,
+ bool sync_enabled,
+ const std::string& expected_mirror_request,
+ const std::string& expected_dice_request) {
+ std::unique_ptr<net::URLRequest> url_request =
+ CreateRequest(url, account_id, sync_enabled);
+ CheckAccountConsistencyHeaderRequest(
+ url_request.get(), kChromeConnectedHeader, expected_mirror_request);
+ CheckAccountConsistencyHeaderRequest(url_request.get(), kDiceRequestHeader,
+ expected_dice_request);
+ }
+#endif
+
base::MessageLoop loop_;
sync_preferences::TestingPrefServiceSyncable prefs_;
@@ -71,7 +113,7 @@ class SigninHeaderHelperTest : public testing::Test {
// Tests that no Mirror request is returned when the user is not signed in (no
// account id).
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestNoAccountId) {
- switches::EnableAccountConsistencyForTesting(
+ switches::EnableAccountConsistencyMirrorForTesting(
base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "", "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), "", "");
@@ -80,7 +122,7 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestNoAccountId) {
// Tests that no Mirror request is returned when the cookies aren't allowed to
// be set.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
- switches::EnableAccountConsistencyForTesting(
+ switches::EnableAccountConsistencyMirrorForTesting(
base::CommandLine::ForCurrentProcess());
cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "0123456789", "");
@@ -89,7 +131,7 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
// Tests that no Mirror request is returned when the target is a non-Google URL.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestExternalURL) {
- switches::EnableAccountConsistencyForTesting(
+ switches::EnableAccountConsistencyMirrorForTesting(
base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(GURL("https://foo.com"), "0123456789", "");
CheckMirrorCookieRequest(GURL("https://foo.com"), "0123456789", "");
@@ -98,7 +140,7 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestExternalURL) {
// Tests that the Mirror request is returned without the GAIA Id when the target
// is a google TLD domain.
TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleTLD) {
- switches::EnableAccountConsistencyForTesting(
+ switches::EnableAccountConsistencyMirrorForTesting(
base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(GURL("https://google.fr"), "0123456789",
"mode=0,enable_account_consistency=true");
@@ -109,7 +151,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleTLD) {
// Tests that the Mirror request is returned when the target is the domain
// google.com, and that the GAIA Id is only attached for the cookie.
TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleCom) {
- switches::EnableAccountConsistencyForTesting(
+ switches::EnableAccountConsistencyMirrorForTesting(
base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(GURL("https://www.google.com"), "0123456789",
"mode=0,enable_account_consistency=true");
@@ -118,14 +160,63 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleCom) {
"id=0123456789:mode=0:enable_account_consistency=true");
}
+// Mirror is always enabled on Android and iOS, so these tests are only relevant
+// on Desktop.
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+
+// Tests that the Mirror request is returned when the target is a Gaia URL, even
+// if account consistency is disabled.
+TEST_F(SigninHeaderHelperTest, TestMirrorRequestGaiaURL) {
+ ASSERT_FALSE(switches::IsAccountConsistencyMirrorEnabled());
+ CheckMirrorHeaderRequest(GURL("https://accounts.google.com"), "0123456789",
+ "mode=0,enable_account_consistency=false");
+ CheckMirrorCookieRequest(
+ GURL("https://accounts.google.com"), "0123456789",
+ "id=0123456789:mode=0:enable_account_consistency=false");
+}
+
+// Tests Dice requests.
+TEST_F(SigninHeaderHelperTest, TestDiceRequest) {
+ switches::EnableAccountConsistencyDiceForTesting(
+ base::CommandLine::ForCurrentProcess());
+ // ChromeConnected but no Dice for Docs URLs.
+ CheckDiceHeaderRequest(
+ GURL("https://docs.google.com"), "0123456789", false /* sync_enabled */,
+ "id=0123456789,mode=0,enable_account_consistency=false", "");
+
+ // ChromeConnected and Dice for Gaia URLs.
+ // Sync disabled.
+ std::string client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id();
+ ASSERT_FALSE(client_id.empty());
+ CheckDiceHeaderRequest(GURL("https://accounts.google.com"), "0123456789",
+ false /* sync_enabled */,
+ "mode=0,enable_account_consistency=false",
+ "client_id=" + client_id);
+ // Sync enabled: check that the Dice header has the Sync account ID and that
+ // the mirror header is not modified.
+ CheckDiceHeaderRequest(
+ GURL("https://accounts.google.com"), "0123456789",
+ true /* sync_enabled */, "mode=0,enable_account_consistency=false",
+ "client_id=" + client_id + ",sync_account_id=0123456789");
+
+ // No ChromeConnected and no Dice for other URLs.
+ CheckDiceHeaderRequest(GURL("https://www.google.com"), "0123456789",
+ false /* sync_enabled */, "", "");
+}
+
+// Tests that no Dice request is returned when Dice is not enabled.
+TEST_F(SigninHeaderHelperTest, TestNoDiceRequestWhenDisabled) {
+ switches::EnableAccountConsistencyMirrorForTesting(
+ base::CommandLine::ForCurrentProcess());
+ CheckDiceHeaderRequest(GURL("https://accounts.google.com"), "0123456789",
+ false /* sync_enabled */,
+ "mode=0,enable_account_consistency=true", "");
+}
+
// Tests that the Mirror request is returned with the GAIA Id on Drive origin,
// even if account consistency is disabled.
-//
-// Account consistency if always enabled on Android and iOS, so this test is
-// only relevant on Desktop.
-#if !defined(OS_ANDROID) && !defined(OS_IOS)
TEST_F(SigninHeaderHelperTest, TestMirrorRequestDrive) {
- DCHECK(!switches::IsEnableAccountConsistency());
+ ASSERT_FALSE(switches::IsAccountConsistencyMirrorEnabled());
CheckMirrorHeaderRequest(
GURL("https://docs.google.com/document"), "0123456789",
"id=0123456789,mode=0,enable_account_consistency=false");
@@ -134,7 +225,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestDrive) {
"id=0123456789:mode=0:enable_account_consistency=false");
// Enable Account Consistency will override the disable.
- switches::EnableAccountConsistencyForTesting(
+ switches::EnableAccountConsistencyMirrorForTesting(
base::CommandLine::ForCurrentProcess());
CheckMirrorHeaderRequest(
GURL("https://docs.google.com/document"), "0123456789",
@@ -143,12 +234,102 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestDrive) {
GURL("https://drive.google.com/drive"), "0123456789",
"id=0123456789:mode=0:enable_account_consistency=true");
}
-#endif
+
+TEST_F(SigninHeaderHelperTest, TestDiceInvalidResponseParams) {
+ DiceResponseParams params = BuildDiceSigninResponseParams("blah");
+ EXPECT_EQ(DiceAction::NONE, params.user_intention);
+}
+
+TEST_F(SigninHeaderHelperTest, TestBuildDiceResponseParams) {
+ const char kAuthorizationCode[] = "authorization_code";
+ const char kEmail[] = "foo@example.com";
+ const char kGaiaID[] = "gaia_id";
+ const int kSessionIndex = 42;
+
+ {
+ // Signin response.
+ DiceResponseParams params =
+ BuildDiceSigninResponseParams(base::StringPrintf(
+ "action=SIGNIN,id=%s,email=%s,authuser=%i,authorization_code=%s",
+ kGaiaID, kEmail, kSessionIndex, kAuthorizationCode));
+ EXPECT_EQ(DiceAction::SIGNIN, params.user_intention);
+ EXPECT_EQ(kGaiaID, params.signin_info.gaia_id);
+ EXPECT_EQ(kEmail, params.signin_info.email);
+ EXPECT_EQ(kSessionIndex, params.signin_info.session_index);
+ EXPECT_EQ(kAuthorizationCode, params.signin_info.authorization_code);
+ }
+
+ {
+ // Signout response.
+ // Note: Gaia responses typically have a whitespace after the commas, and
+ // some fields are wrapped in quotes.
+ DiceResponseParams params = BuildDiceSignoutResponseParams(
+ base::StringPrintf("email=\"%s\", sessionindex=%i, obfuscatedid=\"%s\"",
+ kEmail, kSessionIndex, kGaiaID));
+ ASSERT_EQ(DiceAction::SIGNOUT, params.user_intention);
+ EXPECT_EQ(1u, params.signout_info.gaia_id.size());
+ EXPECT_EQ(1u, params.signout_info.email.size());
+ EXPECT_EQ(1u, params.signout_info.session_index.size());
+ EXPECT_EQ(kGaiaID, params.signout_info.gaia_id[0]);
+ EXPECT_EQ(kEmail, params.signout_info.email[0]);
+ EXPECT_EQ(kSessionIndex, params.signout_info.session_index[0]);
+ }
+
+ {
+ // Multi-Signout response.
+ const char kEmail2[] = "bar@example.com";
+ const char kGaiaID2[] = "gaia_id_2";
+ const int kSessionIndex2 = 2;
+ DiceResponseParams params =
+ BuildDiceSignoutResponseParams(base::StringPrintf(
+ "email=\"%s\", sessionindex=%i, obfuscatedid=\"%s\", "
+ "email=\"%s\", sessionindex=%i, obfuscatedid=\"%s\"",
+ kEmail, kSessionIndex, kGaiaID, kEmail2, kSessionIndex2, kGaiaID2));
+ ASSERT_EQ(DiceAction::SIGNOUT, params.user_intention);
+ EXPECT_EQ(2u, params.signout_info.gaia_id.size());
+ EXPECT_EQ(2u, params.signout_info.email.size());
+ EXPECT_EQ(2u, params.signout_info.session_index.size());
+ EXPECT_EQ(kGaiaID, params.signout_info.gaia_id[0]);
+ EXPECT_EQ(kEmail, params.signout_info.email[0]);
+ EXPECT_EQ(kSessionIndex, params.signout_info.session_index[0]);
+ EXPECT_EQ(kGaiaID2, params.signout_info.gaia_id[1]);
+ EXPECT_EQ(kEmail2, params.signout_info.email[1]);
+ EXPECT_EQ(kSessionIndex2, params.signout_info.session_index[1]);
+ }
+
+ {
+ // Missing authorization code.
+ DiceResponseParams params = BuildDiceSigninResponseParams(
+ base::StringPrintf("action=SIGNIN,id=%s,email=%s,authuser=%i", kGaiaID,
+ kEmail, kSessionIndex));
+ EXPECT_EQ(DiceAction::NONE, params.user_intention);
+ }
+
+ {
+ // Missing email in SIGNIN.
+ DiceResponseParams params =
+ BuildDiceSigninResponseParams(base::StringPrintf(
+ "action=SIGNIN,id=%s,authuser=%i,authorization_code=%s", kGaiaID,
+ kSessionIndex, kAuthorizationCode));
+ EXPECT_EQ(DiceAction::NONE, params.user_intention);
+ }
+
+ {
+ // Missing email in signout.
+ DiceResponseParams params = BuildDiceSignoutResponseParams(
+ base::StringPrintf("email=%s, sessionindex=%i, obfuscatedid=%s, "
+ "sessionindex=2, obfuscatedid=bar",
+ kEmail, kSessionIndex, kGaiaID));
+ EXPECT_EQ(DiceAction::NONE, params.user_intention);
+ }
+}
+
+#endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
// Tests that the Mirror header request is returned normally when the redirect
// URL is eligible.
TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) {
- switches::EnableAccountConsistencyForTesting(
+ switches::EnableAccountConsistencyMirrorForTesting(
base::CommandLine::ForCurrentProcess());
const GURL url("https://docs.google.com/document");
const GURL redirect_url("https://www.google.com");
@@ -156,17 +337,17 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) {
std::unique_ptr<net::URLRequest> url_request =
url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS);
- EXPECT_TRUE(signin::AppendOrRemoveMirrorRequestHeaderIfPossible(
- url_request.get(), redirect_url, account_id, cookie_settings_.get(),
- signin::PROFILE_MODE_DEFAULT));
- EXPECT_TRUE(url_request->extra_request_headers().HasHeader(
- signin::kChromeConnectedHeader));
+ AppendOrRemoveAccountConsistentyRequestHeader(
+ url_request.get(), redirect_url, account_id, false /* sync_enabled */,
+ cookie_settings_.get(), PROFILE_MODE_DEFAULT);
+ EXPECT_TRUE(
+ url_request->extra_request_headers().HasHeader(kChromeConnectedHeader));
}
// Tests that the Mirror header request is stripped when the redirect URL is not
// eligible.
TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) {
- switches::EnableAccountConsistencyForTesting(
+ switches::EnableAccountConsistencyMirrorForTesting(
base::CommandLine::ForCurrentProcess());
const GURL url("https://docs.google.com/document");
const GURL redirect_url("http://www.foo.com");
@@ -174,17 +355,17 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) {
std::unique_ptr<net::URLRequest> url_request =
url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS);
- EXPECT_FALSE(signin::AppendOrRemoveMirrorRequestHeaderIfPossible(
- url_request.get(), redirect_url, account_id, cookie_settings_.get(),
- signin::PROFILE_MODE_DEFAULT));
- EXPECT_FALSE(url_request->extra_request_headers().HasHeader(
- signin::kChromeConnectedHeader));
+ AppendOrRemoveAccountConsistentyRequestHeader(
+ url_request.get(), redirect_url, account_id, false /* sync_enabled */,
+ cookie_settings_.get(), PROFILE_MODE_DEFAULT);
+ EXPECT_FALSE(
+ url_request->extra_request_headers().HasHeader(kChromeConnectedHeader));
}
// Tests that the Mirror header, whatever its value is, is untouched when both
// the current and the redirect URL are non-eligible.
TEST_F(SigninHeaderHelperTest, TestIgnoreMirrorHeaderNonEligibleURLs) {
- switches::EnableAccountConsistencyForTesting(
+ switches::EnableAccountConsistencyMirrorForTesting(
base::CommandLine::ForCurrentProcess());
const GURL url("https://www.bar.com");
const GURL redirect_url("http://www.foo.com");
@@ -193,13 +374,34 @@ TEST_F(SigninHeaderHelperTest, TestIgnoreMirrorHeaderNonEligibleURLs) {
std::unique_ptr<net::URLRequest> url_request =
url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr,
TRAFFIC_ANNOTATION_FOR_TESTS);
- url_request->SetExtraRequestHeaderByName(signin::kChromeConnectedHeader,
- fake_header, false);
- EXPECT_FALSE(signin::AppendOrRemoveMirrorRequestHeaderIfPossible(
- url_request.get(), redirect_url, account_id, cookie_settings_.get(),
- signin::PROFILE_MODE_DEFAULT));
+ url_request->SetExtraRequestHeaderByName(kChromeConnectedHeader, fake_header,
+ false);
+ AppendOrRemoveAccountConsistentyRequestHeader(
+ url_request.get(), redirect_url, account_id, false /* sync_enabled */,
+ cookie_settings_.get(), PROFILE_MODE_DEFAULT);
std::string header;
EXPECT_TRUE(url_request->extra_request_headers().GetHeader(
- signin::kChromeConnectedHeader, &header));
+ kChromeConnectedHeader, &header));
EXPECT_EQ(fake_header, header);
}
+
+TEST_F(SigninHeaderHelperTest, TestInvalidManageAccountsParams) {
+ ManageAccountsParams params = BuildManageAccountsParams("blah");
+ EXPECT_EQ(GAIA_SERVICE_TYPE_NONE, params.service_type);
+}
+
+TEST_F(SigninHeaderHelperTest, TestBuildManageAccountsParams) {
+ const char kContinueURL[] = "https://www.example.com/continue";
+ const char kEmail[] = "foo@example.com";
+
+ ManageAccountsParams params = BuildManageAccountsParams(base::StringPrintf(
+ "action=REAUTH,email=%s,is_saml=true,is_same_tab=true,continue_url=%s",
+ kEmail, kContinueURL));
+ EXPECT_EQ(GAIA_SERVICE_TYPE_REAUTH, params.service_type);
+ EXPECT_EQ(kEmail, params.email);
+ EXPECT_EQ(true, params.is_saml);
+ EXPECT_EQ(true, params.is_same_tab);
+ EXPECT_EQ(GURL(kContinueURL), params.continue_url);
+}
+
+} // namespace signin
diff --git a/chromium/components/signin/core/browser/signin_manager.cc b/chromium/components/signin/core/browser/signin_manager.cc
index 9e588dc9879..5ced3207823 100644
--- a/chromium/components/signin/core/browser/signin_manager.cc
+++ b/chromium/components/signin/core/browser/signin_manager.cc
@@ -54,6 +54,8 @@ std::string SigninManager::SigninTypeToString(SigninManager::SigninType type) {
return "No Signin";
case SIGNIN_TYPE_WITH_REFRESH_TOKEN:
return "With refresh token";
+ case SIGNIN_TYPE_WITHOUT_REFRESH_TOKEN:
+ return "Without refresh token";
}
NOTREACHED();
@@ -66,9 +68,9 @@ bool SigninManager::PrepareForSignin(SigninType type,
const std::string& password) {
std::string account_id =
account_tracker_service()->PickAccountIdForAccount(gaia_id, username);
+ DCHECK(!account_id.empty());
DCHECK(possibly_invalid_account_id_.empty() ||
possibly_invalid_account_id_ == account_id);
- DCHECK(!account_id.empty());
if (!IsAllowedUsername(username)) {
// Account is not allowed by admin policy.
@@ -101,19 +103,21 @@ void SigninManager::StartSignInWithRefreshToken(
const std::string& password,
const OAuthTokenFetchedCallback& callback) {
DCHECK(!IsAuthenticated());
-
- if (!PrepareForSignin(SIGNIN_TYPE_WITH_REFRESH_TOKEN, gaia_id, username,
- password)) {
+ SigninType signin_type = refresh_token.empty()
+ ? SIGNIN_TYPE_WITHOUT_REFRESH_TOKEN
+ : SIGNIN_TYPE_WITH_REFRESH_TOKEN;
+ if (!PrepareForSignin(signin_type, gaia_id, username, password)) {
return;
}
- // Store our token.
+ // Store the refresh token.
temp_refresh_token_ = refresh_token;
- if (!callback.is_null() && !temp_refresh_token_.empty()) {
+ if (!callback.is_null()) {
+ // Callback present, let the caller complete the pending sign-in.
callback.Run(temp_refresh_token_);
} else {
- // No oauth token or callback, so just complete our pending signin.
+ // No callback, so just complete the pending signin.
CompletePendingSignin();
}
}
@@ -350,13 +354,13 @@ void SigninManager::CompletePendingSignin() {
DCHECK(!possibly_invalid_account_id_.empty());
OnSignedIn();
- DCHECK(!temp_refresh_token_.empty());
DCHECK(IsAuthenticated());
- std::string account_id = GetAuthenticatedAccountId();
- token_service_->UpdateCredentials(account_id, temp_refresh_token_);
- temp_refresh_token_.clear();
-
+ if (!temp_refresh_token_.empty()) {
+ std::string account_id = GetAuthenticatedAccountId();
+ token_service_->UpdateCredentials(account_id, temp_refresh_token_);
+ temp_refresh_token_.clear();
+ }
MergeSigninCredentialIntoCookieJar();
}
@@ -385,8 +389,11 @@ void SigninManager::OnSignedIn() {
for (auto& observer : observer_list_) {
observer.GoogleSigninSucceeded(GetAuthenticatedAccountId(),
- GetAuthenticatedAccountInfo().email,
- password_);
+ GetAuthenticatedAccountInfo().email);
+
+ observer.GoogleSigninSucceededWithPassword(
+ GetAuthenticatedAccountId(), GetAuthenticatedAccountInfo().email,
+ password_);
}
client_->OnSignedIn(GetAuthenticatedAccountId(), gaia_id,
diff --git a/chromium/components/signin/core/browser/signin_manager.h b/chromium/components/signin/core/browser/signin_manager.h
index 92e9ff587ec..bae32cf78e4 100644
--- a/chromium/components/signin/core/browser/signin_manager.h
+++ b/chromium/components/signin/core/browser/signin_manager.h
@@ -74,8 +74,10 @@ class SigninManager : public SigninManagerBase,
const std::string& policy);
// Attempt to sign in this user with a refresh token.
+ // If |refresh_token| is not empty, then SigninManager will add it to the
+ // |token_service_| when the sign-in flow is completed.
// If non-null, the passed |oauth_fetched_callback| callback is invoked once
- // signin has been completed.
+ // sign-in has been completed.
// The callback should invoke SignOut() or CompletePendingSignin() to either
// continue or cancel the in-process signin.
virtual void StartSignInWithRefreshToken(
@@ -152,7 +154,11 @@ class SigninManager : public SigninManagerBase,
signin_metrics::SignoutDelete signout_delete_metric);
private:
- enum SigninType { SIGNIN_TYPE_NONE, SIGNIN_TYPE_WITH_REFRESH_TOKEN };
+ enum SigninType {
+ SIGNIN_TYPE_NONE,
+ SIGNIN_TYPE_WITH_REFRESH_TOKEN,
+ SIGNIN_TYPE_WITHOUT_REFRESH_TOKEN
+ };
std::string SigninTypeToString(SigninType type);
friend class FakeSigninManager;
diff --git a/chromium/components/signin/core/browser/signin_manager_base.cc b/chromium/components/signin/core/browser/signin_manager_base.cc
index df125732094..14ad0380e7a 100644
--- a/chromium/components/signin/core/browser/signin_manager_base.cc
+++ b/chromium/components/signin/core/browser/signin_manager_base.cc
@@ -232,7 +232,9 @@ bool SigninManagerBase::AuthInProgress() const {
return false;
}
-void SigninManagerBase::Shutdown() {}
+void SigninManagerBase::Shutdown() {
+ on_shutdown_callback_list_.Notify();
+}
void SigninManagerBase::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
diff --git a/chromium/components/signin/core/browser/signin_manager_base.h b/chromium/components/signin/core/browser/signin_manager_base.h
index ddf20d85567..a7c08678e66 100644
--- a/chromium/components/signin/core/browser/signin_manager_base.h
+++ b/chromium/components/signin/core/browser/signin_manager_base.h
@@ -26,6 +26,7 @@
#include <memory>
#include <string>
+#include "base/callback_list.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -42,6 +43,10 @@ class PrefRegistrySimple;
class PrefService;
class SigninClient;
+namespace password_manager {
+class PasswordStoreSigninNotifierImpl;
+}
+
namespace user_prefs {
class PrefRegistrySyncable;
}
@@ -55,8 +60,7 @@ class SigninManagerBase : public KeyedService {
// Called when a user signs into Google services such as sync.
virtual void GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) {}
+ const std::string& username) {}
// Called when the currently signed-in user for a user has been signed out.
virtual void GoogleSignedOut(const std::string& account_id,
@@ -64,6 +68,30 @@ class SigninManagerBase : public KeyedService {
protected:
virtual ~Observer() {}
+
+ private:
+ // Observers that can observer the password of the Google account after a
+ // successful sign-in.
+ friend class PasswordStoreSigninNotifierImpl;
+
+ // SigninManagers that fire |GoogleSigninSucceededWithPassword|
+ // notifications.
+ friend class SigninManager;
+ friend class FakeSigninManager;
+
+ // Called when a user signs into Google services such as sync. Also passes
+ // the password of the Google account that was used to sign in.
+ //
+ // Observers should override |GoogleSigninSucceeded| if they are not
+ // interested in the password thas was used during the sign-in.
+ //
+ // Note: The password is always empty on mobile as the user signs in to
+ // Chrome with accounts that were added to the device, so Chrome does not
+ // have access to the password.
+ virtual void GoogleSigninSucceededWithPassword(
+ const std::string& account_id,
+ const std::string& username,
+ const std::string& password) {}
};
SigninManagerBase(SigninClient* client,
@@ -132,6 +160,15 @@ class SigninManagerBase : public KeyedService {
// Gives access to the SigninClient instance associated with this instance.
SigninClient* signin_client() const { return client_; }
+ // Adds a callback that will be called when this instance is shut down.Not
+ // intended for general usage, but rather for usage only by the Identity
+ // Service implementation during the time period of conversion of Chrome to
+ // use the Identity Service.
+ std::unique_ptr<base::CallbackList<void()>::Subscription>
+ RegisterOnShutdownCallback(const base::Closure& cb) {
+ return on_shutdown_callback_list_.Add(cb);
+ }
+
protected:
AccountTrackerService* account_tracker_service() const {
return account_tracker_service_;
@@ -169,6 +206,9 @@ class SigninManagerBase : public KeyedService {
base::ObserverList<signin_internals_util::SigninDiagnosticsObserver, true>
signin_diagnostics_observers_;
+ // The list of callbacks notified on shutdown.
+ base::CallbackList<void()> on_shutdown_callback_list_;
+
base::WeakPtrFactory<SigninManagerBase> weak_pointer_factory_;
DISALLOW_COPY_AND_ASSIGN(SigninManagerBase);
diff --git a/chromium/components/signin/core/browser/signin_metrics.h b/chromium/components/signin/core/browser/signin_metrics.h
index 177ed1fae62..cc6709e2958 100644
--- a/chromium/components/signin/core/browser/signin_metrics.h
+++ b/chromium/components/signin/core/browser/signin_metrics.h
@@ -143,6 +143,7 @@ enum class AccessPoint : int {
ACCESS_POINT_NTP_CONTENT_SUGGESTIONS,
ACCESS_POINT_RESIGNIN_INFOBAR,
ACCESS_POINT_TAB_SWITCHER,
+ ACCESS_POINT_FORCE_SIGNIN_WARNING,
ACCESS_POINT_MAX, // This must be last.
};
diff --git a/chromium/components/signin/core/browser/signin_status_metrics_provider.cc b/chromium/components/signin/core/browser/signin_status_metrics_provider.cc
index 699e61d6190..8ead61c4a97 100644
--- a/chromium/components/signin/core/browser/signin_status_metrics_provider.cc
+++ b/chromium/components/signin/core/browser/signin_status_metrics_provider.cc
@@ -77,8 +77,7 @@ void SigninStatusMetricsProvider::OnSigninManagerShutdown(
void SigninStatusMetricsProvider::GoogleSigninSucceeded(
const std::string& account_id,
- const std::string& username,
- const std::string& password) {
+ const std::string& username) {
SigninStatus recorded_signin_status = signin_status();
if (recorded_signin_status == ALL_PROFILES_NOT_SIGNED_IN) {
UpdateSigninStatus(MIXED_SIGNIN_STATUS);
diff --git a/chromium/components/signin/core/browser/signin_status_metrics_provider.h b/chromium/components/signin/core/browser/signin_status_metrics_provider.h
index 9d6e663d126..ee6f0adf6ba 100644
--- a/chromium/components/signin/core/browser/signin_status_metrics_provider.h
+++ b/chromium/components/signin/core/browser/signin_status_metrics_provider.h
@@ -70,8 +70,7 @@ class SigninStatusMetricsProvider : public SigninStatusMetricsProviderBase,
// SigninManagerBase::Observer:
void GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) override;
+ const std::string& username) override;
void GoogleSignedOut(const std::string& account_id,
const std::string& username) override;
diff --git a/chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc b/chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc
index 13f54ab77e4..ed1a87129a9 100644
--- a/chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc
+++ b/chromium/components/signin/core/browser/signin_status_metrics_provider_unittest.cc
@@ -27,15 +27,13 @@ TEST(SigninStatusMetricsProviderTest, GoogleSigninSucceeded) {
// Initial status is all signed out and then one of the profiles is signed in.
metrics_provider.UpdateInitialSigninStatus(2, 0);
- metrics_provider.GoogleSigninSucceeded(std::string(), std::string(),
- std::string());
+ metrics_provider.GoogleSigninSucceeded(std::string(), std::string());
EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS,
metrics_provider.GetSigninStatusForTesting());
// Initial status is mixed and then one of the profiles is signed in.
metrics_provider.UpdateInitialSigninStatus(2, 1);
- metrics_provider.GoogleSigninSucceeded(std::string(), std::string(),
- std::string());
+ metrics_provider.GoogleSigninSucceeded(std::string(), std::string());
EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS,
metrics_provider.GetSigninStatusForTesting());
}
diff --git a/chromium/components/signin/core/browser/signin_tracker.cc b/chromium/components/signin/core/browser/signin_tracker.cc
index b13365dcab3..24e23983344 100644
--- a/chromium/components/signin/core/browser/signin_tracker.cc
+++ b/chromium/components/signin/core/browser/signin_tracker.cc
@@ -32,6 +32,12 @@ void SigninTracker::Initialize() {
cookie_manager_service_->AddObserver(this);
}
+void SigninTracker::GoogleSigninSucceeded(const std::string& account_id,
+ const std::string& username) {
+ if (token_service_->RefreshTokenIsAvailable(account_id))
+ observer_->SigninSuccess();
+}
+
void SigninTracker::GoogleSigninFailed(const GoogleServiceAuthError& error) {
observer_->SigninFailed(error);
}
diff --git a/chromium/components/signin/core/browser/signin_tracker.h b/chromium/components/signin/core/browser/signin_tracker.h
index cabbedf02ca..e433df58722 100644
--- a/chromium/components/signin/core/browser/signin_tracker.h
+++ b/chromium/components/signin/core/browser/signin_tracker.h
@@ -80,6 +80,8 @@ class SigninTracker : public SigninManagerBase::Observer,
~SigninTracker() override;
// SigninManagerBase::Observer implementation.
+ void GoogleSigninSucceeded(const std::string& account_id,
+ const std::string& username) override;
void GoogleSigninFailed(const GoogleServiceAuthError& error) override;
// OAuth2TokenService::Observer implementation.
diff --git a/chromium/components/signin/core/common/BUILD.gn b/chromium/components/signin/core/common/BUILD.gn
index 670bde9c185..c1a5c09b5e9 100644
--- a/chromium/components/signin/core/common/BUILD.gn
+++ b/chromium/components/signin/core/common/BUILD.gn
@@ -2,6 +2,17 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/buildflag_header.gni")
+import("//components/signin/features.gni")
+
+buildflag_header("signin_features") {
+ header = "signin_features.h"
+ flags = [
+ "ENABLE_DICE_SUPPORT=$enable_dice_support",
+ "ENABLE_MIRROR=$enable_mirror",
+ ]
+}
+
static_library("common") {
sources = [
"profile_management_switches.cc",
@@ -15,4 +26,8 @@ static_library("common") {
deps = [
"//base",
]
+
+ public_deps = [
+ ":signin_features",
+ ]
}
diff --git a/chromium/components/signin/core/common/profile_management_switches.cc b/chromium/components/signin/core/common/profile_management_switches.cc
index 4b14f6c0331..61dd356e6c0 100644
--- a/chromium/components/signin/core/common/profile_management_switches.cc
+++ b/chromium/components/signin/core/common/profile_management_switches.cc
@@ -14,14 +14,31 @@
namespace switches {
-bool IsEnableAccountConsistency() {
-#if defined(OS_ANDROID) || defined(OS_IOS)
- // Account consistency is enabled on Android and iOS.
- return true;
+AccountConsistencyMethod GetAccountConsistencyMethod() {
+#if BUILDFLAG(ENABLE_MIRROR)
+ // Mirror is enabled on Android and iOS.
+ return AccountConsistencyMethod::kMirror;
#else
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableAccountConsistency);
-#endif // defined(OS_ANDROID) || defined(OS_IOS)
+ base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
+ std::string method = cmd->GetSwitchValueASCII(switches::kAccountConsistency);
+ if (method == switches::kAccountConsistencyMirror)
+ return AccountConsistencyMethod::kMirror;
+
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+ if (method == switches::kAccountConsistencyDice)
+ return AccountConsistencyMethod::kDice;
+#endif
+
+ return AccountConsistencyMethod::kDisabled;
+#endif // BUILDFLAG(ENABLE_MIRROR)
+}
+
+bool IsAccountConsistencyMirrorEnabled() {
+ return GetAccountConsistencyMethod() == AccountConsistencyMethod::kMirror;
+}
+
+bool IsAccountConsistencyDiceEnabled() {
+ return GetAccountConsistencyMethod() == AccountConsistencyMethod::kDice;
}
bool IsExtensionsMultiAccount() {
@@ -33,13 +50,21 @@ bool IsExtensionsMultiAccount() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kExtensionsMultiAccount) ||
- IsEnableAccountConsistency();
+ GetAccountConsistencyMethod() == AccountConsistencyMethod::kMirror;
}
-void EnableAccountConsistencyForTesting(base::CommandLine* command_line) {
-#if !defined(OS_ANDROID) && !defined(OS_IOS)
- command_line->AppendSwitch(switches::kEnableAccountConsistency);
+void EnableAccountConsistencyMirrorForTesting(base::CommandLine* command_line) {
+#if !BUILDFLAG(ENABLE_MIRROR)
+ command_line->AppendSwitchASCII(switches::kAccountConsistency,
+ switches::kAccountConsistencyMirror);
#endif
}
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+void EnableAccountConsistencyDiceForTesting(base::CommandLine* command_line) {
+ command_line->AppendSwitchASCII(switches::kAccountConsistency,
+ switches::kAccountConsistencyDice);
+}
+#endif
+
} // namespace switches
diff --git a/chromium/components/signin/core/common/profile_management_switches.h b/chromium/components/signin/core/common/profile_management_switches.h
index b3080e961d0..9642ef5b0ce 100644
--- a/chromium/components/signin/core/common/profile_management_switches.h
+++ b/chromium/components/signin/core/common/profile_management_switches.h
@@ -9,21 +9,41 @@
#ifndef COMPONENTS_SIGNIN_CORE_COMMON_PROFILE_MANAGEMENT_SWITCHES_H_
#define COMPONENTS_SIGNIN_CORE_COMMON_PROFILE_MANAGEMENT_SWITCHES_H_
+#include "components/signin/core/common/signin_features.h"
+
namespace base {
class CommandLine;
}
namespace switches {
-// Checks whether account consistency is enabled. If enabled, the account
+enum class AccountConsistencyMethod {
+ kDisabled, // No account consistency.
+ kMirror, // Account management UI in the avatar bubble.
+ kDice // Account management UI on Gaia webpages.
+};
+
+// Returns the account consistency method.
+AccountConsistencyMethod GetAccountConsistencyMethod();
+
+// Checks whether Mirror account consistency is enabled. If enabled, the account
// management UI is available in the avatar bubble.
-bool IsEnableAccountConsistency();
+bool IsAccountConsistencyMirrorEnabled();
+
+// Checks whether Dice account consistency is enabled. If enabled, then account
+// management UI is available on the Gaia webpages.
+bool IsAccountConsistencyDiceEnabled();
// Whether the chrome.identity API should be multi-account.
bool IsExtensionsMultiAccount();
-// Called in tests to force enable account consistency.
-void EnableAccountConsistencyForTesting(base::CommandLine* command_line);
+// Called in tests to force enable Mirror account consistency.
+void EnableAccountConsistencyMirrorForTesting(base::CommandLine* command_line);
+
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+// Called in tests to force enable Dice account consistency.
+void EnableAccountConsistencyDiceForTesting(base::CommandLine* command_line);
+#endif
} // namespace switches
diff --git a/chromium/components/signin/core/common/signin_switches.cc b/chromium/components/signin/core/common/signin_switches.cc
index ef1d865c333..5ef25b778b3 100644
--- a/chromium/components/signin/core/common/signin_switches.cc
+++ b/chromium/components/signin/core/common/signin_switches.cc
@@ -16,9 +16,17 @@ const char kDisableSigninPromo[] = "disable-signin-promo";
// Disables sending signin scoped device id to LSO with refresh token request.
const char kDisableSigninScopedDeviceId[] = "disable-signin-scoped-device-id";
-#if !defined(OS_ANDROID) && !defined(OS_IOS)
-// Enables consistent identity features.
-const char kEnableAccountConsistency[] = "enable-account-consistency";
+#if !BUILDFLAG(ENABLE_MIRROR)
+// Command line flag for enabling account consistency. Default mode is disabled.
+// Mirror is a legacy mode in which Google accounts are always addded to Chrome,
+// and Chrome then adds them to the Google authentication cookies.
+// Dice is a new experiment in which Chrome is aware of the accounts in the
+// Google authentication cookies.
+const char kAccountConsistency[] = "account-consistency";
+
+// Values for the kAccountConsistency flag.
+const char kAccountConsistencyMirror[] = "mirror";
+const char kAccountConsistencyDice[] = "dice";
#endif
// Enables sending EnableRefreshTokenAnnotationRequest.
diff --git a/chromium/components/signin/core/common/signin_switches.h b/chromium/components/signin/core/common/signin_switches.h
index 8c0ecc2db9b..5038a1e4fe3 100644
--- a/chromium/components/signin/core/common/signin_switches.h
+++ b/chromium/components/signin/core/common/signin_switches.h
@@ -5,7 +5,7 @@
#ifndef COMPONENTS_SIGNIN_CORE_COMMON_SIGNIN_SWITCHES_H_
#define COMPONENTS_SIGNIN_CORE_COMMON_SIGNIN_SWITCHES_H_
-#include "base/feature_list.h"
+#include "components/signin/core/common/signin_features.h"
namespace switches {
@@ -22,10 +22,12 @@ extern const char kEnableRefreshTokenAnnotationRequest[];
extern const char kEnableSigninPromo[];
extern const char kExtensionsMultiAccount[];
-#if !defined(OS_ANDROID) && !defined(OS_IOS)
-// Note: Account consistency is already enabled on mobile platforms, so this
-// switch only exist on desktop platforms.
-extern const char kEnableAccountConsistency[];
+#if !BUILDFLAG(ENABLE_MIRROR)
+// Note: Account consistency (Mirror) is already enabled on mobile platforms, so
+// this switch only exist on desktop platforms.
+extern const char kAccountConsistency[];
+extern const char kAccountConsistencyMirror[];
+extern const char kAccountConsistencyDice[];
#endif
} // namespace switches
diff --git a/chromium/components/signin/features.gni b/chromium/components/signin/features.gni
new file mode 100644
index 00000000000..f4636abdb3f
--- /dev/null
+++ b/chromium/components/signin/features.gni
@@ -0,0 +1,9 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Dice is supported on the platform (but not necessarily enabled).
+enable_dice_support = (is_linux && !is_chromeos) || is_mac || is_win
+
+# Mirror is enabled and other account consistency mechanisms are not available.
+enable_mirror = is_android || is_ios
diff --git a/chromium/components/signin/ios/browser/BUILD.gn b/chromium/components/signin/ios/browser/BUILD.gn
index b914497f1d0..f34f92eec9a 100644
--- a/chromium/components/signin/ios/browser/BUILD.gn
+++ b/chromium/components/signin/ios/browser/BUILD.gn
@@ -3,6 +3,7 @@
# found in the LICENSE file.
source_set("browser") {
+ configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"account_consistency_service.h",
"account_consistency_service.mm",
@@ -48,6 +49,7 @@ source_set("test_support") {
}
source_set("unit_tests") {
+ configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"account_consistency_service_unittest.mm",
@@ -62,7 +64,8 @@ source_set("unit_tests") {
"//components/signin/core/common",
"//components/sync_preferences:test_support",
"//ios/web",
- "//ios/web:test_support",
+ "//ios/web/public/test",
+ "//ios/web/public/test/fakes",
"//third_party/ocmock",
]
}
diff --git a/chromium/components/signin/ios/browser/account_consistency_service.h b/chromium/components/signin/ios/browser/account_consistency_service.h
index 1f7a1e6eb3f..8df4874f76b 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service.h
+++ b/chromium/components/signin/ios/browser/account_consistency_service.h
@@ -11,7 +11,6 @@
#include <set>
#include <string>
-#include "base/mac/scoped_nsobject.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
@@ -144,8 +143,7 @@ class AccountConsistencyService : public KeyedService,
// SigninManagerBase::Observer implementation.
void GoogleSigninSucceeded(const std::string& account_id,
- const std::string& username,
- const std::string& password) override;
+ const std::string& username) override;
void GoogleSignedOut(const std::string& account_id,
const std::string& username) override;
@@ -178,11 +176,10 @@ class AccountConsistencyService : public KeyedService,
std::map<std::string, base::Time> last_cookie_update_map_;
// Web view used to apply the CHROME_CONNECTED cookie requests.
- base::scoped_nsobject<WKWebView> web_view_;
+ __strong WKWebView* web_view_;
// Navigation delegate of |web_view_| that informs the service when a cookie
// request has been applied.
- base::scoped_nsobject<AccountConsistencyNavigationDelegate>
- navigation_delegate_;
+ AccountConsistencyNavigationDelegate* navigation_delegate_;
// Handlers reacting on GAIA responses with the X-Chrome-Manage-Accounts
// header set.
diff --git a/chromium/components/signin/ios/browser/account_consistency_service.mm b/chromium/components/signin/ios/browser/account_consistency_service.mm
index 5f15df39e15..a56cc1b8626 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service.mm
+++ b/chromium/components/signin/ios/browser/account_consistency_service.mm
@@ -6,7 +6,6 @@
#import <WebKit/WebKit.h>
-#import "base/ios/weak_nsobject.h"
#include "base/logging.h"
#import "base/mac/foundation_util.h"
#include "base/macros.h"
@@ -24,6 +23,10 @@
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "url/gurl.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
namespace {
// Threshold (in hours) used to control whether the CHROME_CONNECTED cookie
@@ -58,7 +61,7 @@ class AccountConsistencyHandler : public web::WebStatePolicyDecider {
AccountConsistencyService* account_consistency_service_; // Weak.
AccountReconcilor* account_reconcilor_; // Weak.
- base::WeakNSProtocol<id<ManageAccountsDelegate>> delegate_;
+ __weak id<ManageAccountsDelegate> delegate_;
};
}
@@ -390,14 +393,14 @@ WKWebView* AccountConsistencyService::GetWKWebView() {
return nil;
}
if (!web_view_) {
- web_view_.reset([BuildWKWebView() retain]);
- navigation_delegate_.reset([[AccountConsistencyNavigationDelegate alloc]
+ web_view_ = BuildWKWebView();
+ navigation_delegate_ = [[AccountConsistencyNavigationDelegate alloc]
initWithCallback:base::Bind(&AccountConsistencyService::
FinishedApplyingCookieRequest,
- base::Unretained(this), true)]);
+ base::Unretained(this), true)];
[web_view_ setNavigationDelegate:navigation_delegate_];
}
- return web_view_.get();
+ return web_view_;
}
WKWebView* AccountConsistencyService::BuildWKWebView() {
@@ -407,8 +410,8 @@ WKWebView* AccountConsistencyService::BuildWKWebView() {
void AccountConsistencyService::ResetWKWebView() {
[web_view_ setNavigationDelegate:nil];
[web_view_ stopLoading];
- web_view_.reset();
- navigation_delegate_.reset();
+ web_view_ = nil;
+ navigation_delegate_ = nil;
applying_cookie_requests_ = false;
}
@@ -459,8 +462,7 @@ void AccountConsistencyService::OnGaiaAccountsInCookieUpdated(
void AccountConsistencyService::GoogleSigninSucceeded(
const std::string& account_id,
- const std::string& username,
- const std::string& password) {
+ const std::string& username) {
AddChromeConnectedCookies();
}
diff --git a/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm b/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
index 4dcfccf52ca..f61cebd655c 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
+++ b/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
@@ -8,7 +8,6 @@
#include <memory>
-#import "base/mac/scoped_nsobject.h"
#include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/fake_signin_manager.h"
@@ -27,6 +26,10 @@
#include "third_party/ocmock/OCMock/OCMock.h"
#include "third_party/ocmock/gtest_support.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
namespace {
// URL of the Google domain where the CHROME_CONNECTED cookie is set/removed.
NSURL* const kGoogleUrl = [NSURL URLWithString:@"https://google.com/"];
@@ -63,12 +66,11 @@ class FakeAccountConsistencyService : public AccountConsistencyService {
private:
WKWebView* BuildWKWebView() override {
if (!mock_web_view_) {
- mock_web_view_.reset(
- [[OCMockObject niceMockForClass:[WKWebView class]] retain]);
+ mock_web_view_ = [OCMockObject niceMockForClass:[WKWebView class]];
}
return mock_web_view_;
}
- base::scoped_nsobject<id> mock_web_view_;
+ id mock_web_view_;
};
// Mock AccountReconcilor to catch call to OnReceivedManageAccountsResponse.
@@ -155,7 +157,7 @@ class AccountConsistencyServiceTest : public PlatformTest {
void (^continueBlock)(NSInvocation*) = ^(NSInvocation* invocation) {
if (!continue_navigation)
return;
- WKWebView* web_view = nil;
+ __unsafe_unretained WKWebView* web_view = nil;
[invocation getArgument:&web_view atIndex:0];
[GetNavigationDelegate() webView:web_view didFinishNavigation:nil];
};
@@ -236,11 +238,11 @@ TEST_F(AccountConsistencyServiceTest, SignInSignOut) {
id delegate =
[OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
NSDictionary* headers = [NSDictionary dictionary];
- base::scoped_nsobject<NSHTTPURLResponse> response([[NSHTTPURLResponse alloc]
- initWithURL:kCountryGoogleUrl
- statusCode:200
- HTTPVersion:@"HTTP/1.1"
- headerFields:headers]);
+ NSHTTPURLResponse* response =
+ [[NSHTTPURLResponse alloc] initWithURL:kCountryGoogleUrl
+ statusCode:200
+ HTTPVersion:@"HTTP/1.1"
+ headerFields:headers];
account_consistency_service_->SetWebStateHandler(&web_state_, delegate);
EXPECT_TRUE(web_state_.ShouldAllowResponse(response));
web_state_.WebStateDestroyed();
@@ -292,11 +294,11 @@ TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsNotOnGaia) {
NSDictionary* headers =
[NSDictionary dictionaryWithObject:@"action=DEFAULT"
forKey:@"X-Chrome-Manage-Accounts"];
- base::scoped_nsobject<NSHTTPURLResponse> response([[NSHTTPURLResponse alloc]
+ NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://google.com"]
statusCode:200
HTTPVersion:@"HTTP/1.1"
- headerFields:headers]);
+ headerFields:headers];
account_consistency_service_->SetWebStateHandler(&web_state_, delegate);
EXPECT_TRUE(web_state_.ShouldAllowResponse(response));
web_state_.WebStateDestroyed();
@@ -311,11 +313,11 @@ TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsNoHeader) {
[OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
NSDictionary* headers = [NSDictionary dictionary];
- base::scoped_nsobject<NSHTTPURLResponse> response([[NSHTTPURLResponse alloc]
+ NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
statusCode:200
HTTPVersion:@"HTTP/1.1"
- headerFields:headers]);
+ headerFields:headers];
account_consistency_service_->SetWebStateHandler(&web_state_, delegate);
EXPECT_TRUE(web_state_.ShouldAllowResponse(response));
web_state_.WebStateDestroyed();
@@ -335,11 +337,11 @@ TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsDefault) {
NSDictionary* headers =
[NSDictionary dictionaryWithObject:@"action=DEFAULT"
forKey:@"X-Chrome-Manage-Accounts"];
- base::scoped_nsobject<NSHTTPURLResponse> response([[NSHTTPURLResponse alloc]
+ NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
statusCode:200
HTTPVersion:@"HTTP/1.1"
- headerFields:headers]);
+ headerFields:headers];
account_consistency_service_->SetWebStateHandler(&web_state_, delegate);
EXPECT_CALL(account_reconcilor_, OnReceivedManageAccountsResponse(
signin::GAIA_SERVICE_TYPE_DEFAULT))
diff --git a/chromium/components/signin/ios/browser/merge_session_observer_bridge.h b/chromium/components/signin/ios/browser/merge_session_observer_bridge.h
index 8137dbbf1d0..ec9b10439d1 100644
--- a/chromium/components/signin/ios/browser/merge_session_observer_bridge.h
+++ b/chromium/components/signin/ios/browser/merge_session_observer_bridge.h
@@ -35,7 +35,7 @@ class MergeSessionObserverBridge : public GaiaCookieManagerService::Observer {
const GoogleServiceAuthError& error) override;
private:
- id<MergeSessionObserverBridgeDelegate> delegate_;
+ __weak id<MergeSessionObserverBridgeDelegate> delegate_;
GaiaCookieManagerService* cookie_manager_service_;
DISALLOW_COPY_AND_ASSIGN(MergeSessionObserverBridge);
diff --git a/chromium/components/signin/ios/browser/merge_session_observer_bridge.mm b/chromium/components/signin/ios/browser/merge_session_observer_bridge.mm
index 0237be1eb61..ee30039d09a 100644
--- a/chromium/components/signin/ios/browser/merge_session_observer_bridge.mm
+++ b/chromium/components/signin/ios/browser/merge_session_observer_bridge.mm
@@ -7,6 +7,10 @@
#include "base/logging.h"
#include "google_apis/gaia/google_service_auth_error.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
MergeSessionObserverBridge::MergeSessionObserverBridge(
id<MergeSessionObserverBridgeDelegate> delegate,
GaiaCookieManagerService* cookie_manager_service)
diff --git a/chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.h b/chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.h
index 04d38962310..425a9b3e90e 100644
--- a/chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.h
+++ b/chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.h
@@ -7,6 +7,7 @@
#import <Foundation/Foundation.h>
+#import "base/ios/weak_nsobject.h"
#include "base/macros.h"
#include "google_apis/gaia/oauth2_token_service.h"
@@ -49,7 +50,7 @@ class OAuth2TokenServiceObserverBridge : public OAuth2TokenService::Observer {
private:
OAuth2TokenService* token_service_; // weak
- id<OAuth2TokenServiceObserverBridgeDelegate> delegate_;
+ base::WeakNSProtocol<id<OAuth2TokenServiceObserverBridgeDelegate>> delegate_;
DISALLOW_COPY_AND_ASSIGN(OAuth2TokenServiceObserverBridge);
};
diff --git a/chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.mm b/chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.mm
index 7d649a939e9..ddaddb068d3 100644
--- a/chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.mm
+++ b/chromium/components/signin/ios/browser/oauth2_token_service_observer_bridge.mm
@@ -4,6 +4,10 @@
#include "components/signin/ios/browser/oauth2_token_service_observer_bridge.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
OAuth2TokenServiceObserverBridge::OAuth2TokenServiceObserverBridge(
OAuth2TokenService* token_service,
id<OAuth2TokenServiceObserverBridgeDelegate> delegate)
diff --git a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm
index 49606f24e79..57b10f8d544 100644
--- a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm
+++ b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.mm
@@ -27,6 +27,10 @@
#include "google_apis/gaia/oauth2_access_token_fetcher.h"
#include "net/url_request/url_request_status.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
namespace {
// Match the way Chromium handles authentication errors in
diff --git a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm
index a4043b3f022..ecfdd2c1a79 100644
--- a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm
+++ b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm
@@ -20,6 +20,10 @@
#include "net/url_request/test_url_fetcher_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
typedef ProfileOAuth2TokenServiceIOSProvider::AccountInfo ProviderAccount;
class ProfileOAuth2TokenServiceIOSDelegateTest
diff --git a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_provider.mm b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_provider.mm
index 4144c6f2ec7..0ddcca0b5fa 100644
--- a/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_provider.mm
+++ b/chromium/components/signin/ios/browser/profile_oauth2_token_service_ios_provider.mm
@@ -4,6 +4,10 @@
#include "components/signin/ios/browser/profile_oauth2_token_service_ios_provider.h"
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
std::vector<ProfileOAuth2TokenServiceIOSProvider::AccountInfo>
ProfileOAuth2TokenServiceIOSProvider::GetAllAccounts() const {
return std::vector<ProfileOAuth2TokenServiceIOSProvider::AccountInfo>();