Commit 1ac641df authored by Mikel Astiz's avatar Mikel Astiz Committed by Commit Bot

[sync] Expose trusted vault recoverability state in SyncUserSettings

This is intended to be used as an indication to the UI that the user
should take action to improve recoverability of the sync-ed data.

This patch introduces basic plumbing in TrustedVaultClient with TODOs
to address platform-specific implementations in later patches.
Meanwhile, StandaloneTrustedVaultClient is extended with test-only
APIs for integration tests.

Change-Id: Ic255e502d9e33b145272903dc2b7c3a7ec2a1cd8
Bug: 1081649
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2329751Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Commit-Queue: Mikel Astiz <mastiz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#793231}
parent 7e4fb727
......@@ -32,6 +32,7 @@
#include "components/sync/nigori/nigori.h"
#include "components/sync/nigori/nigori_test_utils.h"
#include "components/sync/test/fake_server/fake_server_nigori_helper.h"
#include "components/sync/trusted_vault/standalone_trusted_vault_client.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_launcher.h"
#include "crypto/ec_private_key.h"
......@@ -50,6 +51,8 @@ using syncer::Pbkdf2KeyParamsForTesting;
using testing::NotNull;
using testing::SizeIs;
const char kGaiaId[] = "gaia_id_for_user_gmail.com";
MATCHER_P(IsDataEncryptedWith, key_params, "") {
const sync_pb::EncryptedData& encrypted_data = arg;
std::unique_ptr<syncer::Nigori> nigori = syncer::Nigori::CreateByDerivation(
......@@ -88,7 +91,6 @@ MATCHER_P4(StatusLabelsMatch,
GURL GetTrustedVaultRetrievalURL(
const net::test_server::EmbeddedTestServer& test_server,
const std::vector<uint8_t>& encryption_key) {
const char kGaiaId[] = "gaia_id_for_user_gmail.com";
// encryption_keys_retrieval.html would populate encryption key to sync
// service upon loading. Key is provided as part of URL and needs to be
// encoded with Base64, because |encryption_key| is binary.
......@@ -425,10 +427,7 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriSyncTestWithNotAwaitQuiescence,
class SingleClientNigoriWithWebApiTest : public SyncTest {
public:
SingleClientNigoriWithWebApiTest() : SyncTest(SINGLE_CLIENT) {
override_features_.InitAndEnableFeature(
switches::kSyncSupportTrustedVaultPassphrase);
}
SingleClientNigoriWithWebApiTest() : SyncTest(SINGLE_CLIENT) {}
~SingleClientNigoriWithWebApiTest() override = default;
// InProcessBrowserTest:
......@@ -445,8 +444,6 @@ class SingleClientNigoriWithWebApiTest : public SyncTest {
}
private:
base::test::ScopedFeatureList override_features_;
DISALLOW_COPY_AND_ASSIGN(SingleClientNigoriWithWebApiTest);
};
......@@ -507,6 +504,12 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest,
sync_ui_util::GetStatusLabels(GetProfile(0)),
StatusLabelsMatch(sync_ui_util::SYNCED, IDS_SYNC_ACCOUNT_SYNCING,
IDS_SETTINGS_EMPTY_STRING, sync_ui_util::NO_ACTION));
#if !defined(OS_CHROMEOS)
// Verify the profile-menu error string is empty.
EXPECT_EQ(sync_ui_util::NO_SYNC_ERROR,
sync_ui_util::GetAvatarSyncErrorType(GetProfile(0)));
#endif // !defined(OS_CHROMEOS)
}
IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest,
......@@ -551,8 +554,21 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiTest,
EXPECT_FALSE(GetSyncService(0)
->GetUserSettings()
->IsTrustedVaultKeyRequiredForPreferredDataTypes());
EXPECT_FALSE(GetSyncService(0)
->GetUserSettings()
->IsTrustedVaultRecoverabilityDegraded());
EXPECT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::PASSWORDS));
EXPECT_FALSE(sync_ui_util::ShouldShowSyncKeysMissingError(GetSyncService(0)));
EXPECT_THAT(
sync_ui_util::GetStatusLabels(GetProfile(0)),
StatusLabelsMatch(sync_ui_util::SYNCED, IDS_SYNC_ACCOUNT_SYNCING,
IDS_SETTINGS_EMPTY_STRING, sync_ui_util::NO_ACTION));
#if !defined(OS_CHROMEOS)
// Verify the profile-menu error string is empty.
EXPECT_EQ(sync_ui_util::NO_SYNC_ERROR,
sync_ui_util::GetAvatarSyncErrorType(GetProfile(0)));
#endif // !defined(OS_CHROMEOS)
}
IN_PROC_BROWSER_TEST_F(
......@@ -880,4 +896,54 @@ IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithWebApiFromUntrustedOriginTest,
->IsTrustedVaultKeyRequiredForPreferredDataTypes());
}
class SingleClientNigoriWithRecoverySyncTest : public SyncTest {
public:
SingleClientNigoriWithRecoverySyncTest() : SyncTest(SINGLE_CLIENT) {
override_features_.InitAndEnableFeature(
switches::kSyncSupportTrustedVaultPassphraseRecovery);
}
~SingleClientNigoriWithRecoverySyncTest() override = default;
private:
base::test::ScopedFeatureList override_features_;
DISALLOW_COPY_AND_ASSIGN(SingleClientNigoriWithRecoverySyncTest);
};
IN_PROC_BROWSER_TEST_F(SingleClientNigoriWithRecoverySyncTest,
ShouldReportDegradedTrustedVaultRecoverability) {
const std::vector<uint8_t> kTestEncryptionKey = {1, 2, 3, 4};
// Mimic the account being already using a trusted vault passphrase.
SetNigoriInFakeServer(BuildTrustedVaultNigoriSpecifics({kTestEncryptionKey}),
GetFakeServer());
// Mimic the key being available upon startup but recoverability degraded.
ASSERT_TRUE(SetupClients());
static_cast<syncer::StandaloneTrustedVaultClient*>(
GetSyncService(0)->GetSyncClientForTest()->GetTrustedVaultClient())
->SetRecoverabilityDegradedForTesting();
GetSyncService(0)->AddTrustedVaultDecryptionKeysFromWeb(
kGaiaId, {kTestEncryptionKey}, /*last_key_version=*/1);
ASSERT_TRUE(SetupSync());
ASSERT_EQ(syncer::PassphraseType::kTrustedVaultPassphrase,
GetSyncService(0)->GetUserSettings()->GetPassphraseType());
ASSERT_FALSE(GetSyncService(0)
->GetUserSettings()
->IsTrustedVaultKeyRequiredForPreferredDataTypes());
ASSERT_FALSE(sync_ui_util::ShouldShowSyncKeysMissingError(GetSyncService(0)));
EXPECT_TRUE(GetSyncService(0)
->GetUserSettings()
->IsTrustedVaultRecoverabilityDegraded());
// No messages expected in settings.
EXPECT_THAT(
sync_ui_util::GetStatusLabels(GetProfile(0)),
StatusLabelsMatch(sync_ui_util::SYNCED, IDS_SYNC_ACCOUNT_SYNCING,
IDS_SETTINGS_EMPTY_STRING, sync_ui_util::NO_ACTION));
}
} // namespace
......@@ -129,3 +129,11 @@ void TrustedVaultClientAndroid::MarkKeysAsStale(
Java_TrustedVaultClient_markKeysAsStale(env, reinterpret_cast<intptr_t>(this),
java_account_info);
}
void TrustedVaultClientAndroid::GetIsRecoverabilityDegraded(
const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> cb) {
// TODO(crbug.com/1100279): Needs implementation.
NOTIMPLEMENTED();
std::move(cb).Run(false);
}
......@@ -58,6 +58,8 @@ class TrustedVaultClientAndroid : public syncer::TrustedVaultClient {
void RemoveAllStoredKeys() override;
void MarkKeysAsStale(const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> cb) override;
void GetIsRecoverabilityDegraded(const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> cb) override;
private:
// Struct representing an in-flight FetchKeys() call invoked from C++.
......
......@@ -17,6 +17,7 @@
#include "components/sync/base/sync_prefs.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync/engine/sync_engine_switches.h"
#include "components/sync/engine/sync_string_conversions.h"
#include "components/sync/nigori/nigori.h"
......@@ -66,6 +67,11 @@ class EmptyTrustedVaultClient : public TrustedVaultClient {
base::OnceCallback<void(bool)> cb) override {
std::move(cb).Run(false);
}
void GetIsRecoverabilityDegraded(const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> cb) override {
std::move(cb).Run(false);
}
};
// A SyncEncryptionHandler::Observer implementation that simply posts all calls
......@@ -241,6 +247,7 @@ bool SyncServiceCrypto::IsPassphraseRequired() const {
case RequiredUserAction::kFetchingTrustedVaultKeys:
case RequiredUserAction::kTrustedVaultKeyRequired:
case RequiredUserAction::kTrustedVaultKeyRequiredButFetching:
case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
return false;
case RequiredUserAction::kPassphraseRequiredForDecryption:
case RequiredUserAction::kPassphraseRequiredForEncryption:
......@@ -264,6 +271,12 @@ bool SyncServiceCrypto::IsTrustedVaultKeyRequired() const {
RequiredUserAction::kTrustedVaultKeyRequiredButFetching;
}
bool SyncServiceCrypto::IsTrustedVaultRecoverabilityDegraded() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return state_.required_user_action ==
RequiredUserAction::kTrustedVaultRecoverabilityDegraded;
}
void SyncServiceCrypto::EnableEncryptEverything() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(state_.engine);
......@@ -290,6 +303,7 @@ void SyncServiceCrypto::SetEncryptionPassphrase(const std::string& passphrase) {
switch (state_.required_user_action) {
case RequiredUserAction::kUnknownDuringInitialization:
case RequiredUserAction::kNone:
case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
break;
case RequiredUserAction::kPassphraseRequiredForDecryption:
case RequiredUserAction::kFetchingTrustedVaultKeys:
......@@ -372,6 +386,7 @@ bool SyncServiceCrypto::IsTrustedVaultKeyRequiredStateKnown() const {
case RequiredUserAction::kTrustedVaultKeyRequired:
case RequiredUserAction::kTrustedVaultKeyRequiredButFetching:
case RequiredUserAction::kPassphraseRequiredForEncryption:
case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
return true;
}
NOTREACHED();
......@@ -402,6 +417,7 @@ bool SyncServiceCrypto::HasCryptoError() const {
switch (state_.required_user_action) {
case RequiredUserAction::kUnknownDuringInitialization:
case RequiredUserAction::kNone:
case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
return false;
case RequiredUserAction::kFetchingTrustedVaultKeys:
case RequiredUserAction::kTrustedVaultKeyRequired:
......@@ -495,6 +511,7 @@ void SyncServiceCrypto::OnTrustedVaultKeyAccepted() {
case RequiredUserAction::kNone:
case RequiredUserAction::kPassphraseRequiredForDecryption:
case RequiredUserAction::kPassphraseRequiredForEncryption:
case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
return;
case RequiredUserAction::kFetchingTrustedVaultKeys:
case RequiredUserAction::kTrustedVaultKeyRequired:
......@@ -557,9 +574,19 @@ void SyncServiceCrypto::OnCryptographerStateChanged(
void SyncServiceCrypto::OnPassphraseTypeChanged(PassphraseType type,
base::Time passphrase_time) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(1) << "Passphrase type changed to " << PassphraseTypeToString(type);
state_.cached_passphrase_type = type;
state_.cached_explicit_passphrase_time = passphrase_time;
// Clear recoverability degraded state in case a custom passphrase was set.
if (type != PassphraseType::kTrustedVaultPassphrase &&
state_.required_user_action ==
RequiredUserAction::kTrustedVaultRecoverabilityDegraded) {
UpdateRequiredUserActionAndNotify(RequiredUserAction::kNone);
}
notify_observers_.Run();
}
......@@ -597,6 +624,7 @@ void SyncServiceCrypto::OnTrustedVaultClientKeysChanged() {
case RequiredUserAction::kNone:
case RequiredUserAction::kPassphraseRequiredForDecryption:
case RequiredUserAction::kPassphraseRequiredForEncryption:
case RequiredUserAction::kTrustedVaultRecoverabilityDegraded:
// If no trusted vault keys are required, there's nothing to do. If they
// later are required, a fetch will be triggered in
// OnTrustedVaultKeyRequired().
......@@ -739,8 +767,50 @@ void SyncServiceCrypto::UpdateRequiredUserActionAndNotify(
RequiredUserAction new_required_user_action) {
DCHECK_NE(new_required_user_action,
RequiredUserAction::kUnknownDuringInitialization);
if (state_.required_user_action == new_required_user_action) {
return;
}
state_.required_user_action = new_required_user_action;
notify_required_user_action_changed_.Run();
if (state_.required_user_action == RequiredUserAction::kNone &&
state_.cached_passphrase_type ==
PassphraseType::kTrustedVaultPassphrase &&
base::FeatureList::IsEnabled(
switches::kSyncSupportTrustedVaultPassphraseRecovery)) {
trusted_vault_client_->GetIsRecoverabilityDegraded(
state_.account_info,
base::BindOnce(&SyncServiceCrypto::GetIsRecoverabilityDegradedCompleted,
weak_factory_.GetWeakPtr()));
}
}
void SyncServiceCrypto::GetIsRecoverabilityDegradedCompleted(
bool is_recoverability_degraded) {
if (state_.cached_passphrase_type !=
PassphraseType::kTrustedVaultPassphrase) {
DCHECK_NE(state_.required_user_action,
RequiredUserAction::kTrustedVaultRecoverabilityDegraded);
return;
}
// Transition from non-degraded to degraded recoverability.
if (is_recoverability_degraded &&
state_.required_user_action == RequiredUserAction::kNone) {
UpdateRequiredUserActionAndNotify(
RequiredUserAction::kTrustedVaultRecoverabilityDegraded);
notify_observers_.Run();
}
// Transition from degraded to non-degraded recoverability.
if (!is_recoverability_degraded &&
state_.required_user_action ==
RequiredUserAction::kTrustedVaultRecoverabilityDegraded) {
UpdateRequiredUserActionAndNotify(RequiredUserAction::kNone);
notify_observers_.Run();
}
}
} // namespace syncer
......@@ -48,6 +48,7 @@ class SyncServiceCrypto : public SyncEncryptionHandler::Observer,
bool IsPassphraseRequired() const;
bool IsUsingSecondaryPassphrase() const;
bool IsTrustedVaultKeyRequired() const;
bool IsTrustedVaultRecoverabilityDegraded() const;
void EnableEncryptEverything();
bool IsEncryptEverythingEnabled() const;
void SetEncryptionPassphrase(const std::string& passphrase);
......@@ -107,6 +108,9 @@ class SyncServiceCrypto : public SyncEncryptionHandler::Observer,
// via IsTrustedVaultKeyRequired() but there's an ongoing fetch that may
// resolve the issue.
kTrustedVaultKeyRequiredButFetching,
// No keys are required locally but user action is recommended to improve
// recoverability.
kTrustedVaultRecoverabilityDegraded,
};
// Observer method invoked by TrustedVaultClient when its content changes.
......@@ -131,6 +135,10 @@ class SyncServiceCrypto : public SyncEncryptionHandler::Observer,
void UpdateRequiredUserActionAndNotify(
RequiredUserAction new_required_user_action);
// Completion callback function for
// TrustedVaultClient::GetIsRecoverabilityDegraded().
void GetIsRecoverabilityDegradedCompleted(bool is_recoverability_degraded);
// Calls SyncServiceBase::NotifyObservers(). Never null.
const base::RepeatingClosure notify_observers_;
......
......@@ -12,10 +12,12 @@
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/driver/trusted_vault_client.h"
#include "components/sync/engine/mock_sync_engine.h"
#include "components/sync/engine/sync_engine_switches.h"
#include "components/sync/nigori/nigori.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -130,6 +132,11 @@ class TestTrustedVaultClient : public TrustedVaultClient {
// Exposes the total number of calls to the server's RequestKeysFromServer().
int server_request_count() const { return server_request_count_; }
// Exposes the total number of calls to GetIsRecoverabilityDegraded().
int get_is_recoverablity_degraded_call_count() const {
return get_is_recoverablity_degraded_call_count_;
}
// Mimics the completion of the next (FIFO) FetchKeys() request.
bool CompleteFetchKeysRequest() {
if (pending_responses_.empty()) {
......@@ -142,6 +149,10 @@ class TestTrustedVaultClient : public TrustedVaultClient {
return true;
}
void SetIsRecoverabilityDegraded(bool is_recoverability_degraded) {
is_recoverability_degraded_ = is_recoverability_degraded;
}
// TrustedVaultClient implementation.
std::unique_ptr<Subscription> AddKeysChangedObserver(
const base::RepeatingClosure& cb) override {
......@@ -219,6 +230,12 @@ class TestTrustedVaultClient : public TrustedVaultClient {
std::move(cb).Run(true);
}
void GetIsRecoverabilityDegraded(const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> cb) override {
++get_is_recoverablity_degraded_call_count_;
std::move(cb).Run(is_recoverability_degraded_);
}
private:
struct CachedKeysPerUser {
bool marked_as_stale = false;
......@@ -231,8 +248,10 @@ class TestTrustedVaultClient : public TrustedVaultClient {
CallbackList observer_list_;
int fetch_count_ = 0;
int keys_marked_as_stale_count_ = 0;
int get_is_recoverablity_degraded_call_count_ = 0;
int server_request_count_ = 0;
std::list<base::OnceClosure> pending_responses_;
bool is_recoverability_degraded_ = false;
};
class SyncServiceCryptoTest : public testing::Test {
......@@ -289,6 +308,7 @@ TEST_F(SyncServiceCryptoTest, ShouldRequireNoUserAction) {
EXPECT_FALSE(crypto_.IsPassphraseRequired());
EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
EXPECT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
}
TEST_F(SyncServiceCryptoTest, ShouldSetUpNewCustomPassphrase) {
......@@ -752,6 +772,93 @@ TEST_F(
EXPECT_THAT(trusted_vault_client_.fetch_count(), Eq(3));
}
TEST_F(SyncServiceCryptoTest, ShouldNotGetRecoverabilityIfFeatureDisabled) {
trusted_vault_client_.SetIsRecoverabilityDegraded(true);
crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
base::Time::Now());
crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
ASSERT_THAT(crypto_.GetPassphraseType(),
Eq(PassphraseType::kTrustedVaultPassphrase));
ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
EXPECT_THAT(trusted_vault_client_.get_is_recoverablity_degraded_call_count(),
Eq(0));
EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
}
TEST_F(SyncServiceCryptoTest, ShouldNotReportDegradedRecoverability) {
base::test::ScopedFeatureList override_features;
override_features.InitAndEnableFeature(
switches::kSyncSupportTrustedVaultPassphraseRecovery);
trusted_vault_client_.SetIsRecoverabilityDegraded(false);
crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
base::Time::Now());
crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
ASSERT_THAT(crypto_.GetPassphraseType(),
Eq(PassphraseType::kTrustedVaultPassphrase));
ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
}
TEST_F(SyncServiceCryptoTest, ShouldReportDegradedRecoverability) {
base::test::ScopedFeatureList override_features;
override_features.InitAndEnableFeature(
switches::kSyncSupportTrustedVaultPassphraseRecovery);
trusted_vault_client_.SetIsRecoverabilityDegraded(true);
crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
base::Time::Now());
crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
ASSERT_THAT(crypto_.GetPassphraseType(),
Eq(PassphraseType::kTrustedVaultPassphrase));
ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
EXPECT_TRUE(crypto_.IsTrustedVaultRecoverabilityDegraded());
}
TEST_F(SyncServiceCryptoTest,
ShouldClearDegradedRecoverabilityIfCustomPassphraseIsSet) {
const std::string kTestPassphrase = "somepassphrase";
base::test::ScopedFeatureList override_features;
override_features.InitAndEnableFeature(
switches::kSyncSupportTrustedVaultPassphraseRecovery);
// Mimic a browser startup in |kTrustedVaultPassphrase| with no additional
// keys required and degraded recoverability state.
trusted_vault_client_.SetIsRecoverabilityDegraded(true);
crypto_.OnPassphraseTypeChanged(PassphraseType::kTrustedVaultPassphrase,
base::Time::Now());
crypto_.SetSyncEngine(CoreAccountInfo(), &engine_);
ASSERT_THAT(crypto_.GetPassphraseType(),
Eq(PassphraseType::kTrustedVaultPassphrase));
ASSERT_TRUE(crypto_.IsTrustedVaultKeyRequiredStateKnown());
ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
ASSERT_FALSE(crypto_.IsPassphraseRequired());
ASSERT_TRUE(crypto_.IsTrustedVaultRecoverabilityDegraded());
// Mimic the user setting up a new custom passphrase.
crypto_.SetEncryptionPassphrase(kTestPassphrase);
// Mimic completion of the procedure in the sync engine.
EXPECT_CALL(reconfigure_cb_, Run(CONFIGURE_REASON_CRYPTO));
EXPECT_CALL(notify_observers_cb_, Run());
crypto_.OnPassphraseTypeChanged(PassphraseType::kCustomPassphrase,
base::Time::Now());
crypto_.OnPassphraseAccepted();
ASSERT_THAT(crypto_.GetPassphraseType(),
Eq(PassphraseType::kCustomPassphrase));
// Recoverability should no longer be considered degraded.
EXPECT_FALSE(crypto_.IsTrustedVaultRecoverabilityDegraded());
}
} // namespace
} // namespace syncer
......@@ -109,8 +109,11 @@ class SyncUserSettings {
// encrypted data types.
virtual bool IsTrustedVaultKeyRequired() const = 0;
// Whether trusted vault keys are required for encryption or decryption to
// proceed for any currently enabled data type.
// proceed for currently enabled data types.
virtual bool IsTrustedVaultKeyRequiredForPreferredDataTypes() const = 0;
// Whether recoverability of the trusted vault keys is degraded and user
// action is required, affecting currently enabled data types.
virtual bool IsTrustedVaultRecoverabilityDegraded() const = 0;
// Whether a "secondary" passphrase is in use (aka explicit passphrase), which
// means either a custom or a frozen implicit passphrase.
virtual bool IsUsingSecondaryPassphrase() const = 0;
......
......@@ -198,6 +198,13 @@ bool SyncUserSettingsImpl::IsTrustedVaultKeyRequiredForPreferredDataTypes()
return IsEncryptedDatatypeEnabled() && crypto_->IsTrustedVaultKeyRequired();
}
bool SyncUserSettingsImpl::IsTrustedVaultRecoverabilityDegraded() const {
// TODO(crbug.com/1081649): This should verify that at least one sync entity
// is affected.
return IsEncryptedDatatypeEnabled() &&
crypto_->IsTrustedVaultRecoverabilityDegraded();
}
bool SyncUserSettingsImpl::IsUsingSecondaryPassphrase() const {
return crypto_->IsUsingSecondaryPassphrase();
}
......
......@@ -66,6 +66,7 @@ class SyncUserSettingsImpl : public SyncUserSettings {
bool IsPassphraseRequiredForPreferredDataTypes() const override;
bool IsTrustedVaultKeyRequired() const override;
bool IsTrustedVaultKeyRequiredForPreferredDataTypes() const override;
bool IsTrustedVaultRecoverabilityDegraded() const override;
bool IsUsingSecondaryPassphrase() const override;
base::Time GetExplicitPassphraseTime() const override;
PassphraseType GetPassphraseType() const override;
......
......@@ -51,6 +51,7 @@ class SyncUserSettingsMock : public SyncUserSettings {
MOCK_CONST_METHOD0(IsPassphraseRequiredForPreferredDataTypes, bool());
MOCK_CONST_METHOD0(IsTrustedVaultKeyRequired, bool());
MOCK_CONST_METHOD0(IsTrustedVaultKeyRequiredForPreferredDataTypes, bool());
MOCK_CONST_METHOD0(IsTrustedVaultRecoverabilityDegraded, bool());
MOCK_CONST_METHOD0(IsUsingSecondaryPassphrase, bool());
MOCK_CONST_METHOD0(GetExplicitPassphraseTime, base::Time());
MOCK_CONST_METHOD0(GetPassphraseType, PassphraseType());
......
......@@ -179,6 +179,10 @@ bool TestSyncUserSettings::IsTrustedVaultKeyRequiredForPreferredDataTypes()
return trusted_vault_key_required_for_preferred_data_types_;
}
bool TestSyncUserSettings::IsTrustedVaultRecoverabilityDegraded() const {
return false;
}
bool TestSyncUserSettings::IsUsingSecondaryPassphrase() const {
return using_secondary_passphrase_;
}
......
......@@ -55,6 +55,7 @@ class TestSyncUserSettings : public SyncUserSettings {
bool IsPassphraseRequiredForPreferredDataTypes() const override;
bool IsTrustedVaultKeyRequired() const override;
bool IsTrustedVaultKeyRequiredForPreferredDataTypes() const override;
bool IsTrustedVaultRecoverabilityDegraded() const override;
bool IsUsingSecondaryPassphrase() const override;
base::Time GetExplicitPassphraseTime() const override;
PassphraseType GetPassphraseType() const override;
......
......@@ -66,6 +66,14 @@ class TrustedVaultClient {
// when accounts cookies deleted by the user action.
virtual void RemoveAllStoredKeys() = 0;
// Returns whether recoverability of the keys is degraded and user action is
// required to add a new method. This may be called frequently and
// implementations are responsible for implementing caching and possibly
// throttling.
virtual void GetIsRecoverabilityDegraded(
const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> cb) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(TrustedVaultClient);
};
......
......@@ -20,6 +20,10 @@ const base::Feature kSyncUseScryptForNewCustomPassphrases{
const base::Feature kSyncSupportTrustedVaultPassphrase{
"SyncSupportTrustedVaultPassphrase", base::FEATURE_ENABLED_BY_DEFAULT};
const base::Feature kSyncSupportTrustedVaultPassphraseRecovery{
"SyncSupportTrustedVaultPassphraseRecovery",
base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kSyncTriggerFullKeystoreMigration{
"SyncTriggerFullKeystoreMigration", base::FEATURE_ENABLED_BY_DEFAULT};
......
......@@ -12,6 +12,7 @@ namespace switches {
extern const base::Feature kSyncResetPollIntervalOnStart;
extern const base::Feature kSyncUseScryptForNewCustomPassphrases;
extern const base::Feature kSyncSupportTrustedVaultPassphrase;
extern const base::Feature kSyncSupportTrustedVaultPassphraseRecovery;
extern const base::Feature kSyncTriggerFullKeystoreMigration;
} // namespace switches
......
......@@ -77,6 +77,14 @@ void StandaloneTrustedVaultClient::MarkKeysAsStale(
std::move(cb).Run(false);
}
void StandaloneTrustedVaultClient::GetIsRecoverabilityDegraded(
const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> cb) {
// TODO(crbug.com/1081649): Implement logic.
NOTIMPLEMENTED();
std::move(cb).Run(is_recoverability_degraded_for_testing_);
}
void StandaloneTrustedVaultClient::WaitForFlushForTesting(
base::OnceClosure cb) const {
backend_task_runner_->PostTaskAndReply(FROM_HERE, base::DoNothing(),
......@@ -99,4 +107,8 @@ bool StandaloneTrustedVaultClient::IsInitializationTriggeredForTesting() const {
return backend_ != nullptr;
}
void StandaloneTrustedVaultClient::SetRecoverabilityDegradedForTesting() {
is_recoverability_degraded_for_testing_ = true;
}
} // namespace syncer
......@@ -48,10 +48,13 @@ class StandaloneTrustedVaultClient : public TrustedVaultClient {
void RemoveAllStoredKeys() override;
void MarkKeysAsStale(const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> cb) override;
void GetIsRecoverabilityDegraded(const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> cb) override;
// Runs |cb| when all requests have completed.
void WaitForFlushForTesting(base::OnceClosure cb) const;
bool IsInitializationTriggeredForTesting() const;
void SetRecoverabilityDegradedForTesting();
private:
void TriggerLazyInitializationIfNeeded();
......@@ -64,6 +67,8 @@ class StandaloneTrustedVaultClient : public TrustedVaultClient {
// |backend_| constructed lazily in the UI thread, used in
// |backend_task_runner_| and destroyed (refcounted) on any thread.
scoped_refptr<StandaloneTrustedVaultBackend> backend_;
bool is_recoverability_degraded_for_testing_ = false;
};
} // namespace syncer
......
......@@ -27,6 +27,9 @@ class IOSTrustedVaultClient : public syncer::TrustedVaultClient {
void RemoveAllStoredKeys() override;
void MarkKeysAsStale(const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> callback) override;
void GetIsRecoverabilityDegraded(
const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> callback) override;
// Not copyable or movable
IOSTrustedVaultClient(const IOSTrustedVaultClient&) = delete;
......
......@@ -62,6 +62,13 @@ void IOSTrustedVaultClient::RemoveAllStoredKeys() {
void IOSTrustedVaultClient::MarkKeysAsStale(
const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> callback) {
// TODO(crbug.com/1019685): needs implementation.
// TODO(crbug.com/1100278): Needs implementation.
std::move(callback).Run(false);
}
void IOSTrustedVaultClient::GetIsRecoverabilityDegraded(
const CoreAccountInfo& account_info,
base::OnceCallback<void(bool)> callback) {
// TODO(crbug.com/1100278): Needs implementation.
std::move(callback).Run(false);
}
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