Index: chrome/browser/chromeos/login/quick_unlock/fingerprint_storage_unittest.cc |
diff --git a/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage_unittest.cc b/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..63fad50347421fbc813b5089e1903ea04519b123 |
--- /dev/null |
+++ b/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage_unittest.cc |
@@ -0,0 +1,222 @@ |
+// 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 "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/common/pref_names.h" |
+#include "chrome/test/base/testing_profile.h" |
+#include "components/prefs/pref_service.h" |
+#include "content/public/test/test_browser_thread_bundle.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace chromeos { |
+namespace { |
+ |
+void SetConfirmationFrequency( |
+ PrefService* pref_service, |
+ quick_unlock::PasswordConfirmationFrequency frequency) { |
+ pref_service->SetInteger(prefs::kQuickUnlockTimeout, |
+ static_cast<int>(frequency)); |
+} |
+ |
+base::TimeDelta GetExpirationTime(PrefService* pref_service) { |
+ int frequency = pref_service->GetInteger(prefs::kQuickUnlockTimeout); |
+ return quick_unlock::PasswordConfirmationFrequencyToTimeDelta( |
+ static_cast<quick_unlock::PasswordConfirmationFrequency>(frequency)); |
+} |
+ |
+class FingerprintStorageUnitTest : public testing::Test { |
+ protected: |
+ FingerprintStorageUnitTest() : profile_(new TestingProfile()) {} |
+ ~FingerprintStorageUnitTest() override {} |
+ |
+ // testing::Test: |
+ void SetUp() override { quick_unlock::EnableForTesting(); } |
+ |
+ content::TestBrowserThreadBundle thread_bundle_; |
+ std::unique_ptr<TestingProfile> profile_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FingerprintStorageUnitTest); |
+}; |
+ |
+} // namespace |
+ |
+// Provides test-only FingerprintStorage APIs. |
+class FingerprintStorageTestApi { |
+ public: |
+ // Does *not* take ownership over |fingerprint_storage|. |
+ explicit FingerprintStorageTestApi( |
+ quick_unlock::FingerprintStorage* fingerprint_storage) |
+ : fingerprint_storage_(fingerprint_storage) {} |
+ |
+ // Reduces the amount of strong auth time available by |time_delta|. |
+ void ReduceRemainingStrongAuthTimeBy(const base::TimeDelta& time_delta) { |
+ fingerprint_storage_->last_strong_auth_ -= time_delta; |
+ } |
+ |
+ bool HasStrongAuthInfo() { |
+ return !fingerprint_storage_->last_strong_auth_.is_null(); |
+ } |
+ |
+ void SetEnrollments(bool has_enrollments) { |
+ fingerprint_storage_->has_enrollments_ = has_enrollments; |
+ } |
+ |
+ private: |
+ quick_unlock::FingerprintStorage* fingerprint_storage_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FingerprintStorageTestApi); |
+}; |
+ |
+// Verifies that: |
+// 1. Initial unlock attempt count is zero. |
+// 2. Attempting unlock attempts correctly increases unlock attempt count. |
+// 3. Resetting unlock attempt count correctly sets attempt count to 0. |
+TEST_F(FingerprintStorageUnitTest, UnlockAttemptCount) { |
+ quick_unlock::FingerprintStorage* fingerprint_storage = |
+ quick_unlock::QuickUnlockFactory::GetForProfile(profile_.get()) |
+ ->fingerprint_storage(); |
+ |
+ EXPECT_EQ(0, fingerprint_storage->unlock_attempt_count()); |
+ |
+ fingerprint_storage->AddUnlockAttempt(); |
+ fingerprint_storage->AddUnlockAttempt(); |
+ fingerprint_storage->AddUnlockAttempt(); |
+ EXPECT_EQ(3, fingerprint_storage->unlock_attempt_count()); |
+ |
+ fingerprint_storage->ResetUnlockAttemptCount(); |
+ EXPECT_EQ(0, fingerprint_storage->unlock_attempt_count()); |
+} |
+ |
+// Verifies that marking the strong auth makes TimeSinceLastStrongAuth a > zero |
+// value. |
+TEST_F(FingerprintStorageUnitTest, |
+ TimeSinceLastStrongAuthReturnsPositiveValue) { |
+ quick_unlock::FingerprintStorage* fingerprint_storage = |
+ quick_unlock::QuickUnlockFactory::GetForProfile(profile_.get()) |
+ ->fingerprint_storage(); |
+ PrefService* pref_service = profile_->GetPrefs(); |
+ FingerprintStorageTestApi test_api(fingerprint_storage); |
+ |
+ EXPECT_FALSE(test_api.HasStrongAuthInfo()); |
+ |
+ fingerprint_storage->MarkStrongAuth(); |
+ |
+ EXPECT_TRUE(test_api.HasStrongAuthInfo()); |
+ base::TimeDelta expiration_time = GetExpirationTime(pref_service); |
+ test_api.ReduceRemainingStrongAuthTimeBy(expiration_time); |
+ |
+ EXPECT_TRUE(fingerprint_storage->TimeSinceLastStrongAuth() >= |
+ (expiration_time / 2)); |
+} |
+ |
+// Verifies that by altering the password confirmation preference, the |
+// fingerprint storage will request password reconfirmation as expected. |
+TEST_F(FingerprintStorageUnitTest, |
jdufault
2017/02/27 21:41:50
You should be able to remove these strong auth tes
xiaoyinh(OOO Sep 11-29)
2017/02/28 01:20:49
Done.
|
+ QuickUnlockPasswordConfirmationFrequencyPreference) { |
+ quick_unlock::FingerprintStorage* fingerprint_storage = |
+ quick_unlock::QuickUnlockFactory::GetForProfile(profile_.get()) |
+ ->fingerprint_storage(); |
+ PrefService* pref_service = profile_->GetPrefs(); |
+ FingerprintStorageTestApi test_api(fingerprint_storage); |
+ |
+ // The default is one day, so verify moving the last strong auth time back 12 |
+ // hours(half of the expiration time) should not request strong auth. |
+ fingerprint_storage->MarkStrongAuth(); |
+ base::TimeDelta expiration_time = GetExpirationTime(pref_service); |
+ test_api.ReduceRemainingStrongAuthTimeBy(expiration_time / 2); |
+ EXPECT_TRUE(fingerprint_storage->HasStrongAuth()); |
+ |
+ // Verify moving the last strong auth time back another half of the expiration |
+ // time should request strong auth. |
+ test_api.ReduceRemainingStrongAuthTimeBy(expiration_time / 2); |
+ EXPECT_FALSE(fingerprint_storage->HasStrongAuth()); |
+ |
+ // Verify that by changing the frequency of required password confirmation to |
+ // six hours, moving the last strong auth interval back by 3 hours(half) will |
+ // not trigger a request for strong auth, but moving it by an additional 3 |
+ // hours will. |
+ fingerprint_storage->MarkStrongAuth(); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::SIX_HOURS); |
+ expiration_time = GetExpirationTime(pref_service); |
+ test_api.ReduceRemainingStrongAuthTimeBy(expiration_time / 2); |
+ EXPECT_TRUE(fingerprint_storage->HasStrongAuth()); |
+ test_api.ReduceRemainingStrongAuthTimeBy(expiration_time / 2); |
+ EXPECT_FALSE(fingerprint_storage->HasStrongAuth()); |
+ |
+ // A valid strong auth becomes invalid if the confirmation frequency is |
+ // shortened to less than the expiration time. |
+ fingerprint_storage->MarkStrongAuth(); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::TWELVE_HOURS); |
+ expiration_time = GetExpirationTime(pref_service); |
+ EXPECT_TRUE(fingerprint_storage->HasStrongAuth()); |
+ test_api.ReduceRemainingStrongAuthTimeBy(expiration_time / 2); |
+ EXPECT_TRUE(fingerprint_storage->HasStrongAuth()); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::SIX_HOURS); |
+ EXPECT_FALSE(fingerprint_storage->HasStrongAuth()); |
+ |
+ // An expired strong auth becomes usable if the confirmation frequency gets |
+ // extended past the expiration time. |
+ fingerprint_storage->MarkStrongAuth(); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::SIX_HOURS); |
+ expiration_time = GetExpirationTime(pref_service); |
+ EXPECT_TRUE(fingerprint_storage->HasStrongAuth()); |
+ test_api.ReduceRemainingStrongAuthTimeBy(expiration_time); |
+ EXPECT_FALSE(fingerprint_storage->HasStrongAuth()); |
+ SetConfirmationFrequency( |
+ pref_service, quick_unlock::PasswordConfirmationFrequency::TWELVE_HOURS); |
+ EXPECT_TRUE(fingerprint_storage->HasStrongAuth()); |
+} |
+ |
+// Verifies that authentication is not available when |
+// 1. No enrollments registered |
+// 2. Too many authentication attempts |
+// 3. No valid strong auth |
+TEST_F(FingerprintStorageUnitTest, AuthenticationUnAvailable) { |
+ quick_unlock::FingerprintStorage* fingerprint_storage = |
+ quick_unlock::QuickUnlockFactory::GetForProfile(profile_.get()) |
+ ->fingerprint_storage(); |
+ PrefService* pref_service = profile_->GetPrefs(); |
+ FingerprintStorageTestApi test_api(fingerprint_storage); |
+ |
+ EXPECT_FALSE(test_api.HasStrongAuthInfo()); |
+ fingerprint_storage->MarkStrongAuth(); |
+ EXPECT_TRUE(test_api.HasStrongAuthInfo()); |
+ |
+ EXPECT_FALSE(fingerprint_storage->HasEnrollment()); |
+ test_api.SetEnrollments(true); |
+ EXPECT_TRUE(fingerprint_storage->HasEnrollment()); |
+ EXPECT_EQ(0, fingerprint_storage->unlock_attempt_count()); |
+ EXPECT_TRUE(fingerprint_storage->IsFingerprintAuthenticationAvailable()); |
+ |
+ // No enrollment registered makes fingerprint authentication unavailable. |
+ test_api.SetEnrollments(false); |
+ EXPECT_FALSE(fingerprint_storage->IsFingerprintAuthenticationAvailable()); |
+ test_api.SetEnrollments(true); |
+ EXPECT_TRUE(fingerprint_storage->IsFingerprintAuthenticationAvailable()); |
+ |
+ // Too many authentication attempts make fingerprint authentication |
+ // unavailable. |
+ for (int i = 0; i < quick_unlock::FingerprintStorage::kMaximumUnlockAttempts; |
+ ++i) { |
+ fingerprint_storage->AddUnlockAttempt(); |
+ } |
+ EXPECT_FALSE(fingerprint_storage->IsFingerprintAuthenticationAvailable()); |
+ fingerprint_storage->ResetUnlockAttemptCount(); |
+ EXPECT_TRUE(fingerprint_storage->IsFingerprintAuthenticationAvailable()); |
+ |
+ // Strong auth becomes invalid after 1 day, and invalid strong auth makes |
+ // fingerprint authentication unavailable. |
+ base::TimeDelta expiration_time = GetExpirationTime(pref_service); |
+ test_api.ReduceRemainingStrongAuthTimeBy(expiration_time); |
+ EXPECT_FALSE(fingerprint_storage->HasStrongAuth()); |
+ EXPECT_FALSE(fingerprint_storage->IsFingerprintAuthenticationAvailable()); |
+} |
+ |
+} // namespace chromeos |