Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1777)

Unified Diff: chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc

Issue 2809993004: cros: Implement cryptohome backend for pin.
Patch Set: Address comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
diff --git a/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc b/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
index 13cbf2d989828ed76abc232bf2888e19a5e651d5..51c6ff26ad1d3df2221851fd57efc85ea759fe61 100644
--- a/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
+++ b/chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc
@@ -10,14 +10,22 @@
#include "base/bind.h"
#include "base/memory/ptr_util.h"
+#include "base/stl_util.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "chrome/browser/chromeos/login/quick_unlock/pin_backend.h"
+#include "chrome/browser/chromeos/login/quick_unlock/pin_storage_prefs.h"
#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h"
#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h"
#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/extensions/extension_api_unittest.h"
#include "chrome/common/pref_names.h"
+#include "chromeos/cryptohome/mock_homedir_methods.h"
+#include "chromeos/cryptohome/system_salt_getter.h"
#include "chromeos/login/auth/fake_extended_authenticator.h"
+#include "content/public/test/test_utils.h"
#include "extensions/browser/api_test_utils.h"
#include "extensions/browser/extension_function_dispatcher.h"
@@ -30,6 +38,10 @@ using QuickUnlockMode = quick_unlock_private::QuickUnlockMode;
using QuickUnlockModeList = std::vector<QuickUnlockMode>;
using CredentialList = std::vector<std::string>;
+using ::testing::Invoke;
+using ::testing::WithArgs;
+using ::testing::_;
+
namespace chromeos {
namespace {
@@ -66,7 +78,9 @@ enum ExpectedPinState {
} // namespace
-class QuickUnlockPrivateUnitTest : public ExtensionApiUnittest {
+class QuickUnlockPrivateUnitTest
+ : public ExtensionApiUnittest,
+ public ::testing::WithParamInterface<quick_unlock::PinStorageType> {
public:
QuickUnlockPrivateUnitTest()
: fake_user_manager_(new FakeChromeUserManager()),
@@ -76,17 +90,58 @@ class QuickUnlockPrivateUnitTest : public ExtensionApiUnittest {
void SetUp() override {
ExtensionApiUnittest::SetUp();
- quick_unlock::EnableForTesting(quick_unlock::PinStorageType::kPrefs);
+ quick_unlock::EnableForTesting(GetParam());
+
+ quick_unlock::PinBackend::ResetForTesting();
+ run_loop_ = base::MakeUnique<base::RunLoop>();
+
+ // PinBackend will run cryptohome routines even if we're just using the pref
+ // backend. Make sure it has the globals needed.
+ SystemSaltGetter::Get()->SetRawSaltForTesting({1, 2, 3, 4, 5, 6, 7, 8});
+
+ homedir_methods_ = new cryptohome::MockHomedirMethods();
+ ON_CALL(*homedir_methods_, GetKeyDataEx(_, _, _))
+ .WillByDefault(WithArgs<2>(
+ Invoke(this, &QuickUnlockPrivateUnitTest::DoGetKeyDataCallback)));
+ ON_CALL(*homedir_methods_, AddKeyEx(_, _, _, _, _))
+ .WillByDefault(WithArgs<2, 4>(
+ Invoke(this, &QuickUnlockPrivateUnitTest::DoAddKeyCallback)));
+ ON_CALL(*homedir_methods_, RemoveKeyEx(_, _, _, _))
+ .WillByDefault(WithArgs<2, 3>(
+ Invoke(this, &QuickUnlockPrivateUnitTest::DoRemoveKeyCallback)));
+
+ // InitializeForTesting takes ownership over |homedir_methods_|.
+ cryptohome::HomedirMethods::InitializeForTesting(homedir_methods_);
// Setup a primary user.
auto test_account = AccountId::FromUserEmail(kTestUserEmail);
fake_user_manager_->AddUser(test_account);
fake_user_manager_->UserLoggedIn(test_account, kTestUserEmailHash, false);
+ chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(
+ fake_user_manager_->GetPrimaryUser(), GetProfile());
+ modes_changed_handler_ = base::Bind(&DoNothing);
// Ensure that quick unlock is turned off.
SetModes(QuickUnlockModeList{}, CredentialList{});
+ }
- modes_changed_handler_ = base::Bind(&DoNothing);
+ void TearDown() override {
+ PumpRunLoop();
+ run_loop_.reset();
+
+ homedir_methods_ = nullptr;
+ fake_user_manager_ = nullptr;
+
+ ExtensionApiUnittest::TearDown();
+ cryptohome::HomedirMethods::Shutdown();
+ }
+
+ // Executes all pending tasks.
+ void PumpRunLoop() {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, run_loop_->QuitWhenIdleClosure());
+ run_loop_->Run();
+ run_loop_ = base::MakeUnique<base::RunLoop>();
}
// If a mode change event is raised, fail the test.
@@ -273,16 +328,34 @@ class QuickUnlockPrivateUnitTest : public ExtensionApiUnittest {
CredentialList{});
}
+ // Returns if the pin is set in the backend.
+ bool IsPinSetInBackend() {
+ const AccountId account_id = AccountId::FromUserEmail(kTestUserEmail);
+
+ bool is_set = false;
+ quick_unlock::PinBackend::IsSet(
+ account_id,
+ base::Bind([](bool* result, bool is_set) { *result = is_set; },
+ &is_set));
+
+ PumpRunLoop();
+
+ return is_set;
+ }
+
private:
// Runs the given |func| with the given |params|.
std::unique_ptr<base::Value> RunFunction(
scoped_refptr<UIThreadExtensionFunction> func,
std::unique_ptr<base::ListValue> params) {
- return std::unique_ptr<base::Value>(
+ PumpRunLoop();
+ auto result = std::unique_ptr<base::Value>(
api_test_utils::RunFunctionWithDelegateAndReturnSingleResult(
func, std::move(params), profile(),
base::MakeUnique<ExtensionFunctionDispatcher>(profile()),
api_test_utils::NONE));
+ PumpRunLoop();
+ return result;
}
// Verifies a mode change event is raised and that |expected| is now the
@@ -293,7 +366,35 @@ class QuickUnlockPrivateUnitTest : public ExtensionApiUnittest {
expect_modes_changed_ = false;
}
- FakeChromeUserManager* fake_user_manager_;
+ // Methods used to setup the mock homedir methods instance.
+ void DoGetKeyDataCallback(
+ const cryptohome::HomedirMethods::GetKeyDataCallback& callback) {
+ callback.Run(true, cryptohome::MountError::MOUNT_ERROR_NONE, keys_);
+ }
+
+ void DoAddKeyCallback(const cryptohome::KeyDefinition& key,
+ const cryptohome::HomedirMethods::Callback& callback) {
+ keys_.push_back(key);
+ callback.Run(true, cryptohome::MountError::MOUNT_ERROR_NONE);
+ }
+
+ void DoRemoveKeyCallback(
+ const std::string& label,
+ const cryptohome::HomedirMethods::Callback& callback) {
+ base::EraseIf(keys_, [&label](const cryptohome::KeyDefinition& key) {
+ return key.label == label;
+ });
+ callback.Run(true, cryptohome::MountError::MOUNT_ERROR_NONE);
+ }
+
+ // Run loop that collects all pending tasks. Use |PumpRunLoop| to run them.
+ std::unique_ptr<base::RunLoop> run_loop_;
+
+ // Keys registered on cryptohome.
+ std::vector<cryptohome::KeyDefinition> keys_;
+
+ cryptohome::MockHomedirMethods* homedir_methods_ = nullptr; // Unowned
+ FakeChromeUserManager* fake_user_manager_ = nullptr;
ScopedUserManagerEnabler scoped_user_manager_;
QuickUnlockPrivateSetModesFunction::ModesChangedEventHandler
modes_changed_handler_;
@@ -303,19 +404,19 @@ class QuickUnlockPrivateUnitTest : public ExtensionApiUnittest {
};
// Verify that password checking works.
-TEST_F(QuickUnlockPrivateUnitTest, CheckPassword) {
+TEST_P(QuickUnlockPrivateUnitTest, CheckPassword) {
EXPECT_TRUE(CheckPassword(kValidPassword));
EXPECT_FALSE(CheckPassword(kInvalidPassword));
}
// Verifies that this returns PIN for GetAvailableModes.
-TEST_F(QuickUnlockPrivateUnitTest, GetAvailableModes) {
+TEST_P(QuickUnlockPrivateUnitTest, GetAvailableModes) {
EXPECT_EQ(GetAvailableModes(),
QuickUnlockModeList{QuickUnlockMode::QUICK_UNLOCK_MODE_PIN});
}
// Verifies that an invalid password cannot be used to update the mode list.
-TEST_F(QuickUnlockPrivateUnitTest, SetModesFailsWithInvalidPassword) {
+TEST_P(QuickUnlockPrivateUnitTest, SetModesFailsWithInvalidPassword) {
// Verify there is no active mode.
EXPECT_EQ(GetActiveModes(), QuickUnlockModeList{});
@@ -330,7 +431,7 @@ TEST_F(QuickUnlockPrivateUnitTest, SetModesFailsWithInvalidPassword) {
// Verifies that the quickUnlockPrivate.onActiveModesChanged is only raised when
// the active set of modes changes.
-TEST_F(QuickUnlockPrivateUnitTest, ModeChangeEventOnlyRaisedWhenModesChange) {
+TEST_P(QuickUnlockPrivateUnitTest, ModeChangeEventOnlyRaisedWhenModesChange) {
// Make sure quick unlock is turned off, and then verify that turning it off
// again does not trigger an event.
EXPECT_TRUE(SetModes(QuickUnlockModeList{}, CredentialList{}));
@@ -352,10 +453,7 @@ TEST_F(QuickUnlockPrivateUnitTest, ModeChangeEventOnlyRaisedWhenModesChange) {
// Ensures that quick unlock can be enabled and disabled by checking the result
// of quickUnlockPrivate.GetActiveModes and PinStorage::IsPinSet.
-TEST_F(QuickUnlockPrivateUnitTest, SetModesAndGetActiveModes) {
- quick_unlock::QuickUnlockStorage* quick_unlock_storage =
- quick_unlock::QuickUnlockFactory::GetForProfile(profile());
-
+TEST_P(QuickUnlockPrivateUnitTest, SetModesAndGetActiveModes) {
// Update mode to PIN raises an event and updates GetActiveModes.
ExpectModesChanged(
QuickUnlockModeList{QuickUnlockMode::QUICK_UNLOCK_MODE_PIN});
@@ -363,42 +461,49 @@ TEST_F(QuickUnlockPrivateUnitTest, SetModesAndGetActiveModes) {
QuickUnlockModeList{QuickUnlockMode::QUICK_UNLOCK_MODE_PIN}, {"111111"}));
EXPECT_EQ(GetActiveModes(),
QuickUnlockModeList{QuickUnlockMode::QUICK_UNLOCK_MODE_PIN});
- EXPECT_TRUE(quick_unlock_storage->pin_storage()->IsPinSet());
+ EXPECT_TRUE(IsPinSetInBackend());
// SetModes can be used to turn off a quick unlock mode.
ExpectModesChanged(QuickUnlockModeList{});
EXPECT_TRUE(SetModes(QuickUnlockModeList{}, CredentialList{}));
EXPECT_EQ(GetActiveModes(), QuickUnlockModeList{});
- EXPECT_FALSE(quick_unlock_storage->pin_storage()->IsPinSet());
+ EXPECT_FALSE(IsPinSetInBackend());
}
// Verifies that enabling PIN quick unlock actually talks to the PIN subsystem.
-TEST_F(QuickUnlockPrivateUnitTest, VerifyAuthenticationAgainstPIN) {
+TEST_P(QuickUnlockPrivateUnitTest, VerifyAuthenticationAgainstPIN) {
+ // Cryptohome authentication does not go through PinBackend at the moment and
+ // cannot be easily tested.
+ if (GetParam() == quick_unlock::PinStorageType::kCryptohome)
+ return;
+
quick_unlock::QuickUnlockStorage* quick_unlock_storage =
quick_unlock::QuickUnlockFactory::GetForProfile(profile());
+ quick_unlock::PinStoragePrefs* pin_storage =
+ quick_unlock_storage->pin_storage_prefs();
EXPECT_TRUE(SetModes(QuickUnlockModeList{}, CredentialList{}));
- EXPECT_FALSE(quick_unlock_storage->pin_storage()->IsPinSet());
+ EXPECT_FALSE(IsPinSetInBackend());
EXPECT_TRUE(SetModes(
QuickUnlockModeList{QuickUnlockMode::QUICK_UNLOCK_MODE_PIN}, {"111111"}));
- EXPECT_TRUE(quick_unlock_storage->pin_storage()->IsPinSet());
+ EXPECT_TRUE(IsPinSetInBackend());
quick_unlock_storage->MarkStrongAuth();
- quick_unlock_storage->pin_storage()->ResetUnlockAttemptCount();
- EXPECT_TRUE(quick_unlock_storage->TryAuthenticatePin("111111"));
- EXPECT_FALSE(quick_unlock_storage->TryAuthenticatePin("000000"));
+ pin_storage->ResetUnlockAttemptCount();
+ EXPECT_TRUE(pin_storage->TryAuthenticatePin("111111"));
+ EXPECT_FALSE(pin_storage->TryAuthenticatePin("000000"));
}
// Verifies that the number of modes and the number of passwords given must be
// the same.
-TEST_F(QuickUnlockPrivateUnitTest, ThrowErrorOnMismatchedParameterCount) {
+TEST_P(QuickUnlockPrivateUnitTest, ThrowErrorOnMismatchedParameterCount) {
EXPECT_FALSE(SetModesWithError("[\"valid\", [\"PIN\"], []]").empty());
EXPECT_FALSE(SetModesWithError("[\"valid\", [], [\"11\"]]").empty());
}
// Validates PIN error checking in conjuction with policy-related prefs.
-TEST_F(QuickUnlockPrivateUnitTest, CheckCredentialProblemReporting) {
+TEST_P(QuickUnlockPrivateUnitTest, CheckCredentialProblemReporting) {
PrefService* pref_service = profile()->GetPrefs();
// Verify the pin checks work with the default preferences which are minimum
@@ -470,7 +575,7 @@ TEST_F(QuickUnlockPrivateUnitTest, CheckCredentialProblemReporting) {
CheckPin(PIN_TOO_SHORT | PIN_WEAK_ERROR, "234");
}
-TEST_F(QuickUnlockPrivateUnitTest, GetCredentialRequirements) {
+TEST_P(QuickUnlockPrivateUnitTest, GetCredentialRequirements) {
PrefService* pref_service = profile()->GetPrefs();
// Verify that trying out PINs under the minimum/maximum lengths will send the
@@ -490,4 +595,11 @@ TEST_F(QuickUnlockPrivateUnitTest, GetCredentialRequirements) {
pref_service->SetInteger(prefs::kPinUnlockMaximumLength, -3);
CheckGetCredentialRequirements(1, 0);
}
+
+INSTANTIATE_TEST_CASE_P(
+ StorageProviders,
+ QuickUnlockPrivateUnitTest,
+ ::testing::Values(quick_unlock::PinStorageType::kPrefs,
+ quick_unlock::PinStorageType::kCryptohome));
+
} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698