diff options
Diffstat (limited to 'chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc')
-rw-r--r-- | chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc | 531 |
1 files changed, 394 insertions, 137 deletions
diff --git a/chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc b/chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc index 9c2f2f6d3ab..120b0641380 100644 --- a/chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc +++ b/chromium/components/safe_browsing/password_protection/password_protection_service_unittest.cc @@ -8,7 +8,7 @@ #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" -#include "base/test/histogram_tester.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/null_task_runner.h" #include "base/test/scoped_feature_list.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -18,7 +18,10 @@ #include "components/safe_browsing/password_protection/mock_password_protection_service.h" #include "components/safe_browsing/password_protection/password_protection_request.h" #include "components/sync_preferences/testing_pref_service_syncable.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/test_browser_context.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/web_contents_tester.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" @@ -27,6 +30,8 @@ using testing::_; using testing::ElementsAre; using testing::Return; +using PasswordReuseEvent = + safe_browsing::LoginReputationClientRequest::PasswordReuseEvent; namespace { @@ -65,6 +70,7 @@ class TestPasswordProtectionService : public MockPasswordProtectionService { scoped_refptr<HostContentSettingsMap> content_setting_map) : MockPasswordProtectionService(database_manager, url_loader_factory, + nullptr, content_setting_map.get()) {} void RequestFinished( @@ -132,8 +138,7 @@ class PasswordProtectionServiceTest EXPECT_CALL(*password_protection_service_, IsIncognito()) .WillRepeatedly(Return(GetParam()[1])); EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) - .WillRepeatedly(Return( - LoginReputationClientRequest::PasswordReuseEvent::NOT_SIGNED_IN)); + .WillRepeatedly(Return(PasswordReuseEvent::NOT_SIGNED_IN)); EXPECT_CALL(*password_protection_service_, IsURLWhitelistedForPasswordEntry(_, _)) .WillRepeatedly(Return(false)); @@ -146,35 +151,38 @@ class PasswordProtectionServiceTest void TearDown() override { content_setting_map_->ShutdownOnUIThread(); } // Sets up |database_manager_| and |pending_requests_| as needed. - void InitializeAndStartPasswordOnFocusRequest(bool match_whitelist, - int timeout_in_ms) { + void InitializeAndStartPasswordOnFocusRequest( + bool match_whitelist, + int timeout_in_ms, + content::WebContents* web_contents) { GURL target_url(kTargetUrl); EXPECT_CALL(*database_manager_, CheckCsdWhitelistUrl(target_url, _)) .WillRepeatedly( Return(match_whitelist ? AsyncMatch::MATCH : AsyncMatch::NO_MATCH)); request_ = new PasswordProtectionRequest( - nullptr, target_url, GURL(kFormActionUrl), GURL(kPasswordFrameUrl), - false /* matches_sync_password */, {}, + web_contents, target_url, GURL(kFormActionUrl), GURL(kPasswordFrameUrl), + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, {}, LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true, password_protection_service_.get(), timeout_in_ms); request_->Start(); } void InitializeAndStartPasswordEntryRequest( - bool matches_sync_password, + PasswordReuseEvent::ReusedPasswordType type, const std::vector<std::string>& matching_domains, bool match_whitelist, - int timeout_in_ms) { + int timeout_in_ms, + content::WebContents* web_contents) { GURL target_url(kTargetUrl); EXPECT_CALL(*database_manager_, CheckCsdWhitelistUrl(target_url, _)) .WillRepeatedly( Return(match_whitelist ? AsyncMatch::MATCH : AsyncMatch::NO_MATCH)); request_ = new PasswordProtectionRequest( - nullptr, target_url, GURL(), GURL(), matches_sync_password, - matching_domains, LoginReputationClientRequest::PASSWORD_REUSE_EVENT, - true, password_protection_service_.get(), timeout_in_ms); + web_contents, target_url, GURL(), GURL(), type, matching_domains, + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, true, + password_protection_service_.get(), timeout_in_ms); request_->Start(); } @@ -189,6 +197,7 @@ class PasswordProtectionServiceTest void CacheVerdict(const GURL& url, LoginReputationClientRequest::TriggerType trigger, + ReusedPasswordType password_type, LoginReputationClientResponse::VerdictType verdict, int cache_duration_sec, const std::string& cache_expression, @@ -196,11 +205,11 @@ class PasswordProtectionServiceTest ASSERT_FALSE(cache_expression.empty()); LoginReputationClientResponse response( CreateVerdictProto(verdict, cache_duration_sec, cache_expression)); - password_protection_service_->CacheVerdict(url, trigger, &response, - verdict_received_time); + password_protection_service_->CacheVerdict( + url, trigger, password_type, &response, verdict_received_time); } - void CacheInvalidVerdict() { + void CacheInvalidVerdict(ReusedPasswordType password_type) { GURL invalid_hostname("http://invalid.com"); std::unique_ptr<base::DictionaryValue> verdict_dictionary = base::DictionaryValue::From(content_setting_map_->GetWebsiteSetting( @@ -214,8 +223,13 @@ class PasswordProtectionServiceTest std::make_unique<base::DictionaryValue>(); invalid_verdict_entry->SetString("invalid", "invalid_string"); - verdict_dictionary->SetWithoutPathExpansion( + std::unique_ptr<base::DictionaryValue> invalid_cache_expression_entry = + std::make_unique<base::DictionaryValue>(); + invalid_cache_expression_entry->SetWithoutPathExpansion( "invalid_cache_expression", std::move(invalid_verdict_entry)); + verdict_dictionary->SetWithoutPathExpansion( + base::NumberToString(password_type), + std::move(invalid_cache_expression_entry)); content_setting_map_->SetWebsiteSettingDefaultScope( invalid_hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), std::move(verdict_dictionary)); @@ -225,6 +239,11 @@ class PasswordProtectionServiceTest return password_protection_service_->GetStoredVerdictCount(type); } + content::WebContents* GetWebContents() { + return content::WebContentsTester::CreateTestWebContents( + content::WebContents::CreateParams(&browser_context_)); + } + protected: // |thread_bundle_| is needed here because this test involves both UI and IO // threads. @@ -237,6 +256,7 @@ class PasswordProtectionServiceTest std::unique_ptr<TestPasswordProtectionService> password_protection_service_; scoped_refptr<PasswordProtectionRequest> request_; base::HistogramTester histograms_; + content::TestBrowserContext browser_context_; }; TEST_P(PasswordProtectionServiceTest, TestParseInvalidVerdictEntry) { @@ -321,6 +341,7 @@ TEST_P(PasswordProtectionServiceTest, TestCachePasswordReuseVerdicts) { // Cache a verdict for http://www.test.com/foo/index.html CacheVerdict(GURL("http://www.test.com/foo/index.html"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::SAFE, 10 * kMinute, "test.com/foo/", base::Time::Now()); @@ -331,34 +352,52 @@ TEST_P(PasswordProtectionServiceTest, TestCachePasswordReuseVerdicts) { // override the cache. CacheVerdict(GURL("http://www.test.com/foo/index2.html"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::PHISHING, 10 * kMinute, "test.com/foo/", base::Time::Now()); EXPECT_EQ(1U, GetStoredVerdictCount( LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); LoginReputationClientResponse out_verdict; - EXPECT_EQ( - LoginReputationClientResponse::PHISHING, - password_protection_service_->GetCachedVerdict( - GURL("http://www.test.com/foo/index2.html"), - LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &out_verdict)); + EXPECT_EQ(LoginReputationClientResponse::PHISHING, + password_protection_service_->GetCachedVerdict( + GURL("http://www.test.com/foo/index2.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, &out_verdict)); + + // Cache a password reuse verdict with a different password type but same + // origin and cache expression should add a new entry. + CacheVerdict(GURL("http://www.test.com/foo/index2.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::ENTERPRISE_PASSWORD, + LoginReputationClientResponse::PHISHING, 10 * kMinute, + "test.com/foo/", base::Time::Now()); + EXPECT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + EXPECT_EQ(LoginReputationClientResponse::PHISHING, + password_protection_service_->GetCachedVerdict( + GURL("http://www.test.com/foo/index2.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::ENTERPRISE_PASSWORD, &out_verdict)); // Cache another verdict with the same origin but different cache_expression // will not increase setting count, but will increase the number of verdicts // in the given origin. CacheVerdict(GURL("http://www.test.com/bar/index2.html"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::SAFE, 10 * kMinute, "test.com/bar/", base::Time::Now()); - EXPECT_EQ(2U, GetStoredVerdictCount( + EXPECT_EQ(3U, GetStoredVerdictCount( LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); // Now cache a UNFAMILIAR_LOGIN_PAGE verdict, stored verdict count for // PASSWORD_REUSE_EVENT should be the same. CacheVerdict(GURL("http://www.test.com/foobar/index3.html"), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::SAFE, 10 * kMinute, "test.com/foobar/", base::Time::Now()); - EXPECT_EQ(2U, GetStoredVerdictCount( + EXPECT_EQ(3U, GetStoredVerdictCount( LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); EXPECT_EQ(1U, GetStoredVerdictCount( LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); @@ -372,6 +411,7 @@ TEST_P(PasswordProtectionServiceTest, TestCacheUnfamiliarLoginVerdicts) { // Cache a verdict for http://www.test.com/foo/index.html CacheVerdict(GURL("http://www.test.com/foo/index.html"), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::SAFE, 10 * kMinute, "test.com/foo/", base::Time::Now()); @@ -383,6 +423,7 @@ TEST_P(PasswordProtectionServiceTest, TestCacheUnfamiliarLoginVerdicts) { // in the given origin. CacheVerdict(GURL("http://www.test.com/bar/index2.html"), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::SAFE, 10 * kMinute, "test.com/bar/", base::Time::Now()); EXPECT_EQ(2U, GetStoredVerdictCount( @@ -392,6 +433,7 @@ TEST_P(PasswordProtectionServiceTest, TestCacheUnfamiliarLoginVerdicts) { // UNFAMILIAR_LOGIN_PAGE should be the same. CacheVerdict(GURL("http://www.test.com/foobar/index3.html"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::SAFE, 10 * kMinute, "test.com/foobar/", base::Time::Now()); EXPECT_EQ(2U, GetStoredVerdictCount( @@ -405,70 +447,92 @@ TEST_P(PasswordProtectionServiceTest, TestGetCachedVerdicts) { LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); ASSERT_EQ(0U, GetStoredVerdictCount( LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); - // Prepare 3 verdicts of the same origin with different cache expressions, - // one is expired, one is not, the other is of a different type. + // Prepare 4 verdicts of the same origin with different cache expressions, + // or password type, one is expired, one is not, one is of a different + // trigger type, and the other is with a different password type. base::Time now = base::Time::Now(); CacheVerdict(GURL("http://test.com/login.html"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::SAFE, 10 * kMinute, "test.com/", now); CacheVerdict( GURL("http://test.com/def/index.jsp"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::PHISHING, 10 * kMinute, "test.com/def/", base::Time::FromDoubleT(now.ToDoubleT() - kDay)); // Yesterday, expired. CacheVerdict(GURL("http://test.com/bar/login.html"), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::PHISHING, 10 * kMinute, "test.com/bar/", now); + CacheVerdict(GURL("http://test.com/login.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::ENTERPRISE_PASSWORD, + LoginReputationClientResponse::SAFE, 10 * kMinute, "test.com/", + now); - ASSERT_EQ(2U, GetStoredVerdictCount( + ASSERT_EQ(3U, GetStoredVerdictCount( LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); ASSERT_EQ(1U, GetStoredVerdictCount( LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL with unknown origin. LoginReputationClientResponse actual_verdict; - EXPECT_EQ( - LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, - password_protection_service_->GetCachedVerdict( - GURL("http://www.unknown.com/"), - LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("http://www.unknown.com/"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, &actual_verdict)); + EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("http://www.unknown.com/"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::ENTERPRISE_PASSWORD, &actual_verdict)); // Return SAFE if look up for a URL that matches "test.com" cache expression. - EXPECT_EQ( - LoginReputationClientResponse::SAFE, - password_protection_service_->GetCachedVerdict( - GURL("http://test.com/xyz/foo.jsp"), - LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + EXPECT_EQ(LoginReputationClientResponse::SAFE, + password_protection_service_->GetCachedVerdict( + GURL("http://test.com/xyz/foo.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, &actual_verdict)); + EXPECT_EQ(LoginReputationClientResponse::SAFE, + password_protection_service_->GetCachedVerdict( + GURL("http://test.com/xyz/foo.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::ENTERPRISE_PASSWORD, &actual_verdict)); // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL whose variants match // test.com/def, but the corresponding verdict is expired. - EXPECT_EQ( - LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, - password_protection_service_->GetCachedVerdict( - GURL("http://test.com/def/ghi/index.html"), - LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("http://test.com/def/ghi/index.html"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, &actual_verdict)); // Return PHISHING. Matches "test.com/bar/" cache expression. - EXPECT_EQ(LoginReputationClientResponse::PHISHING, - password_protection_service_->GetCachedVerdict( - GURL("http://test.com/bar/foo.jsp"), - LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, - &actual_verdict)); + EXPECT_EQ( + LoginReputationClientResponse::PHISHING, + password_protection_service_->GetCachedVerdict( + GURL("http://test.com/bar/foo.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, &actual_verdict)); // Now cache SAFE verdict for the full path. CacheVerdict(GURL("http://test.com/bar/foo.jsp"), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::SAFE, 10 * kMinute, "test.com/bar/foo.jsp", now); // Return SAFE now. Matches the full cache expression. - EXPECT_EQ(LoginReputationClientResponse::SAFE, - password_protection_service_->GetCachedVerdict( - GURL("http://test.com/bar/foo.jsp"), - LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, - &actual_verdict)); + EXPECT_EQ( + LoginReputationClientResponse::SAFE, + password_protection_service_->GetCachedVerdict( + GURL("http://test.com/bar/foo.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, &actual_verdict)); } TEST_P(PasswordProtectionServiceTest, TestRemoveCachedVerdictOnURLsDeleted) { @@ -476,26 +540,35 @@ TEST_P(PasswordProtectionServiceTest, TestRemoveCachedVerdictOnURLsDeleted) { LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); ASSERT_EQ(0U, GetStoredVerdictCount( LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); - // Prepare 2 verdicts. One is for origin "http://foo.com", and the other is - // for "http://bar.com". + // Prepare 5 verdicts. Three are for origin "http://foo.com", and the others + // are for "http://bar.com". base::Time now = base::Time::Now(); CacheVerdict(GURL("http://foo.com/abc/index.jsp"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, + LoginReputationClientResponse::LOW_REPUTATION, 10 * kMinute, + "foo.com/abc/", now); + CacheVerdict(GURL("http://foo.com/abc/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::ENTERPRISE_PASSWORD, LoginReputationClientResponse::LOW_REPUTATION, 10 * kMinute, "foo.com/abc/", now); CacheVerdict(GURL("http://bar.com/index.jsp"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::PHISHING, 10 * kMinute, "bar.com", now); - ASSERT_EQ(2U, GetStoredVerdictCount( + ASSERT_EQ(3U, GetStoredVerdictCount( LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); CacheVerdict(GURL("http://foo.com/abc/index.jsp"), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::LOW_REPUTATION, 10 * kMinute, "foo.com/abc/", now); CacheVerdict(GURL("http://bar.com/index.jsp"), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::PHISHING, 10 * kMinute, "bar.com", now); ASSERT_EQ(2U, GetStoredVerdictCount( @@ -512,22 +585,23 @@ TEST_P(PasswordProtectionServiceTest, TestRemoveCachedVerdictOnURLsDeleted) { password_protection_service_->RemoveContentSettingsOnURLsDeleted( false /* all_history */, deleted_urls); - EXPECT_EQ(1U, GetStoredVerdictCount( + EXPECT_EQ(2U, GetStoredVerdictCount( LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); EXPECT_EQ(1U, GetStoredVerdictCount( LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); LoginReputationClientResponse actual_verdict; + EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("http://bar.com"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, &actual_verdict)); EXPECT_EQ( LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, password_protection_service_->GetCachedVerdict( GURL("http://bar.com"), - LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); - EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, - password_protection_service_->GetCachedVerdict( - GURL("http://bar.com"), - LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, - &actual_verdict)); + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, &actual_verdict)); // If delete all history. All password protection content settings should be // gone. @@ -579,8 +653,8 @@ TEST_P(PasswordProtectionServiceTest, VerifyCanGetReputationOfURL) { TEST_P(PasswordProtectionServiceTest, TestNoRequestSentForWhitelistedURL) { histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0); - InitializeAndStartPasswordOnFocusRequest(true /* match whitelist */, - 10000 /* timeout in ms*/); + InitializeAndStartPasswordOnFocusRequest( + true /* match whitelist */, 10000 /* timeout in ms */, GetWebContents()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(nullptr, password_protection_service_->latest_response()); EXPECT_THAT( @@ -592,10 +666,11 @@ TEST_P(PasswordProtectionServiceTest, TestNoRequestSentIfVerdictAlreadyCached) { histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0); CacheVerdict(GURL(kTargetUrl), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::LOW_REPUTATION, 10 * kMinute, GURL(kTargetUrl).host().append("/"), base::Time::Now()); - InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */, - 10000 /* timeout in ms*/); + InitializeAndStartPasswordOnFocusRequest( + false /* match whitelist */, 10000 /* timeout in ms*/, GetWebContents()); base::RunLoop().RunUntilIdle(); EXPECT_THAT( histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogram), @@ -611,8 +686,8 @@ TEST_P(PasswordProtectionServiceTest, TestResponseFetchFailed) { network::URLLoaderCompletionStatus status(net::ERR_FAILED); test_url_loader_factory_.AddResponse(url_, head, std::string(), status); - InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */, - 10000 /* timeout in ms*/); + InitializeAndStartPasswordOnFocusRequest( + false /* match whitelist */, 10000 /* timeout in ms */, GetWebContents()); password_protection_service_->WaitForResponse(); EXPECT_EQ(nullptr, password_protection_service_->latest_response()); EXPECT_THAT( @@ -625,8 +700,8 @@ TEST_P(PasswordProtectionServiceTest, TestMalformedResponse) { // Set up malformed response. test_url_loader_factory_.AddResponse(url_.spec(), "invalid response"); - InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */, - 10000 /* timeout in ms*/); + InitializeAndStartPasswordOnFocusRequest( + false /* match whitelist */, 10000 /* timeout in ms */, GetWebContents()); password_protection_service_->WaitForResponse(); EXPECT_EQ(nullptr, password_protection_service_->latest_response()); EXPECT_THAT( @@ -637,7 +712,8 @@ TEST_P(PasswordProtectionServiceTest, TestMalformedResponse) { TEST_P(PasswordProtectionServiceTest, TestRequestTimedout) { histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 0); InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */, - 0 /* timeout immediately */); + 0 /* timeout immediately */, + GetWebContents()); base::RunLoop().RunUntilIdle(); EXPECT_EQ(nullptr, password_protection_service_->latest_response()); EXPECT_THAT( @@ -655,14 +731,15 @@ TEST_P(PasswordProtectionServiceTest, test_url_loader_factory_.AddResponse(url_.spec(), expected_response.SerializeAsString()); - InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */, - 10000 /* timeout in ms*/); + InitializeAndStartPasswordOnFocusRequest( + false /* match whitelist */, 10000 /* timeout in ms */, GetWebContents()); password_protection_service_->WaitForResponse(); EXPECT_THAT( histograms_.GetAllSamples(kPasswordOnFocusRequestOutcomeHistogram), ElementsAre(base::Bucket(1 /* SUCCEEDED */, 1))); EXPECT_THAT(histograms_.GetAllSamples(kPasswordOnFocusVerdictHistogram), ElementsAre(base::Bucket(3 /* PHISHING */, 1))); + histograms_.ExpectTotalCount(kReferrerChainSizeOfPhishingVerdictHistogram, 1); LoginReputationClientResponse* actual_response = password_protection_service_->latest_response(); EXPECT_EQ(expected_response.verdict_type(), actual_response->verdict_type()); @@ -687,8 +764,8 @@ TEST_P(PasswordProtectionServiceTest, // Initiate a saved password entry request (w/ no sync password). InitializeAndStartPasswordEntryRequest( - false /* matches_sync_password */, {"example.com"}, - false /* match whitelist */, 10000 /* timeout in ms*/); + PasswordReuseEvent::SAVED_PASSWORD, {"example.com"}, + false /* match whitelist */, 10000 /* timeout in ms*/, GetWebContents()); password_protection_service_->WaitForResponse(); // UMA: request outcomes @@ -710,6 +787,7 @@ TEST_P(PasswordProtectionServiceTest, EXPECT_THAT( histograms_.GetAllSamples(kProtectedPasswordEntryVerdictHistogram), ElementsAre(base::Bucket(3 /* PHISHING */, 1))); + histograms_.ExpectTotalCount(kReferrerChainSizeOfPhishingVerdictHistogram, 1); } TEST_P(PasswordProtectionServiceTest, @@ -726,9 +804,9 @@ TEST_P(PasswordProtectionServiceTest, expected_response.SerializeAsString()); // Initiate a sync password entry request (w/ no saved password). - InitializeAndStartPasswordEntryRequest(true /* matches_sync_password */, {}, - false /* match whitelist */, - 10000 /* timeout in ms*/); + InitializeAndStartPasswordEntryRequest( + PasswordReuseEvent::SIGN_IN_PASSWORD, {}, false /* match whitelist */, + 10000 /* timeout in ms*/, GetWebContents()); password_protection_service_->WaitForResponse(); // UMA: request outcomes @@ -747,6 +825,7 @@ TEST_P(PasswordProtectionServiceTest, EXPECT_THAT(histograms_.GetAllSamples(kSyncPasswordEntryVerdictHistogram), ElementsAre(base::Bucket(3 /* PHISHING */, 1))); histograms_.ExpectTotalCount(kProtectedPasswordEntryVerdictHistogram, 0); + histograms_.ExpectTotalCount(kReferrerChainSizeOfPhishingVerdictHistogram, 1); } TEST_P(PasswordProtectionServiceTest, TestTearDownWithPendingRequests) { @@ -756,7 +835,7 @@ TEST_P(PasswordProtectionServiceTest, TestTearDownWithPendingRequests) { .WillRepeatedly(Return(AsyncMatch::NO_MATCH)); password_protection_service_->StartRequest( nullptr, target_url, GURL("http://foo.com/submit"), - GURL("http://foo.com/frame"), false, {}, + GURL("http://foo.com/frame"), PasswordReuseEvent::SAVED_PASSWORD, {}, LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true); // Destroy password_protection_service_ while there is one request pending. @@ -769,7 +848,7 @@ TEST_P(PasswordProtectionServiceTest, TestTearDownWithPendingRequests) { } TEST_P(PasswordProtectionServiceTest, TestCleanUpExpiredVerdict) { - // Prepare 4 verdicts for PASSWORD_REUSE_EVENT: + // Prepare 4 verdicts for PASSWORD_REUSE_EVENT with SIGN_IN_PASSWORD type: // (1) "foo.com/abc/" valid // (2) "foo.com/def/" expired // (3) "bar.com/abc/" expired @@ -777,17 +856,21 @@ TEST_P(PasswordProtectionServiceTest, TestCleanUpExpiredVerdict) { base::Time now = base::Time::Now(); CacheVerdict(GURL("https://foo.com/abc/index.jsp"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::LOW_REPUTATION, 10 * kMinute, "foo.com/abc/", now); CacheVerdict(GURL("https://foo.com/def/index.jsp"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::LOW_REPUTATION, 0, "foo.com/def/", now); CacheVerdict(GURL("https://bar.com/abc/index.jsp"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::PHISHING, 0, "bar.com/abc/", now); CacheVerdict(GURL("https://bar.com/def/index.jsp"), LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::PHISHING, 0, "bar.com/def/", now); ASSERT_EQ(4U, GetStoredVerdictCount( LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); @@ -797,10 +880,12 @@ TEST_P(PasswordProtectionServiceTest, TestCleanUpExpiredVerdict) { // (2) "bar.com/xyz/" expired CacheVerdict(GURL("https://bar.com/def/index.jsp"), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::SAFE, 10 * kMinute, "bar.com/def/", now); CacheVerdict(GURL("https://bar.com/xyz/index.jsp"), LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, LoginReputationClientResponse::PHISHING, 0, "bar.com/xyz/", now); ASSERT_EQ(2U, GetStoredVerdictCount( LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); @@ -813,48 +898,50 @@ TEST_P(PasswordProtectionServiceTest, TestCleanUpExpiredVerdict) { LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); LoginReputationClientResponse actual_verdict; // Has cached PASSWORD_REUSE_EVENT verdict for foo.com/abc/. - EXPECT_EQ( - LoginReputationClientResponse::LOW_REPUTATION, - password_protection_service_->GetCachedVerdict( - GURL("https://foo.com/abc/test.jsp"), - LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION, + password_protection_service_->GetCachedVerdict( + GURL("https://foo.com/abc/test.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, &actual_verdict)); // No cached PASSWORD_REUSE_EVENT verdict for foo.com/def. - EXPECT_EQ( - LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, - password_protection_service_->GetCachedVerdict( - GURL("https://foo.com/def/index.jsp"), - LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("https://foo.com/def/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, &actual_verdict)); // No cached PASSWORD_REUSE_EVENT verdict for bar.com/abc. - EXPECT_EQ( - LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, - password_protection_service_->GetCachedVerdict( - GURL("https://bar.com/abc/index.jsp"), - LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); + EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("https://bar.com/abc/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, &actual_verdict)); // No cached PASSWORD_REUSE_EVENT verdict for bar.com/def. + EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("https://bar.com/def/index.jsp"), + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, &actual_verdict)); + + // Has cached UNFAMILIAR_LOGIN_PAGE verdict for bar.com/def. EXPECT_EQ( - LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + LoginReputationClientResponse::SAFE, password_protection_service_->GetCachedVerdict( GURL("https://bar.com/def/index.jsp"), - LoginReputationClientRequest::PASSWORD_REUSE_EVENT, &actual_verdict)); - - // Has cached UNFAMILIAR_LOGIN_PAGE verdict for bar.com/def. - EXPECT_EQ(LoginReputationClientResponse::SAFE, - password_protection_service_->GetCachedVerdict( - GURL("https://bar.com/def/index.jsp"), - LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, - &actual_verdict)); + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, &actual_verdict)); // No cached UNFAMILIAR_LOGIN_PAGE verdict for bar.com/xyz. - EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, - password_protection_service_->GetCachedVerdict( - GURL("https://bar.com/xyz/index.jsp"), - LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, - &actual_verdict)); + EXPECT_EQ( + LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, + password_protection_service_->GetCachedVerdict( + GURL("https://bar.com/xyz/index.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, &actual_verdict)); } TEST_P(PasswordProtectionServiceTest, TestCleanUpExpiredVerdictWithInvalidEntry) { - CacheInvalidVerdict(); + CacheInvalidVerdict(PasswordReuseEvent::SIGN_IN_PASSWORD); ContentSettingsForOneType password_protection_settings; content_setting_map_->GetSettingsForOneType( CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), @@ -878,7 +965,8 @@ TEST_P(PasswordProtectionServiceTest, VerifyPasswordOnFocusRequestProto) { expected_response.SerializeAsString()); InitializeAndStartPasswordOnFocusRequest(false /* match whitelist */, - 100000 /* timeout in ms*/); + 100000 /* timeout in ms */, + GetWebContents()); password_protection_service_->WaitForResponse(); const LoginReputationClientRequest* actual_request = @@ -904,9 +992,9 @@ TEST_P(PasswordProtectionServiceTest, expected_response.SerializeAsString()); // Initialize request triggered by chrome sync password reuse. - InitializeAndStartPasswordEntryRequest(true /* matches_sync_password */, {}, - false /* match whitelist */, - 100000 /* timeout in ms*/); + InitializeAndStartPasswordEntryRequest( + PasswordReuseEvent::SIGN_IN_PASSWORD, {}, false /* match whitelist */, + 100000 /* timeout in ms*/, GetWebContents()); password_protection_service_->WaitForResponse(); const LoginReputationClientRequest* actual_request = @@ -934,8 +1022,8 @@ TEST_P(PasswordProtectionServiceTest, // Initialize request triggered by saved password reuse. InitializeAndStartPasswordEntryRequest( - false /* matches_sync_password */, {kSavedDomain, kSavedDomain2}, - false /* match whitelist */, 100000 /* timeout in ms*/); + PasswordReuseEvent::SAVED_PASSWORD, {kSavedDomain, kSavedDomain2}, + false /* match whitelist */, 100000 /* timeout in ms*/, GetWebContents()); password_protection_service_->WaitForResponse(); const LoginReputationClientRequest* actual_request = @@ -956,8 +1044,7 @@ TEST_P(PasswordProtectionServiceTest, TEST_P(PasswordProtectionServiceTest, VerifyShouldShowModalWarning) { EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) - .WillRepeatedly( - Return(LoginReputationClientRequest::PasswordReuseEvent::GMAIL)); + .WillRepeatedly(Return(PasswordReuseEvent::GMAIL)); EXPECT_CALL(*password_protection_service_, GetPasswordProtectionWarningTriggerPref()) .WillRepeatedly(Return(PHISHING_REUSE)); @@ -965,23 +1052,49 @@ TEST_P(PasswordProtectionServiceTest, VerifyShouldShowModalWarning) { // Don't show modal warning if it is not a password reuse ping. EXPECT_FALSE(password_protection_service_->ShouldShowModalWarning( LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, - /*matches_sync_password=*/true, LoginReputationClientResponse::PHISHING)); + PasswordReuseEvent::SIGN_IN_PASSWORD, + LoginReputationClientResponse::PHISHING)); - // Don't show modal warning if it is not a sync password reuse. + // Don't show modal warning if it is a saved password reuse. EXPECT_FALSE(password_protection_service_->ShouldShowModalWarning( LoginReputationClientRequest::PASSWORD_REUSE_EVENT, - /*matches_sync_password=*/false, + PasswordReuseEvent::SAVED_PASSWORD, LoginReputationClientResponse::PHISHING)); - // Show modal warning otherwise + // Don't show modal warning if it is a non-sync gaia password reuse. + EXPECT_FALSE(password_protection_service_->ShouldShowModalWarning( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::OTHER_GAIA_PASSWORD, + LoginReputationClientResponse::PHISHING)); + + // Don't show modal warning if reused password type unknown. + EXPECT_FALSE(password_protection_service_->ShouldShowModalWarning( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, + LoginReputationClientResponse::PHISHING)); + + // Don't show modal warning if it is a sync password reuse but user is not + // signed in. + EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) + .WillRepeatedly(Return(PasswordReuseEvent::NOT_SIGNED_IN)); + EXPECT_FALSE(password_protection_service_->ShouldShowModalWarning( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::SIGN_IN_PASSWORD, + LoginReputationClientResponse::PHISHING)); + + // Show warning if it is a sync password reuse and user is signed in and + // is not manged by enterprise. + EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) + .WillRepeatedly(Return(PasswordReuseEvent::GMAIL)); EXPECT_TRUE(password_protection_service_->ShouldShowModalWarning( LoginReputationClientRequest::PASSWORD_REUSE_EVENT, - /*matches_sync_password=*/true, LoginReputationClientResponse::PHISHING)); + PasswordReuseEvent::SIGN_IN_PASSWORD, + LoginReputationClientResponse::PHISHING)); - // For a GSUITE account, don't show warning if password protection is off. + // For a GSUITE account, don't show warning if password protection is set to + // off by enterprise policy. EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) - .WillRepeatedly( - Return(LoginReputationClientRequest::PasswordReuseEvent::GSUITE)); + .WillRepeatedly(Return(PasswordReuseEvent::GSUITE)); EXPECT_CALL(*password_protection_service_, GetPasswordProtectionWarningTriggerPref()) .WillRepeatedly(Return(PASSWORD_PROTECTION_OFF)); @@ -990,7 +1103,8 @@ TEST_P(PasswordProtectionServiceTest, VerifyShouldShowModalWarning) { password_protection_service_->GetPasswordProtectionWarningTriggerPref()); EXPECT_FALSE(password_protection_service_->ShouldShowModalWarning( LoginReputationClientRequest::PASSWORD_REUSE_EVENT, - /*matches_sync_password=*/true, LoginReputationClientResponse::PHISHING)); + PasswordReuseEvent::SIGN_IN_PASSWORD, + LoginReputationClientResponse::PHISHING)); // For a GSUITE account, show warning if password protection is set to // PHISHING_REUSE. @@ -1002,40 +1116,183 @@ TEST_P(PasswordProtectionServiceTest, VerifyShouldShowModalWarning) { password_protection_service_->GetPasswordProtectionWarningTriggerPref()); EXPECT_TRUE(password_protection_service_->ShouldShowModalWarning( LoginReputationClientRequest::PASSWORD_REUSE_EVENT, - /*matches_sync_password=*/true, LoginReputationClientResponse::PHISHING)); + PasswordReuseEvent::SIGN_IN_PASSWORD, + LoginReputationClientResponse::PHISHING)); // Modal dialog warning is also shown on LOW_REPUTATION verdict. EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) - .WillRepeatedly( - Return(LoginReputationClientRequest::PasswordReuseEvent::GMAIL)); + .WillRepeatedly(Return(PasswordReuseEvent::GMAIL)); EXPECT_TRUE(password_protection_service_->ShouldShowModalWarning( LoginReputationClientRequest::PASSWORD_REUSE_EVENT, - /*matches_sync_password=*/true, + PasswordReuseEvent::SIGN_IN_PASSWORD, LoginReputationClientResponse::LOW_REPUTATION)); + + // Modal dialog warning should not be shown for enterprise password reuse + // if it is turned off by policy. + EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) + .WillRepeatedly(Return(PasswordReuseEvent::NOT_SIGNED_IN)); + EXPECT_CALL(*password_protection_service_, + GetPasswordProtectionWarningTriggerPref()) + .WillRepeatedly(Return(PASSWORD_PROTECTION_OFF)); + EXPECT_FALSE(password_protection_service_->ShouldShowModalWarning( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::ENTERPRISE_PASSWORD, + LoginReputationClientResponse::PHISHING)); + + // Show modal warning for enterprise password reuse if the trigger is + // configured to PHISHING_REUSE. + EXPECT_CALL(*password_protection_service_, + GetPasswordProtectionWarningTriggerPref()) + .WillRepeatedly(Return(PHISHING_REUSE)); + EXPECT_TRUE(password_protection_service_->ShouldShowModalWarning( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT, + PasswordReuseEvent::ENTERPRISE_PASSWORD, + LoginReputationClientResponse::PHISHING)); } TEST_P(PasswordProtectionServiceTest, VerifyIsEventLoggingEnabled) { // For user who is not signed-in, event logging should be disabled. - EXPECT_EQ(LoginReputationClientRequest::PasswordReuseEvent::NOT_SIGNED_IN, + EXPECT_EQ(PasswordReuseEvent::NOT_SIGNED_IN, password_protection_service_->GetSyncAccountType()); EXPECT_FALSE(password_protection_service_->IsEventLoggingEnabled()); // Event logging should be enable for all signed-in users.. EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) - .WillRepeatedly( - Return(LoginReputationClientRequest::PasswordReuseEvent::GMAIL)); - EXPECT_EQ(LoginReputationClientRequest::PasswordReuseEvent::GMAIL, + .WillRepeatedly(Return(PasswordReuseEvent::GMAIL)); + EXPECT_EQ(PasswordReuseEvent::GMAIL, password_protection_service_->GetSyncAccountType()); EXPECT_TRUE(password_protection_service_->IsEventLoggingEnabled()); EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) - .WillRepeatedly( - Return(LoginReputationClientRequest::PasswordReuseEvent::GSUITE)); - EXPECT_EQ(LoginReputationClientRequest::PasswordReuseEvent::GSUITE, + .WillRepeatedly(Return(PasswordReuseEvent::GSUITE)); + EXPECT_EQ(PasswordReuseEvent::GSUITE, password_protection_service_->GetSyncAccountType()); EXPECT_TRUE(password_protection_service_->IsEventLoggingEnabled()); } +TEST_P(PasswordProtectionServiceTest, VerifyContentTypeIsPopulated) { + content::WebContents* web_contents = GetWebContents(); + + content::WebContentsTester::For(web_contents) + ->SetMainFrameMimeType("application/pdf"); + + InitializeAndStartPasswordOnFocusRequest( + false /* match whitelist */, 10000 /* timeout in ms */, web_contents); + + password_protection_service_->WaitForResponse(); + + EXPECT_EQ( + "application/pdf", + password_protection_service_->GetLatestRequestProto()->content_type()); +} + +TEST_P(PasswordProtectionServiceTest, VerifyIsSupportedPasswordTypeForPinging) { + { + base::test::ScopedFeatureList scoped_features; + scoped_features.InitAndDisableFeature(kEnterprisePasswordProtectionV1); + EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) + .WillRepeatedly(Return(PasswordReuseEvent::NOT_SIGNED_IN)); + EXPECT_TRUE(password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::SAVED_PASSWORD)); + EXPECT_FALSE( + password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_FALSE( + password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::OTHER_GAIA_PASSWORD)); + EXPECT_FALSE( + password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::ENTERPRISE_PASSWORD)); + + EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) + .WillRepeatedly(Return(PasswordReuseEvent::GMAIL)); + EXPECT_TRUE(password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::SAVED_PASSWORD)); + EXPECT_TRUE(password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_FALSE( + password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::OTHER_GAIA_PASSWORD)); + EXPECT_FALSE( + password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::ENTERPRISE_PASSWORD)); + } + + { + base::test::ScopedFeatureList scoped_features; + scoped_features.InitAndEnableFeature(kEnterprisePasswordProtectionV1); + EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) + .WillRepeatedly(Return(PasswordReuseEvent::NOT_SIGNED_IN)); + EXPECT_TRUE(password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::SAVED_PASSWORD)); + EXPECT_FALSE( + password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_FALSE( + password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::OTHER_GAIA_PASSWORD)); + EXPECT_TRUE(password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::ENTERPRISE_PASSWORD)); + + EXPECT_CALL(*password_protection_service_, GetSyncAccountType()) + .WillRepeatedly(Return(PasswordReuseEvent::GMAIL)); + EXPECT_TRUE(password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::SAVED_PASSWORD)); + EXPECT_TRUE(password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::SIGN_IN_PASSWORD)); + EXPECT_FALSE( + password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::OTHER_GAIA_PASSWORD)); + EXPECT_TRUE(password_protection_service_->IsSupportedPasswordTypeForPinging( + PasswordReuseEvent::ENTERPRISE_PASSWORD)); + } +} + +TEST_P(PasswordProtectionServiceTest, TestMigrateCachedVerdict) { + ASSERT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + ASSERT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); + base::Time now = base::Time::Now(); + CacheVerdict(GURL("http://foo.com/abc/index.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, + LoginReputationClientResponse::LOW_REPUTATION, 10 * kMinute, + "foo.com/abc/", now); + CacheVerdict(GURL("http://bar.com/index.jsp"), + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, + PasswordReuseEvent::REUSED_PASSWORD_TYPE_UNKNOWN, + LoginReputationClientResponse::PHISHING, 10 * kMinute, "bar.com", + now); + + // Now add some entries that need to be migrated to |content_setting_map_|. + GURL hostname("http://foo.com"); + std::unique_ptr<base::DictionaryValue> cache_dictionary = + base::DictionaryValue::From(content_setting_map_->GetWebsiteSetting( + hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, + std::string(), nullptr)); + DCHECK(cache_dictionary); + cache_dictionary->SetKey("foo.com/abc", base::Value("some value")); + cache_dictionary->SetKey("bar.com", base::Value("some value")); + content_setting_map_->SetWebsiteSettingDefaultScope( + hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, + std::string(), std::move(cache_dictionary)); + + password_protection_service_->MigrateCachedVerdicts(); + cache_dictionary = + base::DictionaryValue::From(content_setting_map_->GetWebsiteSetting( + hostname, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, + std::string(), nullptr)); + EXPECT_FALSE(cache_dictionary->FindKey("foo.com/abc")); + EXPECT_FALSE(cache_dictionary->FindKey("bar.com")); + histograms_.ExpectBucketCount( + "PasswordProtection.NumberOfVerdictsMigratedDuringInitialization", 2, 1); + EXPECT_EQ(0U, GetStoredVerdictCount( + LoginReputationClientRequest::PASSWORD_REUSE_EVENT)); + EXPECT_EQ(2U, GetStoredVerdictCount( + LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE)); +} + INSTANTIATE_TEST_CASE_P( InstSBERIncog, PasswordProtectionServiceTest, |