chromium/chrome/browser/sync/test/integration/single_client_webauthn_credentials_sync_test.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/containers/span.h"
#include "base/location.h"
#include "base/rand_util.h"
#include "base/ranges/algorithm.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h"
#include "chrome/browser/sync/test/integration/secondary_account_helper.h"
#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
#include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
#include "chrome/browser/sync/test/integration/sync_service_impl_harness.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/browser/sync/test/integration/webauthn_credentials_helper.h"
#include "chrome/browser/ui/browser.h"
#include "components/password_manager/core/browser/features/password_manager_features_util.h"
#include "components/signin/public/base/signin_switches.h"
#include "components/sync/base/client_tag_hash.h"
#include "components/sync/base/data_type.h"
#include "components/sync/base/features.h"
#include "components/sync/engine/loopback_server/loopback_server_entity.h"
#include "components/sync/engine/loopback_server/persistent_unique_client_entity.h"
#include "components/sync/model/in_memory_metadata_change_list.h"
#include "components/sync/protocol/entity_specifics.pb.h"
#include "components/sync/protocol/webauthn_credential_specifics.pb.h"
#include "components/sync/test/test_matchers.h"
#include "components/version_info/version_info.h"
#include "components/webauthn/core/browser/passkey_model.h"
#include "components/webauthn/core/browser/passkey_model_change.h"
#include "components/webauthn/core/browser/passkey_model_utils.h"
#include "components/webauthn/core/browser/passkey_sync_bridge.h"
#include "content/public/test/browser_test.h"
#include "crypto/ec_private_key.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace {

ElementsAre;
IsEmpty;
Optional;
UnorderedElementsAre;

EntityHasDisplayName;
EntityHasSyncId;
EntityHasUsername;
kTestRpId;
LocalPasskeysChangedChecker;
LocalPasskeysMatchChecker;
MockPasskeyModelObserver;
NewPasskey;
NewShadowingPasskey;
PasskeyChangeObservationChecker;
PasskeyHasDisplayName;
PasskeyHasRpId;
PasskeyHasSyncId;
PasskeyHasUserId;
PasskeySpecificsEq;
PasskeySyncActiveChecker;
ServerPasskeysMatchChecker;

constexpr int kSingleProfile =;
constexpr char kUsername1[] =;
constexpr char kDisplayName1[] =;
constexpr char kUsername2[] =;
constexpr char kDisplayName2[] =;

static const webauthn::PasskeyModel::UserEntity kTestUser(
    std::vector<uint8_t>{},
    "[email protected]",
    "Example User");

constexpr std::array<uint8_t, 32> kTrustedVaultKey =;

constexpr int32_t kTrustedVaultKeyVersion =;

bool PublicKeyForPasskeyEquals(
    const sync_pb::WebauthnCredentialSpecifics& passkey,
    base::span<const uint8_t> trusted_vault_key,
    base::span<const uint8_t> expected_spki) {}

std::unique_ptr<syncer::PersistentUniqueClientEntity>
CreateEntityWithCustomClientTagHash(
    const std::string& client_tag_hash,
    const sync_pb::WebauthnCredentialSpecifics& specifics) {}

class PasskeyModelReadyChecker : public StatusChangeChecker,
                                 public webauthn::PasskeyModel::Observer {};

class SingleClientWebAuthnCredentialsSyncTest : public SyncTest {};

// Adding a local passkey should sync to the server.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       UploadNewLocalPasskey) {}

IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       StartWithLocalPasskey) {}

// CreatePasskey should create a new passkey entity and upload it to the server.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest, CreatePasskey) {}

// Creating a new passkey should shadow passkeys for the same (RP ID, user ID).
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       CreatePasskeyWithShadows) {}

// Tests CreatePasskey from a pre-constructed WebAuthnCredentialSpecifics.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       CreatePasskeyFromEntity) {}

// Tests CreatePasskey from a pre-constructed WebAuthnCredentialSpecifics with
// shadow passkeys being added.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       CreatePasskeyFromEntityWithShadows) {}

// Adding a remote passkey should sync to the client.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DownloadNewServerPasskey) {}

// The model should retrieve individual passkeys by RP ID and credential ID.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest, GetPasskeys) {}

// When getting passkeys, shadowed entities should be ignored.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       GetPasskeysWithShadows) {}

// Deleting a local passkey should remove from the server.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       UploadLocalPasskeyDeletion) {}

// Downloading a deletion for a passkey that does not exist locally should not
// crash.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DownloadDeletionOfNonExistingLocalPasskey) {}

// Deleting a remote passkey should remove from the client.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DownloadServerPasskeyDeletion) {}

// Attempting to delete a passkey that does not exist should return false.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DeleteNonExistingPasskey) {}

// Deleting a passkey should also delete its shadowed credentials.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DeleteShadowedPasskeys) {}

// Deleting a passkey should not delete passkeys for a different rp id or user
// id.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DoNotDeleteCredentialsForDifferentRpIdOrUserId) {}

// Attempt deleting a passkey that is part of a shadow chain circle.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DeletePasskeyFromShadowChainCircle) {}

IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DeleteAllPasskeys) {}

IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DeleteAllPasskeysEmptyStore) {}

// Tests that deleting a passkey is persisted across browser restarts.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       PRE_DeletingPasskeysPersistsOverRestarts) {}

IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DeletingPasskeysPersistsOverRestarts) {}

// Tests updating a passkey.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest, UpdatePasskey) {}

// Tests that attempting to update a non existing passkey returns false.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       UpdateNonExistingPasskey) {}

// Tests that updating a passkey is persisted across browser restarts.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       PRE_UpdatingPasskeysPersistsOverRestarts) {}

IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       UpdatingPasskeysPersistsOverRestarts) {}

IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       LegacySyncIdCompatibilityUponInitialDownload) {}

IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       LegacySyncIdCompatibilityUponIncrementalUpdate) {}

// Updating a remote passkey should sync to the client.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       DownloadPasskeyUpdate) {}

// Tests that disabling sync before sync startup correctly clears the passkey
// cache.
// Regression test for crbug.com/1476895.
IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       PRE_ClearingModelDataOnSyncStartup) {}

IN_PROC_BROWSER_TEST_F(SingleClientWebAuthnCredentialsSyncTest,
                       ClearingModelDataOnSyncStartup) {}

// The unconsented primary account isn't supported on ChromeOS.
#if !BUILDFLAG(IS_CHROMEOS_ASH)

class SingleClientWebAuthnCredentialsSyncTestExplicitParamTest
    : public SingleClientWebAuthnCredentialsSyncTest,
      public testing::WithParamInterface<bool /*explicit_signin*/> {};

// Tests that passkeys sync on transport mode only if the user has consented to
// showing credentials from their Google account.
IN_PROC_BROWSER_TEST_P(SingleClientWebAuthnCredentialsSyncTestExplicitParamTest,
                       TransportModeConsent) {}

INSTANTIATE_TEST_SUITE_P();
#endif  // !BUILDFLAG(IS_CHROMEOS_ASH)

}  // namespace