diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-20 10:33:36 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-11-22 11:45:12 +0000 |
commit | be59a35641616a4cf23c4a13fa0632624b021c1b (patch) | |
tree | 9da183258bdf9cc413f7562079d25ace6955467f /chromium/components/signin | |
parent | d702e4b6a64574e97fc7df8fe3238cde70242080 (diff) | |
download | qtwebengine-chromium-be59a35641616a4cf23c4a13fa0632624b021c1b.tar.gz |
BASELINE: Update Chromium to 62.0.3202.101
Change-Id: I2d5eca8117600df6d331f6166ab24d943d9814ac
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/components/signin')
35 files changed, 490 insertions, 167 deletions
diff --git a/chromium/components/signin/core/browser/BUILD.gn b/chromium/components/signin/core/browser/BUILD.gn index b900638e0cf..28c5cada8b0 100644 --- a/chromium/components/signin/core/browser/BUILD.gn +++ b/chromium/components/signin/core/browser/BUILD.gn @@ -152,10 +152,16 @@ static_library("test_support") { "fake_profile_oauth2_token_service.h", "fake_signin_manager.cc", "fake_signin_manager.h", + "scoped_account_consistency.cc", + "scoped_account_consistency.h", "test_signin_client.cc", "test_signin_client.h", ] + deps = [ + "//base/test:test_support", + ] + public_deps = [ ":browser", "//base", @@ -175,6 +181,7 @@ source_set("unit_tests") { "account_investigator_unittest.cc", "account_tracker_service_unittest.cc", "gaia_cookie_manager_service_unittest.cc", + "profile_management_switches_unittest.cc", "refresh_token_annotation_request_unittest.cc", "signin_error_controller_unittest.cc", "signin_header_helper_unittest.cc", diff --git a/chromium/components/signin/core/browser/about_signin_internals.cc b/chromium/components/signin/core/browser/about_signin_internals.cc index fca6fbe2507..757a42fc059 100644 --- a/chromium/components/signin/core/browser/about_signin_internals.cc +++ b/chromium/components/signin/core/browser/about_signin_internals.cc @@ -6,8 +6,10 @@ #include <stddef.h> +#include <algorithm> #include <tuple> #include <utility> +#include <vector> #include "base/command_line.h" #include "base/hash.h" @@ -131,7 +133,7 @@ std::string SigninStatusFieldToLabel(TimedSigninStatusField field) { NOTREACHED(); return "Error"; } -#endif // !defined (OS_CHROMEOS) +#endif // !defined (OS_CHROMEOS) void SetPref(PrefService* prefs, TimedSigninStatusField field, @@ -534,7 +536,7 @@ AboutSigninInternals::SigninStatus::ToValue( AddSectionEntry(basic_info, "Chrome Version", product_version); AddSectionEntry( basic_info, "Account Consistency?", - switches::IsAccountConsistencyMirrorEnabled() == true ? "On" : "Off"); + signin::IsAccountConsistencyMirrorEnabled() == true ? "On" : "Off"); AddSectionEntry(basic_info, "Signin Status", signin_manager->IsAuthenticated() ? "Signed In" : "Not Signed In"); OAuth2TokenServiceDelegate::LoadCredentialsState load_tokens_state = @@ -632,7 +634,7 @@ AboutSigninInternals::SigninStatus::ToValue( ""); } -#endif // !defined(OS_CHROMEOS) +#endif // !defined(OS_CHROMEOS) // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 is // fixed. @@ -689,5 +691,14 @@ AboutSigninInternals::SigninStatus::ToValue( } signin_status->Set("accountInfo", std::move(account_info)); + +#if BUILDFLAG(ENABLE_DICE_SUPPORT) + if (signin::IsAccountConsistencyDiceEnabled()) { + auto dice_info = base::MakeUnique<base::DictionaryValue>(); + dice_info->SetBoolean("isSignedIn", signin_manager->IsAuthenticated()); + signin_status->Set("dice", std::move(dice_info)); + } +#endif + return signin_status; } diff --git a/chromium/components/signin/core/browser/account_reconcilor.cc b/chromium/components/signin/core/browser/account_reconcilor.cc index 3393ef7333e..3d02ebb2af5 100644 --- a/chromium/components/signin/core/browser/account_reconcilor.cc +++ b/chromium/components/signin/core/browser/account_reconcilor.cc @@ -240,7 +240,7 @@ void AccountReconcilor::GoogleSignedOut(const std::string& account_id, } void AccountReconcilor::PerformMergeAction(const std::string& account_id) { - if (!switches::IsAccountConsistencyMirrorEnabled()) { + if (!signin::IsAccountConsistencyMirrorEnabled()) { MarkAccountAsAddedToCookie(account_id); return; } @@ -249,7 +249,7 @@ void AccountReconcilor::PerformMergeAction(const std::string& account_id) { } void AccountReconcilor::PerformLogoutAllAccountsAction() { - if (!switches::IsAccountConsistencyMirrorEnabled()) + if (!signin::IsAccountConsistencyMirrorEnabled()) return; VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction"; cookie_manager_service_->LogOutAllAccounts(kSource); diff --git a/chromium/components/signin/core/browser/android/BUILD.gn b/chromium/components/signin/core/browser/android/BUILD.gn index d7d0c958299..57e1962642b 100644 --- a/chromium/components/signin/core/browser/android/BUILD.gn +++ b/chromium/components/signin/core/browser/android/BUILD.gn @@ -13,21 +13,26 @@ generate_jni("jni_headers") { android_library("java") { deps = [ + "$google_play_services_package:google_play_services_auth_base_java", + "$google_play_services_package:google_play_services_base_java", + "$google_play_services_package:google_play_services_basement_java", "//base:base_java", "//net/android:net_java", "//third_party/android_tools:android_support_annotations_java", - google_play_services_library, ] java_files = [ "java/src/org/chromium/components/signin/AccountManagerDelegate.java", + "java/src/org/chromium/components/signin/AccountManagerDelegateException.java", "java/src/org/chromium/components/signin/AccountManagerFacade.java", - "java/src/org/chromium/components/signin/AccountManagerHelper.java", + "java/src/org/chromium/components/signin/AccountManagerResult.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/GmsAvailabilityException.java", + "java/src/org/chromium/components/signin/GmsJustUpdatedException.java", + "java/src/org/chromium/components/signin/ProfileDataSource.java", "java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java", ] } @@ -40,6 +45,7 @@ android_library("javatests") { "//base:base_java", "//base:base_java_test_support", "//third_party/android_support_test_runner:runner_java", + "//third_party/junit", ] java_files = [ "javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java" ] 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 2fbdd2a0076..05c2602bc3e 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 @@ -47,7 +47,7 @@ ChildAccountInfoFetcherAndroid::ChildAccountInfoFetcherAndroid( ChildAccountInfoFetcherAndroid::~ChildAccountInfoFetcherAndroid() { Java_ChildAccountInfoFetcher_destroy(base::android::AttachCurrentThread(), - j_child_account_info_fetcher_.obj()); + j_child_account_info_fetcher_); } void SetIsChildAccount(JNIEnv* env, diff --git a/chromium/components/signin/core/browser/chrome_connected_header_helper.cc b/chromium/components/signin/core/browser/chrome_connected_header_helper.cc index 12486b67317..dde5fb6d274 100644 --- a/chromium/components/signin/core/browser/chrome_connected_header_helper.cc +++ b/chromium/components/signin/core/browser/chrome_connected_header_helper.cc @@ -131,8 +131,7 @@ bool ChromeConnectedHeaderHelper::IsUrlEligibleForRequestHeader( return false; GURL origin(url.GetOrigin()); - bool is_enable_account_consistency = - switches::IsAccountConsistencyMirrorEnabled(); + bool is_enable_account_consistency = IsAccountConsistencyMirrorEnabled(); bool is_google_url = is_enable_account_consistency && (google_util::IsGoogleDomainUrl( url, google_util::ALLOW_SUBDOMAIN, @@ -163,7 +162,7 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader( base::IntToString(profile_mode_mask).c_str())); parts.push_back(base::StringPrintf( "%s=%s", kEnableAccountConsistencyAttrName, - switches::IsAccountConsistencyMirrorEnabled() ? "true" : "false")); + IsAccountConsistencyMirrorEnabled() ? "true" : "false")); return base::JoinString(parts, is_header_request ? "," : ":"); } diff --git a/chromium/components/signin/core/browser/dice_header_helper.cc b/chromium/components/signin/core/browser/dice_header_helper.cc index 4d8aade04f2..c0bf31e26f6 100644 --- a/chromium/components/signin/core/browser/dice_header_helper.cc +++ b/chromium/components/signin/core/browser/dice_header_helper.cc @@ -37,6 +37,9 @@ DiceAction GetDiceActionFromHeader(const std::string& value) { } // namespace +DiceHeaderHelper::DiceHeaderHelper(bool signed_in_with_auth_error) + : signed_in_with_auth_error_(signed_in_with_auth_error) {} + // static DiceResponseParams DiceHeaderHelper::BuildDiceSigninResponseParams( const std::string& header_value) { @@ -127,10 +130,17 @@ DiceResponseParams DiceHeaderHelper::BuildDiceSignoutResponseParams( } bool DiceHeaderHelper::IsUrlEligibleForRequestHeader(const GURL& url) { - if (switches::GetAccountConsistencyMethod() != - switches::AccountConsistencyMethod::kDice) { + if (!IsDiceFixAuthErrorsEnabled()) + return false; + + // With kDiceFixAuthError, only set the request header if the user is signed + // in and has an authentication error. + if (!signed_in_with_auth_error_ && + (GetAccountConsistencyMethod() == + AccountConsistencyMethod::kDiceFixAuthErrors)) { return false; } + return gaia::IsGaiaSignonRealm(url.GetOrigin()); } diff --git a/chromium/components/signin/core/browser/dice_header_helper.h b/chromium/components/signin/core/browser/dice_header_helper.h index d83fa037693..bece6b77d65 100644 --- a/chromium/components/signin/core/browser/dice_header_helper.h +++ b/chromium/components/signin/core/browser/dice_header_helper.h @@ -7,6 +7,7 @@ #include <string> +#include "base/macros.h" #include "components/signin/core/browser/signin_header_helper.h" class GURL; @@ -16,7 +17,7 @@ namespace signin { // SigninHeaderHelper implementation managing the Dice header. class DiceHeaderHelper : public SigninHeaderHelper { public: - DiceHeaderHelper() {} + explicit DiceHeaderHelper(bool signed_in_with_auth_error); ~DiceHeaderHelper() override {} // Returns the parameters contained in the X-Chrome-ID-Consistency-Response @@ -37,6 +38,10 @@ class DiceHeaderHelper : public SigninHeaderHelper { private: // SigninHeaderHelper implementation: bool IsUrlEligibleForRequestHeader(const GURL& url) override; + + bool signed_in_with_auth_error_; + + DISALLOW_COPY_AND_ASSIGN(DiceHeaderHelper); }; } // namespace signin diff --git a/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc b/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc index 0e664641579..85e7d283991 100644 --- a/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc +++ b/chromium/components/signin/core/browser/gaia_cookie_manager_service.cc @@ -65,7 +65,7 @@ const int kMaxFetcherRetries = 8; // Name of the GAIA cookie that is being observed to detect when available // accounts have changed in the content-area. -const char* kGaiaCookieName = "APISID"; +const char* const kGaiaCookieName = "APISID"; enum GaiaCookieRequestType { ADD_ACCOUNT, @@ -144,11 +144,9 @@ void GaiaCookieManagerService::ExternalCcResultFetcher::Start() { helper_->gaia_auth_fetcher_->StartGetCheckConnectionInfo(); // Some fetches may timeout. Start a timer to decide when the result fetcher - // has waited long enough. - // TODO(rogerta): I have no idea how long to wait before timing out. - // Gaia folks say this should take no more than 2 second even in mobile. - // This will need to be tweaked. - timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(5), this, + // has waited long enough. See https://crbug.com/750316#c36 for details on + // exact timeout duration. + timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(7), this, &GaiaCookieManagerService::ExternalCcResultFetcher::Timeout); } @@ -234,7 +232,7 @@ GaiaCookieManagerService::ExternalCcResultFetcher::CreateFetcher( destination: GOOGLE_OWNED_SERVICE } policy { - cookies_allowed: false + cookies_allowed: NO setting: "This feature cannot be disabled in settings." policy_exception_justification: "Not implemented. Disabling GaiaCookieManager would break " diff --git a/chromium/components/signin/core/browser/gaia_cookie_manager_service.h b/chromium/components/signin/core/browser/gaia_cookie_manager_service.h index 30d0562f6b0..b9a25211e69 100644 --- a/chromium/components/signin/core/browser/gaia_cookie_manager_service.h +++ b/chromium/components/signin/core/browser/gaia_cookie_manager_service.h @@ -5,13 +5,13 @@ #ifndef COMPONENTS_SIGNIN_CORE_BROWSER_GAIA_COOKIE_MANAGER_SERVICE_H_ #define COMPONENTS_SIGNIN_CORE_BROWSER_GAIA_COOKIE_MANAGER_SERVICE_H_ -#include <deque> #include <map> #include <memory> #include <string> #include <utility> #include <vector> +#include "base/containers/circular_deque.h" #include "base/macros.h" #include "base/observer_list.h" #include "base/timer/timer.h" @@ -308,7 +308,7 @@ class GaiaCookieManagerService : public KeyedService, // A worklist for this class. Stores any pending requests that couldn't be // executed right away, since this class only permits one request to be // executed at a time. - std::deque<GaiaCookieRequest> requests_; + base::circular_deque<GaiaCookieRequest> requests_; // List of observers to notify when merge session completes. // Makes sure list is empty on destruction. diff --git a/chromium/components/signin/core/browser/profile_management_switches_unittest.cc b/chromium/components/signin/core/browser/profile_management_switches_unittest.cc new file mode 100644 index 00000000000..8119b0b009e --- /dev/null +++ b/chromium/components/signin/core/browser/profile_management_switches_unittest.cc @@ -0,0 +1,59 @@ +// 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/common/profile_management_switches.h" + +#include "base/macros.h" +#include "components/signin/core/browser/scoped_account_consistency.h" +#include "components/signin/core/common/signin_features.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace signin { + +#if BUILDFLAG(ENABLE_MIRROR) +TEST(ProfileManagementSwitchesTest, GetAccountConsistencyMethodMirror) { + // Mirror is enabled by default on some platforms. + EXPECT_EQ(AccountConsistencyMethod::kMirror, GetAccountConsistencyMethod()); + EXPECT_TRUE(IsAccountConsistencyMirrorEnabled()); + EXPECT_FALSE(IsAccountConsistencyDiceEnabled()); + EXPECT_FALSE(IsDiceFixAuthErrorsEnabled()); +} +#else +TEST(ProfileManagementSwitchesTest, GetAccountConsistencyMethod) { + // By default account consistency is disabled. + EXPECT_EQ(AccountConsistencyMethod::kDisabled, GetAccountConsistencyMethod()); + EXPECT_FALSE(IsAccountConsistencyMirrorEnabled()); + EXPECT_FALSE(IsAccountConsistencyDiceEnabled()); + EXPECT_FALSE(IsDiceFixAuthErrorsEnabled()); + + // Check that feature flags work. + struct TestCase { + AccountConsistencyMethod method; + bool expect_mirror_enabled; + bool expect_dice_fix_auth_errors; + bool expect_dice_enabled; + }; + + TestCase test_cases[] = { + {AccountConsistencyMethod::kDisabled, false, false, false}, +#if BUILDFLAG(ENABLE_DICE_SUPPORT) + {AccountConsistencyMethod::kDiceFixAuthErrors, false, true, false}, + {AccountConsistencyMethod::kDice, false, true, true}, +#endif + {AccountConsistencyMethod::kMirror, true, false, false} + }; + + for (TestCase test_case : test_cases) { + ScopedAccountConsistency scoped_method(test_case.method); + EXPECT_EQ(test_case.method, GetAccountConsistencyMethod()); + EXPECT_EQ(test_case.expect_mirror_enabled, + IsAccountConsistencyMirrorEnabled()); + EXPECT_EQ(test_case.expect_dice_fix_auth_errors, + IsDiceFixAuthErrorsEnabled()); + EXPECT_EQ(test_case.expect_dice_enabled, IsAccountConsistencyDiceEnabled()); + } +} +#endif // BUILDFLAG(ENABLE_MIRROR) + +} // namespace signin diff --git a/chromium/components/signin/core/browser/resources/signin_index.css b/chromium/components/signin/core/browser/resources/signin_index.css index ebcc78732f1..34531a7ceac 100644 --- a/chromium/components/signin/core/browser/resources/signin_index.css +++ b/chromium/components/signin/core/browser/resources/signin_index.css @@ -76,3 +76,13 @@ tr[highlighted]:nth-child(odd) { -webkit-animation-name: highlight2; -webkit-animation-timing-function: linear; } + +paper-button.dice-primary-action { + --paper-button-flat-keyboard-focus: { + background: rgb(58, 117, 215); + font-weight: 500; + margin-top: 20; + }; + background: var(--google-blue-500); + color: white; +} diff --git a/chromium/components/signin/core/browser/resources/signin_index.html b/chromium/components/signin/core/browser/resources/signin_index.html index 513a934658d..2b300d38b12 100644 --- a/chromium/components/signin/core/browser/resources/signin_index.html +++ b/chromium/components/signin/core/browser/resources/signin_index.html @@ -2,6 +2,9 @@ <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf-8"> + <link rel="import" href="chrome://resources/html/polymer.html"> + <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> + <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html"> <title>Signin Internals</title> <script src="chrome://resources/js/cr.js"></script> <script src="chrome://resources/js/util.js"></script> @@ -86,6 +89,17 @@ </table> </div> </div> + <div id="diceSection" hidden="true"> + <h2>Desktop Identity Consistency</h2> + <div class="action-container"> + <paper-button class="dice-primary-action" id="enableSyncButton"> + Enable Sync + </paper-button> + <paper-button class="dice-primary-action" id="disableSyncButton"> + Disable Sync + </paper-button> + </div> + </div> <script src="chrome://resources/js/i18n_template.js"></script> <script src="chrome://resources/js/jstemplate_compiled.js"></script> <script src="chrome://signin-internals/signin_internals.js"></script> diff --git a/chromium/components/signin/core/browser/resources/signin_internals.js b/chromium/components/signin/core/browser/resources/signin_internals.js index 5ac1b25eeb8..fb0f47c275e 100644 --- a/chromium/components/signin/core/browser/resources/signin_internals.js +++ b/chromium/components/signin/core/browser/resources/signin_internals.js @@ -161,6 +161,39 @@ for (var i = 0; i < signinFunctions.length; ++i) { chrome.signin[signinFunction] = makeSigninFunction(signinFunction); } +cr.define('chrome.signin.dice', function() { + 'use strict'; + + function initialize() { + $('enableSyncButton').addEventListener('click', function(e) { + chrome.send("enableSync"); + }); + } + + function refreshUI(signinInfo) { + var diceInfo = signinInfo.dice; + + if (diceInfo == undefined) { + $('diceSection').hidden = true; + return; + } + + $('diceSection').hidden = false; + if (diceInfo.isSignedIn) { + $('enableSyncButton').hidden = true; + $('disableSyncButton').hidden = false; + } else { + $('disableSyncButton').hidden = true; + $('enableSyncButton').hidden = false; + } + } + + return { + initialize: initialize, + refreshUI: refreshUI, + }; +}); + chrome.signin.internalsInfo = {}; // Replace the displayed values with the latest fetched ones. @@ -169,6 +202,9 @@ function refreshSigninInfo(signinInfo) { jstProcess(new JsEvalContext(signinInfo), $('signin-info')); jstProcess(new JsEvalContext(signinInfo), $('token-info')); jstProcess(new JsEvalContext(signinInfo), $('account-info')); + + // Refresh the DICE section if needed. + chrome.signin.dice.refreshUI(signinInfo); } // Replace the cookie information with the fetched values. @@ -183,6 +219,7 @@ function onLoad() { chrome.signin.onSigninInfoChanged.addListener(refreshSigninInfo); chrome.signin.onCookieAccountsFetched.addListener(updateCookieAccounts); + chrome.signin.dice.initialize(); } document.addEventListener('DOMContentLoaded', onLoad, false); diff --git a/chromium/components/signin/core/browser/scoped_account_consistency.cc b/chromium/components/signin/core/browser/scoped_account_consistency.cc new file mode 100644 index 00000000000..fbf910f9d8e --- /dev/null +++ b/chromium/components/signin/core/browser/scoped_account_consistency.cc @@ -0,0 +1,63 @@ +// 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/scoped_account_consistency.h" + +#include <map> +#include <string> +#include <utility> + +#include "base/feature_list.h" +#include "base/logging.h" +#include "base/test/scoped_feature_list.h" +#include "components/signin/core/common/signin_features.h" + +namespace signin { + +ScopedAccountConsistency::ScopedAccountConsistency( + AccountConsistencyMethod method) { +#if !BUILDFLAG(ENABLE_DICE_SUPPORT) + DCHECK_NE(AccountConsistencyMethod::kDice, method); + DCHECK_NE(AccountConsistencyMethod::kDiceFixAuthErrors, method); +#endif + +#if BUILDFLAG(ENABLE_MIRROR) + DCHECK_EQ(AccountConsistencyMethod::kMirror, method); + return; +#endif + + if (method == AccountConsistencyMethod::kDisabled) { + scoped_feature_list_.InitAndDisableFeature(kAccountConsistencyFeature); + DCHECK_EQ(method, GetAccountConsistencyMethod()); + return; + } + + // Set up the account consistency method. + std::string feature_value; + switch (method) { + case AccountConsistencyMethod::kDisabled: + NOTREACHED(); + break; + case AccountConsistencyMethod::kMirror: + feature_value = kAccountConsistencyFeatureMethodMirror; + break; + case AccountConsistencyMethod::kDiceFixAuthErrors: + feature_value = kAccountConsistencyFeatureMethodDiceFixAuthErrors; + break; + case AccountConsistencyMethod::kDice: + feature_value = kAccountConsistencyFeatureMethodDice; + break; + } + + std::map<std::string, std::string> feature_params; + feature_params[kAccountConsistencyFeatureMethodParameter] = feature_value; + + scoped_feature_list_.InitAndEnableFeatureWithParameters( + kAccountConsistencyFeature, feature_params); + DCHECK_EQ(method, GetAccountConsistencyMethod()); +} + +ScopedAccountConsistency::~ScopedAccountConsistency() {} + +} // namespace signin diff --git a/chromium/components/signin/core/browser/scoped_account_consistency.h b/chromium/components/signin/core/browser/scoped_account_consistency.h new file mode 100644 index 00000000000..0c4938d2314 --- /dev/null +++ b/chromium/components/signin/core/browser/scoped_account_consistency.h @@ -0,0 +1,56 @@ +// 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_SCOPED_ACCOUNT_CONSISTENCY_H_ +#define COMPONENTS_SIGNIN_CORE_BROWSER_SCOPED_ACCOUNT_CONSISTENCY_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/test/scoped_feature_list.h" +#include "components/signin/core/common/profile_management_switches.h" + +namespace signin { + +// Changes the account consistency method while it is in scope. Useful for +// tests. +class ScopedAccountConsistency { + public: + explicit ScopedAccountConsistency(AccountConsistencyMethod method); + ~ScopedAccountConsistency(); + + private: + base::test::ScopedFeatureList scoped_feature_list_; + + DISALLOW_COPY_AND_ASSIGN(ScopedAccountConsistency); +}; + +// Specialized helper classes for each account consistency method: +// ScopedAccountConsistencyDice, ScopedAccountConsistencyMirror, ... + +#define SCOPED_ACCOUNT_CONSISTENCY_SPECIALIZATION(method) \ + class ScopedAccountConsistency##method { \ + public: \ + ScopedAccountConsistency##method() \ + : scoped_consistency_(AccountConsistencyMethod::k##method) {} \ + \ + private: \ + ScopedAccountConsistency scoped_consistency_; \ + DISALLOW_COPY_AND_ASSIGN(ScopedAccountConsistency##method); \ + } + +// ScopedAccountConsistencyDisabled: +SCOPED_ACCOUNT_CONSISTENCY_SPECIALIZATION(Disabled); +// ScopedAccountConsistencyMirror: +SCOPED_ACCOUNT_CONSISTENCY_SPECIALIZATION(Mirror); +// ScopedAccountConsistencyDiceFixAuthErrors: +SCOPED_ACCOUNT_CONSISTENCY_SPECIALIZATION(DiceFixAuthErrors); +// ScopedAccountConsistencyDice: +SCOPED_ACCOUNT_CONSISTENCY_SPECIALIZATION(Dice); + +#undef SCOPED_ACCOUNT_CONSISTENCY_SPECIALIZATION + +} // namespace signin + +#endif // COMPONENTS_SIGNIN_CORE_BROWSER_SCOPED_ACCOUNT_CONSISTENCY_H_ diff --git a/chromium/components/signin/core/browser/signin_header_helper.cc b/chromium/components/signin/core/browser/signin_header_helper.cc index 0a326c1f807..ef836c4158f 100644 --- a/chromium/components/signin/core/browser/signin_header_helper.cc +++ b/chromium/components/signin/core/browser/signin_header_helper.cc @@ -24,8 +24,9 @@ namespace signin { -extern const char kChromeConnectedHeader[] = "X-Chrome-Connected"; -extern const char kDiceRequestHeader[] = "X-Chrome-ID-Consistency-Request"; +const char kChromeConnectedHeader[] = "X-Chrome-Connected"; +const char kDiceRequestHeader[] = "X-Chrome-ID-Consistency-Request"; +const char kDiceResponseHeader[] = "X-Chrome-ID-Consistency-Response"; ManageAccountsParams::ManageAccountsParams() : service_type(GAIA_SERVICE_TYPE_NONE), @@ -125,16 +126,17 @@ bool SigninHeaderHelper::ShouldBuildRequestHeader( return true; } -void AppendOrRemoveAccountConsistentyRequestHeader( +void AppendOrRemoveAccountConsistencyRequestHeader( net::URLRequest* request, const GURL& redirect_url, const std::string& account_id, bool sync_enabled, + bool sync_has_auth_error, 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; + DiceHeaderHelper dice_helper(!account_id.empty() && sync_has_auth_error); std::string dice_header_value; if (dice_helper.ShouldBuildRequestHeader(url, cookie_settings)) { dice_header_value = diff --git a/chromium/components/signin/core/browser/signin_header_helper.h b/chromium/components/signin/core/browser/signin_header_helper.h index 06b72cb3ad6..1e43ebb975f 100644 --- a/chromium/components/signin/core/browser/signin_header_helper.h +++ b/chromium/components/signin/core/browser/signin_header_helper.h @@ -33,6 +33,7 @@ enum ProfileMode { extern const char kChromeConnectedHeader[]; extern const char kDiceRequestHeader[]; +extern const char kDiceResponseHeader[]; // 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 @@ -159,11 +160,12 @@ std::string BuildMirrorRequestCookieIfPossible( // 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. -void AppendOrRemoveAccountConsistentyRequestHeader( +void AppendOrRemoveAccountConsistencyRequestHeader( net::URLRequest* request, const GURL& redirect_url, const std::string& account_id, bool sync_enabled, + bool sync_has_auth_error, const content_settings::CookieSettings* cookie_settings, int profile_mode_mask); 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 bade766e6fb..e6965ea651f 100644 --- a/chromium/components/signin/core/browser/signin_header_helper_unittest.cc +++ b/chromium/components/signin/core/browser/signin_header_helper_unittest.cc @@ -12,6 +12,7 @@ #include "base/strings/stringprintf.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/signin/core/browser/chrome_connected_header_helper.h" +#include "components/signin/core/browser/scoped_account_consistency.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" @@ -51,15 +52,15 @@ class SigninHeaderHelperTest : public testing::Test { expected_request); } - std::unique_ptr<net::URLRequest> CreateRequest(const GURL& url, - const std::string& account_id, - bool sync_enabled) { + std::unique_ptr<net::URLRequest> CreateRequest( + const GURL& url, + const std::string& account_id) { std::unique_ptr<net::URLRequest> url_request = url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); - AppendOrRemoveAccountConsistentyRequestHeader( - url_request.get(), GURL(), account_id, sync_enabled, - cookie_settings_.get(), PROFILE_MODE_DEFAULT); + AppendOrRemoveAccountConsistencyRequestHeader( + url_request.get(), GURL(), account_id, sync_enabled_, + sync_has_auth_error_, cookie_settings_.get(), PROFILE_MODE_DEFAULT); return url_request; } @@ -71,7 +72,8 @@ class SigninHeaderHelperTest : public testing::Test { std::string request; EXPECT_EQ( url_request->extra_request_headers().GetHeader(header_name, &request), - expected_result); + expected_result) + << header_name << ": " << request; if (expected_result) { EXPECT_EQ(expected_request, request); } @@ -81,7 +83,7 @@ class SigninHeaderHelperTest : public testing::Test { const std::string& account_id, const std::string& expected_request) { std::unique_ptr<net::URLRequest> url_request = - CreateRequest(url, account_id, false /* sync_enabled */); + CreateRequest(url, account_id); CheckAccountConsistencyHeaderRequest( url_request.get(), kChromeConnectedHeader, expected_request); } @@ -89,11 +91,10 @@ class SigninHeaderHelperTest : public testing::Test { #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); + CreateRequest(url, account_id); CheckAccountConsistencyHeaderRequest( url_request.get(), kChromeConnectedHeader, expected_mirror_request); CheckAccountConsistencyHeaderRequest(url_request.get(), kDiceRequestHeader, @@ -103,6 +104,9 @@ class SigninHeaderHelperTest : public testing::Test { base::MessageLoop loop_; + bool sync_enabled_ = false; + bool sync_has_auth_error_ = false; + sync_preferences::TestingPrefServiceSyncable prefs_; net::TestURLRequestContext url_request_context_; @@ -113,8 +117,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::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "", ""); CheckMirrorCookieRequest(GURL("https://docs.google.com"), "", ""); } @@ -122,8 +125,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::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK); CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "0123456789", ""); CheckMirrorCookieRequest(GURL("https://docs.google.com"), "0123456789", ""); @@ -131,8 +133,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::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; CheckMirrorHeaderRequest(GURL("https://foo.com"), "0123456789", ""); CheckMirrorCookieRequest(GURL("https://foo.com"), "0123456789", ""); } @@ -140,8 +141,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::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; CheckMirrorHeaderRequest(GURL("https://google.fr"), "0123456789", "mode=0,enable_account_consistency=true"); CheckMirrorCookieRequest(GURL("https://google.de"), "0123456789", @@ -151,8 +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::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; CheckMirrorHeaderRequest(GURL("https://www.google.com"), "0123456789", "mode=0,enable_account_consistency=true"); CheckMirrorCookieRequest( @@ -167,7 +166,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleCom) { // 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()); + ASSERT_FALSE(IsAccountConsistencyMirrorEnabled()); CheckMirrorHeaderRequest(GURL("https://accounts.google.com"), "0123456789", "mode=0,enable_account_consistency=false"); CheckMirrorCookieRequest( @@ -177,11 +176,10 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGaiaURL) { // Tests Dice requests. TEST_F(SigninHeaderHelperTest, TestDiceRequest) { - switches::EnableAccountConsistencyDiceForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyDice scoped_dice; // ChromeConnected but no Dice for Docs URLs. CheckDiceHeaderRequest( - GURL("https://docs.google.com"), "0123456789", false /* sync_enabled */, + GURL("https://docs.google.com"), "0123456789", "id=0123456789,mode=0,enable_account_consistency=false", ""); // ChromeConnected and Dice for Gaia URLs. @@ -189,34 +187,48 @@ TEST_F(SigninHeaderHelperTest, TestDiceRequest) { 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. + sync_enabled_ = true; CheckDiceHeaderRequest( GURL("https://accounts.google.com"), "0123456789", - true /* sync_enabled */, "mode=0,enable_account_consistency=false", + "mode=0,enable_account_consistency=false", "client_id=" + client_id + ",sync_account_id=0123456789"); + sync_enabled_ = false; // No ChromeConnected and no Dice for other URLs. - CheckDiceHeaderRequest(GURL("https://www.google.com"), "0123456789", - false /* sync_enabled */, "", ""); + CheckDiceHeaderRequest(GURL("https://www.google.com"), "0123456789", "", ""); } // Tests that no Dice request is returned when Dice is not enabled. TEST_F(SigninHeaderHelperTest, TestNoDiceRequestWhenDisabled) { - switches::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; CheckDiceHeaderRequest(GURL("https://accounts.google.com"), "0123456789", - false /* sync_enabled */, "mode=0,enable_account_consistency=true", ""); } +// Tests that a Dice request is returned only when there is an authentication +// error if the method is kDiceFixAuthErrors. +TEST_F(SigninHeaderHelperTest, TestDiceFixAuthError) { + ScopedAccountConsistencyDiceFixAuthErrors scoped_dice_fix_auth_errors; + // Without authentication error, no Dice request. + CheckDiceHeaderRequest(GURL("https://accounts.google.com"), "0123456789", + "mode=0,enable_account_consistency=false", ""); + + // With authentication error, there is a Dice request. + sync_has_auth_error_ = true; + CheckDiceHeaderRequest( + GURL("https://accounts.google.com"), "0123456789", + "mode=0,enable_account_consistency=false", + "client_id=" + GaiaUrls::GetInstance()->oauth2_chrome_client_id()); +} + // Tests that the Mirror request is returned with the GAIA Id on Drive origin, // even if account consistency is disabled. TEST_F(SigninHeaderHelperTest, TestMirrorRequestDrive) { - ASSERT_FALSE(switches::IsAccountConsistencyMirrorEnabled()); + ASSERT_FALSE(IsAccountConsistencyMirrorEnabled()); CheckMirrorHeaderRequest( GURL("https://docs.google.com/document"), "0123456789", "id=0123456789,mode=0,enable_account_consistency=false"); @@ -225,8 +237,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestDrive) { "id=0123456789:mode=0:enable_account_consistency=false"); // Enable Account Consistency will override the disable. - switches::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; CheckMirrorHeaderRequest( GURL("https://docs.google.com/document"), "0123456789", "id=0123456789,mode=0,enable_account_consistency=true"); @@ -329,17 +340,16 @@ TEST_F(SigninHeaderHelperTest, TestBuildDiceResponseParams) { // Tests that the Mirror header request is returned normally when the redirect // URL is eligible. TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) { - switches::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; const GURL url("https://docs.google.com/document"); const GURL redirect_url("https://www.google.com"); const std::string account_id = "0123456789"; std::unique_ptr<net::URLRequest> url_request = url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); - AppendOrRemoveAccountConsistentyRequestHeader( - url_request.get(), redirect_url, account_id, false /* sync_enabled */, - cookie_settings_.get(), PROFILE_MODE_DEFAULT); + AppendOrRemoveAccountConsistencyRequestHeader( + url_request.get(), redirect_url, account_id, sync_enabled_, + sync_has_auth_error_, cookie_settings_.get(), PROFILE_MODE_DEFAULT); EXPECT_TRUE( url_request->extra_request_headers().HasHeader(kChromeConnectedHeader)); } @@ -347,17 +357,16 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) { // Tests that the Mirror header request is stripped when the redirect URL is not // eligible. TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) { - switches::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; const GURL url("https://docs.google.com/document"); const GURL redirect_url("http://www.foo.com"); const std::string account_id = "0123456789"; std::unique_ptr<net::URLRequest> url_request = url_request_context_.CreateRequest(url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS); - AppendOrRemoveAccountConsistentyRequestHeader( - url_request.get(), redirect_url, account_id, false /* sync_enabled */, - cookie_settings_.get(), PROFILE_MODE_DEFAULT); + AppendOrRemoveAccountConsistencyRequestHeader( + url_request.get(), redirect_url, account_id, sync_enabled_, + sync_has_auth_error_, cookie_settings_.get(), PROFILE_MODE_DEFAULT); EXPECT_FALSE( url_request->extra_request_headers().HasHeader(kChromeConnectedHeader)); } @@ -365,8 +374,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) { // 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::EnableAccountConsistencyMirrorForTesting( - base::CommandLine::ForCurrentProcess()); + ScopedAccountConsistencyMirror scoped_mirror; const GURL url("https://www.bar.com"); const GURL redirect_url("http://www.foo.com"); const std::string account_id = "0123456789"; @@ -376,9 +384,9 @@ TEST_F(SigninHeaderHelperTest, TestIgnoreMirrorHeaderNonEligibleURLs) { TRAFFIC_ANNOTATION_FOR_TESTS); url_request->SetExtraRequestHeaderByName(kChromeConnectedHeader, fake_header, false); - AppendOrRemoveAccountConsistentyRequestHeader( - url_request.get(), redirect_url, account_id, false /* sync_enabled */, - cookie_settings_.get(), PROFILE_MODE_DEFAULT); + AppendOrRemoveAccountConsistencyRequestHeader( + url_request.get(), redirect_url, account_id, sync_enabled_, + sync_has_auth_error_, cookie_settings_.get(), PROFILE_MODE_DEFAULT); std::string header; EXPECT_TRUE(url_request->extra_request_headers().GetHeader( kChromeConnectedHeader, &header)); diff --git a/chromium/components/signin/core/browser/signin_manager.cc b/chromium/components/signin/core/browser/signin_manager.cc index 5ced3207823..60f309fc6a4 100644 --- a/chromium/components/signin/core/browser/signin_manager.cc +++ b/chromium/components/signin/core/browser/signin_manager.cc @@ -376,8 +376,11 @@ void SigninManager::OnExternalSigninCompleted(const std::string& username) { } void SigninManager::OnSignedIn() { + bool reauth_in_progress = IsAuthenticated(); + client_->GetPrefs()->SetInt64(prefs::kSignedInTime, base::Time::Now().ToInternalValue()); + SetAuthenticatedAccountInfo(possibly_invalid_gaia_id_, possibly_invalid_email_); const std::string gaia_id = possibly_invalid_gaia_id_; @@ -387,14 +390,8 @@ void SigninManager::OnSignedIn() { possibly_invalid_email_.clear(); signin_manager_signed_in_ = true; - for (auto& observer : observer_list_) { - observer.GoogleSigninSucceeded(GetAuthenticatedAccountId(), - GetAuthenticatedAccountInfo().email); - - observer.GoogleSigninSucceededWithPassword( - GetAuthenticatedAccountId(), GetAuthenticatedAccountInfo().email, - password_); - } + if (!reauth_in_progress) + FireGoogleSigninSucceeded(); client_->OnSignedIn(GetAuthenticatedAccountId(), gaia_id, GetAuthenticatedAccountInfo().email, password_); @@ -407,6 +404,15 @@ void SigninManager::OnSignedIn() { PostSignedIn(); } +void SigninManager::FireGoogleSigninSucceeded() { + std::string account_id = GetAuthenticatedAccountId(); + std::string email = GetAuthenticatedAccountInfo().email; + for (auto& observer : observer_list_) { + observer.GoogleSigninSucceeded(account_id, email); + observer.GoogleSigninSucceededWithPassword(account_id, email, password_); + } +} + void SigninManager::PostSignedIn() { if (!signin_manager_signed_in_ || !user_info_fetched_by_account_tracker_) return; diff --git a/chromium/components/signin/core/browser/signin_manager.h b/chromium/components/signin/core/browser/signin_manager.h index bae32cf78e4..7ec3c3f69cf 100644 --- a/chromium/components/signin/core/browser/signin_manager.h +++ b/chromium/components/signin/core/browser/signin_manager.h @@ -184,15 +184,18 @@ class SigninManager : public SigninManagerBase, // a sign-in success notification. void OnSignedIn(); + // Send all observers |GoogleSigninSucceeded| notifications. + void FireGoogleSigninSucceeded(); + // Waits for the AccountTrackerService, then sends GoogleSigninSucceeded to // the client and clears the local password. void PostSignedIn(); - // AccountTrackerService::Observer implementation. + // AccountTrackerService::Observer: void OnAccountUpdated(const AccountInfo& info) override; void OnAccountUpdateFailed(const std::string& account_id) override; - // OAuth2TokenService::Observer + // OAuth2TokenService::Observer: void OnRefreshTokensLoaded() override; // Called when a new request to re-authenticate a user is in progress. diff --git a/chromium/components/signin/core/browser/signin_manager_base.cc b/chromium/components/signin/core/browser/signin_manager_base.cc index 14ad0380e7a..bb6331147f3 100644 --- a/chromium/components/signin/core/browser/signin_manager_base.cc +++ b/chromium/components/signin/core/browser/signin_manager_base.cc @@ -184,9 +184,9 @@ void SigninManagerBase::SetAuthenticatedAccountId( const std::string& account_id) { DCHECK(!account_id.empty()); if (!authenticated_account_id_.empty()) { - DLOG_IF(ERROR, account_id != authenticated_account_id_) - << "Tried to change the authenticated id to something different: " - << "Current: " << authenticated_account_id_ << ", New: " << account_id; + DCHECK_EQ(account_id, authenticated_account_id_) + << "Changing the authenticated account while authenticated is not " + "allowed."; return; } diff --git a/chromium/components/signin/core/browser/signin_manager_base.h b/chromium/components/signin/core/browser/signin_manager_base.h index a7c08678e66..690c209591f 100644 --- a/chromium/components/signin/core/browser/signin_manager_base.h +++ b/chromium/components/signin/core/browser/signin_manager_base.h @@ -59,6 +59,7 @@ class SigninManagerBase : public KeyedService { virtual void GoogleSigninFailed(const GoogleServiceAuthError& error) {} // Called when a user signs into Google services such as sync. + // This method is not called during a reauth. virtual void GoogleSigninSucceeded(const std::string& account_id, const std::string& username) {} @@ -81,6 +82,7 @@ class SigninManagerBase : public KeyedService { // 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. + // This method is not called during a reauth. // // Observers should override |GoogleSigninSucceeded| if they are not // interested in the password thas was used during the sign-in. @@ -175,6 +177,10 @@ class SigninManagerBase : public KeyedService { } // Sets the authenticated user's account id. + // If the user is already authenticated with the same account id, then this + // method is a no-op. + // It is forbidden to call this method if the user is already authenticated + // with a different account (this method will DCHECK in that case). void SetAuthenticatedAccountId(const std::string& account_id); // Used by subclass to clear the authenticated user instead of using diff --git a/chromium/components/signin/core/browser/signin_metrics.cc b/chromium/components/signin/core/browser/signin_metrics.cc index d754cf87a30..7daf5965000 100644 --- a/chromium/components/signin/core/browser/signin_metrics.cc +++ b/chromium/components/signin/core/browser/signin_metrics.cc @@ -186,7 +186,7 @@ void LogAuthError(GoogleServiceAuthError::State auth_error) { GoogleServiceAuthError::State::NUM_STATES); } -void LogSigninConfirmHistogramValue(int action) { +void LogSigninConfirmHistogramValue(ConfirmationUsage action) { UMA_HISTOGRAM_ENUMERATION("Signin.OneClickConfirmation", action, signin_metrics::HISTOGRAM_CONFIRM_MAX); } diff --git a/chromium/components/signin/core/browser/signin_metrics.h b/chromium/components/signin/core/browser/signin_metrics.h index cc6709e2958..bcaa972e98c 100644 --- a/chromium/components/signin/core/browser/signin_metrics.h +++ b/chromium/components/signin/core/browser/signin_metrics.h @@ -53,7 +53,7 @@ enum ProfileSignout { }; // Enum values used for use with "AutoLogin.Reverse" histograms. -enum { +enum AccessPointAction { // The infobar was shown to the user. HISTOGRAM_SHOWN, // The user pressed the accept button to perform the suggested action. @@ -82,7 +82,7 @@ enum { // Enum values used with the "Signin.OneClickConfirmation" histogram, which // tracks the actions used in the OneClickConfirmation bubble. -enum { +enum ConfirmationUsage { HISTOGRAM_CONFIRM_SHOWN, HISTOGRAM_CONFIRM_OK, HISTOGRAM_CONFIRM_RETURN, @@ -353,7 +353,7 @@ void LogExternalCcResultFetches( // Track when the current authentication error changed. void LogAuthError(GoogleServiceAuthError::State auth_error); -void LogSigninConfirmHistogramValue(int action); +void LogSigninConfirmHistogramValue(ConfirmationUsage action); void LogXDevicePromoEligible(CrossDevicePromoEligibility metric); 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 8ead61c4a97..1b499cd3411 100644 --- a/chromium/components/signin/core/browser/signin_status_metrics_provider.cc +++ b/chromium/components/signin/core/browser/signin_status_metrics_provider.cc @@ -35,7 +35,7 @@ SigninStatusMetricsProvider::SigninStatusMetricsProvider( SigninStatusMetricsProvider::~SigninStatusMetricsProvider() {} -void SigninStatusMetricsProvider::ProvideGeneralMetrics( +void SigninStatusMetricsProvider::ProvideCurrentSessionData( metrics::ChromeUserMetricsExtension* uma_proto) { RecordSigninStatusHistogram(signin_status()); // After a histogram value is recorded, a new UMA session will be started, so 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 ee6f0adf6ba..73cd0a4d676 100644 --- a/chromium/components/signin/core/browser/signin_status_metrics_provider.h +++ b/chromium/components/signin/core/browser/signin_status_metrics_provider.h @@ -33,7 +33,7 @@ class SigninStatusMetricsProvider : public SigninStatusMetricsProviderBase, ~SigninStatusMetricsProvider() override; // SigninStatusMetricsProviderBase: - void ProvideGeneralMetrics( + void ProvideCurrentSessionData( metrics::ChromeUserMetricsExtension* uma_proto) override; // Factory method, creates a new instance of this class. diff --git a/chromium/components/signin/core/browser/webdata/token_service_table_unittest.cc b/chromium/components/signin/core/browser/webdata/token_service_table_unittest.cc index 47391e47637..32d169a839a 100644 --- a/chromium/components/signin/core/browser/webdata/token_service_table_unittest.cc +++ b/chromium/components/signin/core/browser/webdata/token_service_table_unittest.cc @@ -21,7 +21,7 @@ class TokenServiceTableTest : public testing::Test { protected: void SetUp() override { - OSCryptMocker::SetUpWithSingleton(); + OSCryptMocker::SetUp(); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); file_ = temp_dir_.GetPath().AppendASCII("TestWebDatabase"); diff --git a/chromium/components/signin/core/browser/webdata/token_web_data.cc b/chromium/components/signin/core/browser/webdata/token_web_data.cc index d8c405f0605..cb53ca68c96 100644 --- a/chromium/components/signin/core/browser/webdata/token_web_data.cc +++ b/chromium/components/signin/core/browser/webdata/token_web_data.cc @@ -18,8 +18,9 @@ using base::Time; class TokenWebDataBackend : public base::RefCountedDeleteOnSequence<TokenWebDataBackend> { public: - TokenWebDataBackend(scoped_refptr<base::SingleThreadTaskRunner> db_thread) - : base::RefCountedDeleteOnSequence<TokenWebDataBackend>(db_thread) {} + TokenWebDataBackend( + scoped_refptr<base::SingleThreadTaskRunner> db_task_runner) + : base::RefCountedDeleteOnSequence<TokenWebDataBackend>(db_task_runner) {} WebDatabase::State RemoveAllTokens(WebDatabase* db) { if (TokenServiceTable::FromWebDatabase(db)->RemoveAllTokens()) { @@ -69,12 +70,11 @@ TokenResult::~TokenResult(){}; TokenWebData::TokenWebData( scoped_refptr<WebDatabaseService> wdbs, - scoped_refptr<base::SingleThreadTaskRunner> ui_thread, - scoped_refptr<base::SingleThreadTaskRunner> db_thread, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> db_task_runner, const ProfileErrorCallback& callback) - : WebDataServiceBase(wdbs, callback, ui_thread), - token_backend_(new TokenWebDataBackend(db_thread)) { -} + : WebDataServiceBase(wdbs, callback, ui_task_runner), + token_backend_(new TokenWebDataBackend(db_task_runner)) {} void TokenWebData::SetTokenForService(const std::string& service, const std::string& token) { @@ -102,11 +102,10 @@ WebDataServiceBase::Handle TokenWebData::GetAllTokens( } TokenWebData::TokenWebData( - scoped_refptr<base::SingleThreadTaskRunner> ui_thread, - scoped_refptr<base::SingleThreadTaskRunner> db_thread) - : WebDataServiceBase(NULL, ProfileErrorCallback(), ui_thread), - token_backend_(new TokenWebDataBackend(db_thread)) { -} + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> db_task_runner) + : WebDataServiceBase(NULL, ProfileErrorCallback(), ui_task_runner), + token_backend_(new TokenWebDataBackend(db_task_runner)) {} TokenWebData::~TokenWebData() { } diff --git a/chromium/components/signin/core/browser/webdata/token_web_data.h b/chromium/components/signin/core/browser/webdata/token_web_data.h index f47f371c252..39bb6af92a9 100644 --- a/chromium/components/signin/core/browser/webdata/token_web_data.h +++ b/chromium/components/signin/core/browser/webdata/token_web_data.h @@ -47,12 +47,12 @@ struct TokenResult { class TokenWebData : public WebDataServiceBase { public: TokenWebData(scoped_refptr<WebDatabaseService> wdbs, - scoped_refptr<base::SingleThreadTaskRunner> ui_thread, - scoped_refptr<base::SingleThreadTaskRunner> db_thread, + scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> db_task_runner, const ProfileErrorCallback& callback); - TokenWebData(scoped_refptr<base::SingleThreadTaskRunner> ui_thread, - scoped_refptr<base::SingleThreadTaskRunner> db_thread); + TokenWebData(scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> db_task_runner); // Set a token to use for a specified service. void SetTokenForService(const std::string& service, diff --git a/chromium/components/signin/core/common/profile_management_switches.cc b/chromium/components/signin/core/common/profile_management_switches.cc index 61dd356e6c0..b8ea88e432b 100644 --- a/chromium/components/signin/core/common/profile_management_switches.cc +++ b/chromium/components/signin/core/common/profile_management_switches.cc @@ -7,25 +7,40 @@ #include <string> #include "base/command_line.h" -#include "base/feature_list.h" -#include "base/metrics/field_trial.h" +#include "base/logging.h" +#include "base/metrics/field_trial_params.h" #include "build/build_config.h" +#include "components/signin/core/common/signin_features.h" #include "components/signin/core/common/signin_switches.h" -namespace switches { +namespace signin { + +// base::Feature definitions. +const base::Feature kAccountConsistencyFeature{ + "AccountConsistency", base::FEATURE_DISABLED_BY_DEFAULT}; +const char kAccountConsistencyFeatureMethodParameter[] = "method"; +const char kAccountConsistencyFeatureMethodMirror[] = "mirror"; +const char kAccountConsistencyFeatureMethodDiceFixAuthErrors[] = + "dice_fix_auth_errors"; +const char kAccountConsistencyFeatureMethodDice[] = "dice"; AccountConsistencyMethod GetAccountConsistencyMethod() { #if BUILDFLAG(ENABLE_MIRROR) - // Mirror is enabled on Android and iOS. + // Mirror is always enabled on Android and iOS. return AccountConsistencyMethod::kMirror; #else - base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); - std::string method = cmd->GetSwitchValueASCII(switches::kAccountConsistency); - if (method == switches::kAccountConsistencyMirror) - return AccountConsistencyMethod::kMirror; + if (!base::FeatureList::IsEnabled(kAccountConsistencyFeature)) + return AccountConsistencyMethod::kDisabled; + std::string method_value = base::GetFieldTrialParamValueByFeature( + kAccountConsistencyFeature, kAccountConsistencyFeatureMethodParameter); + + if (method_value == kAccountConsistencyFeatureMethodMirror) + return AccountConsistencyMethod::kMirror; #if BUILDFLAG(ENABLE_DICE_SUPPORT) - if (method == switches::kAccountConsistencyDice) + else if (method_value == kAccountConsistencyFeatureMethodDiceFixAuthErrors) + return AccountConsistencyMethod::kDiceFixAuthErrors; + else if (method_value == kAccountConsistencyFeatureMethodDice) return AccountConsistencyMethod::kDice; #endif @@ -38,7 +53,13 @@ bool IsAccountConsistencyMirrorEnabled() { } bool IsAccountConsistencyDiceEnabled() { - return GetAccountConsistencyMethod() == AccountConsistencyMethod::kDice; + return (GetAccountConsistencyMethod() == AccountConsistencyMethod::kDice); +} + +bool IsDiceFixAuthErrorsEnabled() { + AccountConsistencyMethod method = GetAccountConsistencyMethod(); + return (method == AccountConsistencyMethod::kDiceFixAuthErrors) || + (method == AccountConsistencyMethod::kDice); } bool IsExtensionsMultiAccount() { @@ -53,18 +74,4 @@ bool IsExtensionsMultiAccount() { GetAccountConsistencyMethod() == AccountConsistencyMethod::kMirror; } -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 +} // namespace signin diff --git a/chromium/components/signin/core/common/profile_management_switches.h b/chromium/components/signin/core/common/profile_management_switches.h index 9642ef5b0ce..7b379269cd5 100644 --- a/chromium/components/signin/core/common/profile_management_switches.h +++ b/chromium/components/signin/core/common/profile_management_switches.h @@ -9,18 +9,28 @@ #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" +#include "base/feature_list.h" -namespace base { -class CommandLine; -} +namespace signin { -namespace switches { +// Account consistency feature. Only used on platforms where Mirror is not +// always enabled (ENABLE_MIRROR is false). +extern const base::Feature kAccountConsistencyFeature; + +// The account consistency method parameter name. +extern const char kAccountConsistencyFeatureMethodParameter[]; + +// Account consistency method values. +extern const char kAccountConsistencyFeatureMethodMirror[]; +extern const char kAccountConsistencyFeatureMethodDiceFixAuthErrors[]; +extern const char kAccountConsistencyFeatureMethodDice[]; enum class AccountConsistencyMethod { - kDisabled, // No account consistency. - kMirror, // Account management UI in the avatar bubble. - kDice // Account management UI on Gaia webpages. + kDisabled, // No account consistency. + kMirror, // Account management UI in the avatar bubble. + kDiceFixAuthErrors, // No account consistency, but Dice fixes authentication + // errors. + kDice // Account management UI on Gaia webpages. }; // Returns the account consistency method. @@ -32,19 +42,17 @@ bool IsAccountConsistencyMirrorEnabled(); // Checks whether Dice account consistency is enabled. If enabled, then account // management UI is available on the Gaia webpages. +// Returns true when the account consistency method is kDice. +// WARNING: returns false when the method is kDiceFixAuthErrors. bool IsAccountConsistencyDiceEnabled(); +// Returns true if the account consistency method is kDiceFixAuthErrors or +// kDice. +bool IsDiceFixAuthErrorsEnabled(); + // Whether the chrome.identity API should be multi-account. bool IsExtensionsMultiAccount(); -// 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 +} // namespace signin #endif // COMPONENTS_SIGNIN_CORE_COMMON_PROFILE_MANAGEMENT_SWITCHES_H_ diff --git a/chromium/components/signin/ios/browser/account_consistency_service.h b/chromium/components/signin/ios/browser/account_consistency_service.h index 8df4874f76b..e05b4c78228 100644 --- a/chromium/components/signin/ios/browser/account_consistency_service.h +++ b/chromium/components/signin/ios/browser/account_consistency_service.h @@ -5,12 +5,12 @@ #ifndef COMPONENTS_SIGNIN_IOS_BROWSER_ACCOUNT_CONSISTENCY_SERVICE_H_ #define COMPONENTS_SIGNIN_IOS_BROWSER_ACCOUNT_CONSISTENCY_SERVICE_H_ -#include <deque> #include <map> #include <memory> #include <set> #include <string> +#include "base/containers/circular_deque.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" @@ -170,7 +170,7 @@ class AccountConsistencyService : public KeyedService, // Whether a CHROME_CONNECTED cookie request is currently being applied. bool applying_cookie_requests_; // The queue of CHROME_CONNECTED cookie requests to be applied. - std::deque<CookieRequest> cookie_requests_; + base::circular_deque<CookieRequest> cookie_requests_; // The map between domains where a CHROME_CONNECTED cookie is present and // the time when the cookie was last updated. std::map<std::string, base::Time> last_cookie_update_map_; diff --git a/chromium/components/signin/ios/browser/account_consistency_service.mm b/chromium/components/signin/ios/browser/account_consistency_service.mm index a56cc1b8626..cf4ab48e794 100644 --- a/chromium/components/signin/ios/browser/account_consistency_service.mm +++ b/chromium/components/signin/ios/browser/account_consistency_service.mm @@ -56,7 +56,8 @@ class AccountConsistencyHandler : public web::WebStatePolicyDecider { private: // web::WebStatePolicyDecider override - bool ShouldAllowResponse(NSURLResponse* response) override; + bool ShouldAllowResponse(NSURLResponse* response, + bool for_main_frame) override; void WebStateDestroyed() override; AccountConsistencyService* account_consistency_service_; // Weak. @@ -75,7 +76,8 @@ AccountConsistencyHandler::AccountConsistencyHandler( account_reconcilor_(account_reconcilor), delegate_(delegate) {} -bool AccountConsistencyHandler::ShouldAllowResponse(NSURLResponse* response) { +bool AccountConsistencyHandler::ShouldAllowResponse(NSURLResponse* response, + bool for_main_frame) { NSHTTPURLResponse* http_response = base::mac::ObjCCast<NSHTTPURLResponse>(response); if (!http_response) @@ -373,7 +375,7 @@ void AccountConsistencyService::FinishedApplyingCookieRequest(bool success) { case ADD_CHROME_CONNECTED_COOKIE: // Add request.domain to prefs, use |true| as a dummy value (that is // never used), as the dictionary is used as a set. - update->SetBooleanWithoutPathExpansion(request.domain, true); + update->SetKey(request.domain, base::Value(true)); break; case REMOVE_CHROME_CONNECTED_COOKIE: // Remove request.domain from prefs. 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 f61cebd655c..7b940c01592 100644 --- a/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm +++ b/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm @@ -103,8 +103,9 @@ class TestWebState : public web::TestWebState { EXPECT_EQ(decider_, decider); decider_ = nullptr; } - bool ShouldAllowResponse(NSURLResponse* response) { - return decider_ ? decider_->ShouldAllowResponse(response) : true; + bool ShouldAllowResponse(NSURLResponse* response, bool for_main_frame) { + return decider_ ? decider_->ShouldAllowResponse(response, for_main_frame) + : true; } void WebStateDestroyed() { if (!decider_) @@ -244,7 +245,8 @@ TEST_F(AccountConsistencyServiceTest, SignInSignOut) { HTTPVersion:@"HTTP/1.1" headerFields:headers]; account_consistency_service_->SetWebStateHandler(&web_state_, delegate); - EXPECT_TRUE(web_state_.ShouldAllowResponse(response)); + EXPECT_TRUE( + web_state_.ShouldAllowResponse(response, /* for_main_frame = */ true)); web_state_.WebStateDestroyed(); // Check that all domains are removed. @@ -300,7 +302,8 @@ TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsNotOnGaia) { HTTPVersion:@"HTTP/1.1" headerFields:headers]; account_consistency_service_->SetWebStateHandler(&web_state_, delegate); - EXPECT_TRUE(web_state_.ShouldAllowResponse(response)); + EXPECT_TRUE( + web_state_.ShouldAllowResponse(response, /* for_main_frame = */ true)); web_state_.WebStateDestroyed(); EXPECT_OCMOCK_VERIFY(delegate); @@ -319,7 +322,8 @@ TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsNoHeader) { HTTPVersion:@"HTTP/1.1" headerFields:headers]; account_consistency_service_->SetWebStateHandler(&web_state_, delegate); - EXPECT_TRUE(web_state_.ShouldAllowResponse(response)); + EXPECT_TRUE( + web_state_.ShouldAllowResponse(response, /* for_main_frame = */ true)); web_state_.WebStateDestroyed(); EXPECT_OCMOCK_VERIFY(delegate); @@ -346,7 +350,8 @@ TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsDefault) { EXPECT_CALL(account_reconcilor_, OnReceivedManageAccountsResponse( signin::GAIA_SERVICE_TYPE_DEFAULT)) .Times(1); - EXPECT_FALSE(web_state_.ShouldAllowResponse(response)); + EXPECT_FALSE( + web_state_.ShouldAllowResponse(response, /* for_main_frame = */ true)); web_state_.WebStateDestroyed(); EXPECT_OCMOCK_VERIFY(delegate); |