Commit aaedfc4c authored by Boris Sazonov's avatar Boris Sazonov Committed by Commit Bot

[Signin][Android] Revise sign-out flow for unconsented account

Changes sign-out flow logic in PrimaryAccountManager:
1. Allows sign-out flow even if there's only an unconsented account and
   adds a test for this.
2. Adds "if !defined(OS_ANDROID)" to DICE-specific
   PrimaryAccountManager & PrimaryAccountMutator tests.

Bug: 1095128
Change-Id: I0d5b5e804b360ff2ea5c4bf7c6e3add07a21d835
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2391237
Commit-Queue: Boris Sazonov <bsazonov@chromium.org>
Reviewed-by: default avatarDavid Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807015}
parent 496cb36c
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/signin/internal/identity_manager/account_tracker_service.h" #include "components/signin/internal/identity_manager/account_tracker_service.h"
...@@ -310,12 +311,20 @@ void PrimaryAccountManager::StartSignOut( ...@@ -310,12 +311,20 @@ void PrimaryAccountManager::StartSignOut(
VLOG(1) << "StartSignOut: " << static_cast<int>(signout_source_metric) << ", " VLOG(1) << "StartSignOut: " << static_cast<int>(signout_source_metric) << ", "
<< static_cast<int>(signout_delete_metric) << ", " << static_cast<int>(signout_delete_metric) << ", "
<< static_cast<int>(remove_option); << static_cast<int>(remove_option);
if (IsAuthenticated()) {
client_->PreSignOut( client_->PreSignOut(
base::BindOnce(&PrimaryAccountManager::OnSignoutDecisionReached, base::BindOnce(&PrimaryAccountManager::OnSignoutDecisionReached,
base::Unretained(this), signout_source_metric, base::Unretained(this), signout_source_metric,
signout_delete_metric, remove_option, signout_delete_metric, remove_option,
assert_signout_allowed), assert_signout_allowed),
signout_source_metric); signout_source_metric);
} else {
// Sign-out is always allowed if there's only unconsented primary account
// without sync consent, so skip calling PreSignOut.
OnSignoutDecisionReached(signout_source_metric, signout_delete_metric,
remove_option, assert_signout_allowed,
SigninClient::SignoutDecision::ALLOW_SIGNOUT);
}
} }
void PrimaryAccountManager::OnSignoutDecisionReached( void PrimaryAccountManager::OnSignoutDecisionReached(
...@@ -331,7 +340,7 @@ void PrimaryAccountManager::OnSignoutDecisionReached( ...@@ -331,7 +340,7 @@ void PrimaryAccountManager::OnSignoutDecisionReached(
VLOG(1) << "OnSignoutDecisionReached: " VLOG(1) << "OnSignoutDecisionReached: "
<< (signout_decision == SigninClient::SignoutDecision::ALLOW_SIGNOUT); << (signout_decision == SigninClient::SignoutDecision::ALLOW_SIGNOUT);
signin_metrics::LogSignout(signout_source_metric, signout_delete_metric); signin_metrics::LogSignout(signout_source_metric, signout_delete_metric);
if (!IsAuthenticated()) { if (primary_account_info().IsEmpty()) {
return; return;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "build/build_config.h"
#include "components/image_fetcher/core/fake_image_decoder.h" #include "components/image_fetcher/core/fake_image_decoder.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h" #include "components/prefs/scoped_user_pref_update.h"
...@@ -184,6 +185,8 @@ TEST_F(PrimaryAccountManagerTest, SignOutRevoke) { ...@@ -184,6 +185,8 @@ TEST_F(PrimaryAccountManagerTest, SignOutRevoke) {
EXPECT_TRUE(token_service_.GetAccounts().empty()); EXPECT_TRUE(token_service_.GetAccounts().empty());
} }
// kRemoveAuthenticatedAccountIfInError isn't supported on Android.
#if !defined(OS_ANDROID)
TEST_F(PrimaryAccountManagerTest, SignOutDiceNoRevoke) { TEST_F(PrimaryAccountManagerTest, SignOutDiceNoRevoke) {
account_consistency_ = signin::AccountConsistencyMethod::kDice; account_consistency_ = signin::AccountConsistencyMethod::kDice;
CreatePrimaryAccountManager(); CreatePrimaryAccountManager();
...@@ -239,6 +242,7 @@ TEST_F(PrimaryAccountManagerTest, SignOutDiceWithError) { ...@@ -239,6 +242,7 @@ TEST_F(PrimaryAccountManagerTest, SignOutDiceWithError) {
std::vector<CoreAccountId> expected_tokens = {other_account_id}; std::vector<CoreAccountId> expected_tokens = {other_account_id};
EXPECT_EQ(expected_tokens, token_service_.GetAccounts()); EXPECT_EQ(expected_tokens, token_service_.GetAccounts());
} }
#endif
TEST_F(PrimaryAccountManagerTest, SignOutWhileProhibited) { TEST_F(PrimaryAccountManagerTest, SignOutWhileProhibited) {
CreatePrimaryAccountManager(); CreatePrimaryAccountManager();
...@@ -258,6 +262,23 @@ TEST_F(PrimaryAccountManagerTest, SignOutWhileProhibited) { ...@@ -258,6 +262,23 @@ TEST_F(PrimaryAccountManagerTest, SignOutWhileProhibited) {
EXPECT_FALSE(manager_->IsAuthenticated()); EXPECT_FALSE(manager_->IsAuthenticated());
} }
TEST_F(PrimaryAccountManagerTest, UnconsentedSignOutWhileProhibited) {
CreatePrimaryAccountManager();
EXPECT_FALSE(manager_->IsAuthenticated());
EXPECT_TRUE(manager_->GetAuthenticatedAccountInfo().email.empty());
EXPECT_TRUE(manager_->GetAuthenticatedAccountId().empty());
CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
CoreAccountInfo account_info = account_tracker()->GetAccountInfo(account_id);
manager_->SetUnconsentedPrimaryAccountInfo(account_info);
EXPECT_TRUE(manager_->HasUnconsentedPrimaryAccount());
EXPECT_FALSE(manager_->IsAuthenticated());
signin_client()->set_is_signout_allowed(false);
manager_->SignOut(signin_metrics::SIGNOUT_TEST,
signin_metrics::SignoutDelete::IGNORE_METRIC);
EXPECT_FALSE(manager_->HasUnconsentedPrimaryAccount());
}
TEST_F(PrimaryAccountManagerTest, ProhibitedAtStartup) { TEST_F(PrimaryAccountManagerTest, ProhibitedAtStartup) {
CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com"); CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
user_prefs_.SetString(prefs::kGoogleServicesAccountId, account_id.ToString()); user_prefs_.SetString(prefs::kGoogleServicesAccountId, account_id.ToString());
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/scoped_observer.h" #include "base/scoped_observer.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "build/build_config.h"
#include "components/signin/public/base/signin_metrics.h" #include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/base/signin_pref_names.h" #include "components/signin/public/base/signin_pref_names.h"
#include "components/signin/public/identity_manager/consent_level.h" #include "components/signin/public/identity_manager/consent_level.h"
...@@ -480,6 +481,9 @@ TEST_F(PrimaryAccountMutatorTest, ...@@ -480,6 +481,9 @@ TEST_F(PrimaryAccountMutatorTest,
RemoveAccountExpectation::kRemoveAll); RemoveAccountExpectation::kRemoveAll);
} }
// kRemoveAuthenticatedAccountIfInError isn't supported on Android.
#if !defined(OS_ANDROID)
// Test that ClearPrimaryAccount(...) with ClearAccountTokensAction::kDefault // Test that ClearPrimaryAccount(...) with ClearAccountTokensAction::kDefault
// and AccountConsistencyMethod::kDice keeps all accounts when the the primary // and AccountConsistencyMethod::kDice keeps all accounts when the the primary
// account does not have an authentication error (see *_AuthError test). // account does not have an authentication error (see *_AuthError test).
...@@ -500,6 +504,7 @@ TEST_F(PrimaryAccountMutatorTest, ...@@ -500,6 +504,7 @@ TEST_F(PrimaryAccountMutatorTest,
signin::PrimaryAccountMutator::ClearAccountsAction::kDefault, signin::PrimaryAccountMutator::ClearAccountsAction::kDefault,
RemoveAccountExpectation::kRemovePrimary, AuthExpectation::kAuthError); RemoveAccountExpectation::kRemovePrimary, AuthExpectation::kAuthError);
} }
#endif // !defined(OS_ANDROID)
#endif // !defined(OS_CHROMEOS) #endif // !defined(OS_CHROMEOS)
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment