Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 #include "components/safe_browsing/password_protection/password_protection_servi ce.h" | 4 #include "components/safe_browsing/password_protection/password_protection_servi ce.h" |
| 5 | 5 |
| 6 #include "base/memory/ptr_util.h" | 6 #include "base/memory/ptr_util.h" |
| 7 #include "base/run_loop.h" | 7 #include "base/run_loop.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/test/histogram_tester.h" | 9 #include "base/test/histogram_tester.h" |
| 10 #include "base/test/null_task_runner.h" | |
| 11 #include "components/safe_browsing/password_protection/password_protection_reque st.h" | |
| 10 #include "components/safe_browsing_db/test_database_manager.h" | 12 #include "components/safe_browsing_db/test_database_manager.h" |
| 11 #include "components/sync_preferences/testing_pref_service_syncable.h" | 13 #include "components/sync_preferences/testing_pref_service_syncable.h" |
| 12 #include "content/public/test/test_browser_thread_bundle.h" | 14 #include "content/public/test/test_browser_thread_bundle.h" |
| 15 #include "net/url_request/test_url_fetcher_factory.h" | |
| 13 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 18 |
| 16 namespace { | 19 namespace { |
| 17 | 20 |
| 18 const char kPasswordReuseMatchWhitelistHistogramName[] = | 21 const char kPasswordReuseMatchWhitelistHistogramName[] = |
| 19 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist"; | 22 "PasswordManager.PasswordReuse.MainFrameMatchCsdWhitelist"; |
| 20 const char kWhitelistedUrl[] = "http://inwhitelist.com"; | 23 const char kWhitelistedUrl[] = "http://inwhitelist.com"; |
| 21 const char kNoneWhitelistedUrl[] = "http://notinwhitelist.com"; | 24 const char kNoneWhitelistedUrl[] = "http://notinwhitelist.com"; |
| 25 const char kRequestOutcomeHistogramName[] = "PasswordProtection.RequestOutcome"; | |
| 26 const char kTargetUrl[] = "http://foo.com"; | |
| 22 | 27 |
| 23 } // namespace | 28 } // namespace |
| 24 | 29 |
| 25 namespace safe_browsing { | 30 namespace safe_browsing { |
| 26 | 31 |
| 27 class MockSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager { | 32 class MockSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager { |
| 28 public: | 33 public: |
| 29 MockSafeBrowsingDatabaseManager() {} | 34 MockSafeBrowsingDatabaseManager() {} |
| 30 | 35 |
| 31 MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL&)); | 36 MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL&)); |
| 32 | 37 |
| 33 protected: | 38 protected: |
| 34 ~MockSafeBrowsingDatabaseManager() override {} | 39 ~MockSafeBrowsingDatabaseManager() override {} |
| 35 | 40 |
| 36 private: | 41 private: |
| 37 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager); | 42 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager); |
| 38 }; | 43 }; |
| 39 | 44 |
| 45 class DummyURLRequestContextGetter : public net::URLRequestContextGetter { | |
| 46 public: | |
| 47 DummyURLRequestContextGetter() | |
| 48 : dummy_task_runner_(new base::NullTaskRunner) {} | |
| 49 | |
| 50 net::URLRequestContext* GetURLRequestContext() override { return nullptr; } | |
| 51 | |
| 52 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() | |
| 53 const override { | |
| 54 return dummy_task_runner_; | |
| 55 } | |
| 56 | |
| 57 private: | |
| 58 ~DummyURLRequestContextGetter() override {} | |
| 59 | |
| 60 scoped_refptr<base::SingleThreadTaskRunner> dummy_task_runner_; | |
| 61 }; | |
| 62 | |
| 63 class TestPasswordProtectionService : public PasswordProtectionService { | |
| 64 public: | |
| 65 TestPasswordProtectionService( | |
| 66 const scoped_refptr<SafeBrowsingDatabaseManager>& database_manager, | |
| 67 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | |
| 68 scoped_refptr<HostContentSettingsMap> content_setting_map) | |
| 69 : PasswordProtectionService(database_manager, request_context_getter), | |
| 70 content_setting_map_(content_setting_map) {} | |
| 71 | |
| 72 HostContentSettingsMap* GetSettingMapForActiveProfile() override { | |
| 73 return content_setting_map_.get(); | |
| 74 } | |
| 75 | |
| 76 void RequestFinished( | |
| 77 PasswordProtectionRequest* request, | |
| 78 std::unique_ptr<LoginReputationClientResponse> response) override { | |
| 79 latest_response_ = std::move(response); | |
| 80 } | |
| 81 | |
| 82 LoginReputationClientResponse* latest_response() { | |
| 83 return latest_response_.get(); | |
| 84 } | |
| 85 | |
| 86 private: | |
| 87 std::unique_ptr<LoginReputationClientResponse> latest_response_; | |
| 88 scoped_refptr<HostContentSettingsMap> content_setting_map_; | |
| 89 DISALLOW_COPY_AND_ASSIGN(TestPasswordProtectionService); | |
| 90 }; | |
| 91 | |
| 40 class PasswordProtectionServiceTest : public testing::Test { | 92 class PasswordProtectionServiceTest : public testing::Test { |
| 41 public: | 93 public: |
| 42 PasswordProtectionServiceTest(){}; | 94 PasswordProtectionServiceTest(){}; |
| 43 | 95 |
| 44 ~PasswordProtectionServiceTest() override { | |
| 45 content_setting_map_->ShutdownOnUIThread(); | |
| 46 } | |
| 47 | |
| 48 LoginReputationClientResponse CreateVerdictProto( | 96 LoginReputationClientResponse CreateVerdictProto( |
| 49 LoginReputationClientResponse::VerdictType verdict, | 97 LoginReputationClientResponse::VerdictType verdict, |
| 50 int cache_duration_sec, | 98 int cache_duration_sec, |
| 51 const std::string& cache_expression, | 99 const std::string& cache_expression, |
| 52 bool exact_match) { | 100 bool exact_match) { |
| 53 LoginReputationClientResponse verdict_proto; | 101 LoginReputationClientResponse verdict_proto; |
| 54 verdict_proto.set_verdict_type(verdict); | 102 verdict_proto.set_verdict_type(verdict); |
| 55 verdict_proto.set_cache_duration_sec(cache_duration_sec); | 103 verdict_proto.set_cache_duration_sec(cache_duration_sec); |
| 56 verdict_proto.set_cache_expression(cache_expression); | 104 verdict_proto.set_cache_expression(cache_expression); |
| 57 verdict_proto.set_cache_expression_exact_match(exact_match); | 105 verdict_proto.set_cache_expression_exact_match(exact_match); |
| 58 return verdict_proto; | 106 return verdict_proto; |
| 59 } | 107 } |
| 60 | 108 |
| 61 void SetUp() override { | 109 void SetUp() override { |
| 62 database_manager_ = new MockSafeBrowsingDatabaseManager(); | |
| 63 password_protection_service_ = | |
| 64 base::MakeUnique<PasswordProtectionService>(database_manager_); | |
| 65 HostContentSettingsMap::RegisterProfilePrefs(test_pref_service_.registry()); | 110 HostContentSettingsMap::RegisterProfilePrefs(test_pref_service_.registry()); |
| 66 content_setting_map_ = new HostContentSettingsMap( | 111 content_setting_map_ = new HostContentSettingsMap( |
| 67 &test_pref_service_, false /* incognito */, false /* guest_profile */); | 112 &test_pref_service_, false /* incognito */, false /* guest_profile */); |
| 113 database_manager_ = new MockSafeBrowsingDatabaseManager(); | |
| 114 dummy_request_context_getter_ = new DummyURLRequestContextGetter(); | |
| 115 password_protection_service_ = | |
| 116 base::MakeUnique<TestPasswordProtectionService>( | |
| 117 database_manager_, dummy_request_context_getter_, | |
| 118 content_setting_map_); | |
| 119 } | |
| 120 | |
| 121 void TearDown() override { content_setting_map_->ShutdownOnUIThread(); } | |
| 122 | |
| 123 // Sets up |database_manager_| and |requests_| as needed. | |
| 124 void InitializeAndStartRequest(bool is_extended_reporting, | |
| 125 bool incognito, | |
| 126 bool match_whitelist, | |
| 127 int timeout_in_ms) { | |
| 128 GURL target_url(kTargetUrl); | |
| 129 EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(target_url)) | |
| 130 .WillRepeatedly(testing::Return(match_whitelist)); | |
| 131 | |
| 132 request_ = base::MakeUnique<PasswordProtectionRequest>( | |
| 133 target_url, LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, | |
| 134 is_extended_reporting, incognito, | |
| 135 password_protection_service_->GetWeakPtr(), timeout_in_ms); | |
| 136 request_->Start(); | |
| 68 } | 137 } |
| 69 | 138 |
| 70 bool PathVariantsMatchCacheExpression(const GURL& url, | 139 bool PathVariantsMatchCacheExpression(const GURL& url, |
| 71 const std::string& cache_expression) { | 140 const std::string& cache_expression) { |
| 72 std::vector<std::string> paths; | 141 std::vector<std::string> paths; |
| 73 PasswordProtectionService::GeneratePathVariantsWithoutQuery(url, &paths); | 142 PasswordProtectionService::GeneratePathVariantsWithoutQuery(url, &paths); |
| 74 return PasswordProtectionService::PathVariantsMatchCacheExpression( | 143 return PasswordProtectionService::PathVariantsMatchCacheExpression( |
| 75 paths, | 144 paths, |
| 76 PasswordProtectionService::GetCacheExpressionPath(cache_expression)); | 145 PasswordProtectionService::GetCacheExpressionPath(cache_expression)); |
| 77 } | 146 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 90 int cache_duration_sec, | 159 int cache_duration_sec, |
| 91 const std::string& cache_expression, | 160 const std::string& cache_expression, |
| 92 bool exact_match, | 161 bool exact_match, |
| 93 const base::Time& verdict_received_time) { | 162 const base::Time& verdict_received_time) { |
| 94 LoginReputationClientResponse response(CreateVerdictProto( | 163 LoginReputationClientResponse response(CreateVerdictProto( |
| 95 verdict, cache_duration_sec, cache_expression, exact_match)); | 164 verdict, cache_duration_sec, cache_expression, exact_match)); |
| 96 password_protection_service_->CacheVerdict( | 165 password_protection_service_->CacheVerdict( |
| 97 url, &response, verdict_received_time, content_setting_map_.get()); | 166 url, &response, verdict_received_time, content_setting_map_.get()); |
| 98 } | 167 } |
| 99 | 168 |
| 100 size_t GetPasswordProtectionSettingCount() { | 169 size_t GetStoredVerdictCount() { |
| 101 ContentSettingsForOneType password_protection_settings; | 170 return password_protection_service_->GetStoredVerdictCount(); |
| 102 content_setting_map_->GetSettingsForOneType( | |
| 103 CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, std::string(), | |
| 104 &password_protection_settings); | |
| 105 return password_protection_settings.size(); | |
| 106 } | |
| 107 | |
| 108 size_t GetVerdictCountForOrigin(const GURL& origin_url) { | |
| 109 std::unique_ptr<base::DictionaryValue> verdict_dictionary = | |
| 110 base::DictionaryValue::From(content_setting_map_->GetWebsiteSetting( | |
| 111 origin_url, GURL(), CONTENT_SETTINGS_TYPE_PASSWORD_PROTECTION, | |
| 112 std::string(), nullptr)); | |
| 113 return verdict_dictionary->size(); | |
| 114 } | 171 } |
| 115 | 172 |
| 116 protected: | 173 protected: |
| 117 // |thread_bundle_| is needed here because this test involves both UI and IO | 174 // |thread_bundle_| is needed here because this test involves both UI and IO |
| 118 // threads. | 175 // threads. |
| 119 content::TestBrowserThreadBundle thread_bundle_; | 176 content::TestBrowserThreadBundle thread_bundle_; |
| 120 scoped_refptr<MockSafeBrowsingDatabaseManager> database_manager_; | 177 scoped_refptr<MockSafeBrowsingDatabaseManager> database_manager_; |
| 121 std::unique_ptr<PasswordProtectionService> password_protection_service_; | |
| 122 sync_preferences::TestingPrefServiceSyncable test_pref_service_; | 178 sync_preferences::TestingPrefServiceSyncable test_pref_service_; |
| 123 scoped_refptr<HostContentSettingsMap> content_setting_map_; | 179 scoped_refptr<HostContentSettingsMap> content_setting_map_; |
| 180 scoped_refptr<DummyURLRequestContextGetter> dummy_request_context_getter_; | |
| 181 std::unique_ptr<TestPasswordProtectionService> password_protection_service_; | |
| 182 std::unique_ptr<PasswordProtectionRequest> request_; | |
| 183 base::HistogramTester histograms_; | |
| 124 }; | 184 }; |
| 125 | 185 |
| 126 TEST_F(PasswordProtectionServiceTest, | 186 TEST_F(PasswordProtectionServiceTest, |
| 127 TestPasswordReuseMatchWhitelistHistogram) { | 187 TestPasswordReuseMatchWhitelistHistogram) { |
| 128 const GURL whitelisted_url(kWhitelistedUrl); | 188 const GURL whitelisted_url(kWhitelistedUrl); |
| 129 const GURL not_whitelisted_url(kNoneWhitelistedUrl); | 189 const GURL not_whitelisted_url(kNoneWhitelistedUrl); |
| 130 EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(whitelisted_url)) | 190 EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(whitelisted_url)) |
| 131 .WillOnce(testing::Return(true)); | 191 .WillOnce(testing::Return(true)); |
| 132 EXPECT_CALL(*database_manager_.get(), | 192 EXPECT_CALL(*database_manager_.get(), |
| 133 MatchCsdWhitelistUrl(not_whitelisted_url)) | 193 MatchCsdWhitelistUrl(not_whitelisted_url)) |
| 134 .WillOnce(testing::Return(false)); | 194 .WillOnce(testing::Return(false)); |
| 135 base::HistogramTester histograms; | 195 histograms_.ExpectTotalCount(kPasswordReuseMatchWhitelistHistogramName, 0); |
| 136 histograms.ExpectTotalCount(kPasswordReuseMatchWhitelistHistogramName, 0); | |
| 137 | 196 |
| 138 // Empty url should not increment metric. | 197 // Empty url should not increment metric. |
| 139 password_protection_service_->RecordPasswordReuse(GURL()); | 198 password_protection_service_->RecordPasswordReuse(GURL()); |
| 140 base::RunLoop().RunUntilIdle(); | 199 base::RunLoop().RunUntilIdle(); |
| 141 histograms.ExpectTotalCount(kPasswordReuseMatchWhitelistHistogramName, 0); | 200 histograms_.ExpectTotalCount(kPasswordReuseMatchWhitelistHistogramName, 0); |
| 142 | 201 |
| 143 // Whitelisted url should increase "True" bucket by 1. | 202 // Whitelisted url should increase "True" bucket by 1. |
| 144 password_protection_service_->RecordPasswordReuse(whitelisted_url); | 203 password_protection_service_->RecordPasswordReuse(whitelisted_url); |
| 145 base::RunLoop().RunUntilIdle(); | 204 base::RunLoop().RunUntilIdle(); |
| 146 EXPECT_THAT( | 205 EXPECT_THAT( |
| 147 histograms.GetAllSamples(kPasswordReuseMatchWhitelistHistogramName), | 206 histograms_.GetAllSamples(kPasswordReuseMatchWhitelistHistogramName), |
| 148 testing::ElementsAre(base::Bucket(1, 1))); | 207 testing::ElementsAre(base::Bucket(1, 1))); |
| 149 | 208 |
| 150 // Non-whitelisted url should increase "False" bucket by 1. | 209 // Non-whitelisted url should increase "False" bucket by 1. |
| 151 password_protection_service_->RecordPasswordReuse(not_whitelisted_url); | 210 password_protection_service_->RecordPasswordReuse(not_whitelisted_url); |
| 152 base::RunLoop().RunUntilIdle(); | 211 base::RunLoop().RunUntilIdle(); |
| 153 EXPECT_THAT( | 212 EXPECT_THAT( |
| 154 histograms.GetAllSamples(kPasswordReuseMatchWhitelistHistogramName), | 213 histograms_.GetAllSamples(kPasswordReuseMatchWhitelistHistogramName), |
| 155 testing::ElementsAre(base::Bucket(0, 1), base::Bucket(1, 1))); | 214 testing::ElementsAre(base::Bucket(0, 1), base::Bucket(1, 1))); |
| 156 } | 215 } |
| 157 | 216 |
| 158 TEST_F(PasswordProtectionServiceTest, TestParseInvalidVerdictEntry) { | 217 TEST_F(PasswordProtectionServiceTest, TestParseInvalidVerdictEntry) { |
| 159 std::unique_ptr<base::DictionaryValue> invalid_verdict_entry = | 218 std::unique_ptr<base::DictionaryValue> invalid_verdict_entry = |
| 160 base::MakeUnique<base::DictionaryValue>(); | 219 base::MakeUnique<base::DictionaryValue>(); |
| 161 invalid_verdict_entry->SetString("cache_creation_time", "invalid_time"); | 220 invalid_verdict_entry->SetString("cache_creation_time", "invalid_time"); |
| 162 | 221 |
| 163 int cache_creation_time; | 222 int cache_creation_time; |
| 164 LoginReputationClientResponse response; | 223 LoginReputationClientResponse response; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 cache_expression)); | 316 cache_expression)); |
| 258 EXPECT_TRUE(PathMatchCacheExpressionExactly( | 317 EXPECT_TRUE(PathMatchCacheExpressionExactly( |
| 259 GURL("http://evil.com/bad/index.html"), cache_expression)); | 318 GURL("http://evil.com/bad/index.html"), cache_expression)); |
| 260 EXPECT_FALSE(PathMatchCacheExpressionExactly(GURL("http://evil.com/bad/abc/"), | 319 EXPECT_FALSE(PathMatchCacheExpressionExactly(GURL("http://evil.com/bad/abc/"), |
| 261 cache_expression)); | 320 cache_expression)); |
| 262 EXPECT_FALSE(PathMatchCacheExpressionExactly( | 321 EXPECT_FALSE(PathMatchCacheExpressionExactly( |
| 263 GURL("http://evil.com/bad/abc/login.jsp"), cache_expression)); | 322 GURL("http://evil.com/bad/abc/login.jsp"), cache_expression)); |
| 264 } | 323 } |
| 265 | 324 |
| 266 TEST_F(PasswordProtectionServiceTest, TestCachedVerdicts) { | 325 TEST_F(PasswordProtectionServiceTest, TestCachedVerdicts) { |
| 267 ASSERT_EQ(0U, GetPasswordProtectionSettingCount()); | 326 ASSERT_EQ(0U, GetStoredVerdictCount()); |
| 268 // Assume each verdict has a TTL of 10 minutes. | 327 // Assume each verdict has a TTL of 10 minutes. |
| 269 // Cache a verdict for http://www.test.com/foo/index.html | 328 // Cache a verdict for http://www.test.com/foo/index.html |
| 270 CacheVerdict(GURL("http://www.test.com/foo/index.html"), | 329 CacheVerdict(GURL("http://www.test.com/foo/index.html"), |
| 271 LoginReputationClientResponse::SAFE, 10 * 60, "test.com/foo", | 330 LoginReputationClientResponse::SAFE, 10 * 60, "test.com/foo", |
| 272 false, base::Time::Now()); | 331 false, base::Time::Now()); |
| 273 | 332 |
| 274 EXPECT_EQ(1U, GetPasswordProtectionSettingCount()); | 333 EXPECT_EQ(1U, GetStoredVerdictCount()); |
| 275 EXPECT_EQ(1U, GetVerdictCountForOrigin( | |
| 276 GURL("http://www.test.com/foo/index.html").GetOrigin())); | |
| 277 | 334 |
| 278 // Cache another verdict with the some origin and cache_expression should | 335 // Cache another verdict with the some origin and cache_expression should |
| 279 // override the cache. | 336 // override the cache. |
| 280 CacheVerdict(GURL("http://www.test.com/foo/index2.html"), | 337 CacheVerdict(GURL("http://www.test.com/foo/index2.html"), |
| 281 LoginReputationClientResponse::PHISHING, 10 * 60, "test.com/foo", | 338 LoginReputationClientResponse::PHISHING, 10 * 60, "test.com/foo", |
| 282 false, base::Time::Now()); | 339 false, base::Time::Now()); |
| 283 EXPECT_EQ(1U, GetPasswordProtectionSettingCount()); | 340 EXPECT_EQ(1U, GetStoredVerdictCount()); |
| 284 EXPECT_EQ(1U, | 341 LoginReputationClientResponse out_verdict; |
| 285 GetVerdictCountForOrigin(GURL("http://www.test.com/").GetOrigin())); | |
| 286 EXPECT_EQ(LoginReputationClientResponse::PHISHING, | 342 EXPECT_EQ(LoginReputationClientResponse::PHISHING, |
| 287 password_protection_service_->GetCachedVerdict( | 343 password_protection_service_->GetCachedVerdict( |
| 288 content_setting_map_.get(), | 344 content_setting_map_.get(), |
| 289 GURL("http://www.test.com/foo/index2.html"))); | 345 GURL("http://www.test.com/foo/index2.html"), &out_verdict)); |
| 290 | 346 |
| 291 // Cache another verdict with the same origin but different cache_expression | 347 // Cache another verdict with the same origin but different cache_expression |
| 292 // will not increase setting count, but will increase the number of verdicts | 348 // will not increase setting count, but will increase the number of verdicts |
| 293 // in the given origin. | 349 // in the given origin. |
| 294 CacheVerdict(GURL("http://www.test.com/bar/index2.html"), | 350 CacheVerdict(GURL("http://www.test.com/bar/index2.html"), |
| 295 LoginReputationClientResponse::SAFE, 10 * 60, "test.com/bar", | 351 LoginReputationClientResponse::SAFE, 10 * 60, "test.com/bar", |
| 296 false, base::Time::Now()); | 352 false, base::Time::Now()); |
| 297 EXPECT_EQ(1U, GetPasswordProtectionSettingCount()); | 353 EXPECT_EQ(2U, GetStoredVerdictCount()); |
| 298 EXPECT_EQ(2U, | |
| 299 GetVerdictCountForOrigin(GURL("http://www.test.com/").GetOrigin())); | |
| 300 } | 354 } |
| 301 | 355 |
| 302 TEST_F(PasswordProtectionServiceTest, TestGetCachedVerdicts) { | 356 TEST_F(PasswordProtectionServiceTest, TestGetCachedVerdicts) { |
| 303 ASSERT_EQ(0U, GetPasswordProtectionSettingCount()); | 357 ASSERT_EQ(0U, GetStoredVerdictCount()); |
| 304 // Prepare 3 verdicts of the same origin with different cache expressions: | 358 // Prepare 3 verdicts of the same origin with different cache expressions: |
| 305 // (1) require exact match, not expired. | 359 // (1) require exact match, not expired. |
| 306 // (2) not require exact match, not expired. | 360 // (2) not require exact match, not expired. |
| 307 // (3) require exact match, expired. | 361 // (3) require exact match, expired. |
| 308 base::Time now = base::Time::Now(); | 362 base::Time now = base::Time::Now(); |
| 309 CacheVerdict(GURL("http://test.com/login.html"), | 363 CacheVerdict(GURL("http://test.com/login.html"), |
| 310 LoginReputationClientResponse::SAFE, 10 * 60, "test.com", true, | 364 LoginReputationClientResponse::SAFE, 10 * 60, "test.com", true, |
| 311 now); | 365 now); |
| 312 CacheVerdict(GURL("http://test.com/abc/index.jsp"), | 366 CacheVerdict(GURL("http://test.com/abc/index.jsp"), |
| 313 LoginReputationClientResponse::LOW_REPUTATION, 10 * 60, | 367 LoginReputationClientResponse::LOW_REPUTATION, 10 * 60, |
| 314 "test.com/abc", false, now); | 368 "test.com/abc", false, now); |
| 315 CacheVerdict( | 369 CacheVerdict( |
| 316 GURL("http://test.com/def/index.jsp"), | 370 GURL("http://test.com/def/index.jsp"), |
| 317 LoginReputationClientResponse::PHISHING, 10 * 60, "test.com/def", false, | 371 LoginReputationClientResponse::PHISHING, 10 * 60, "test.com/def", false, |
| 318 base::Time::FromDoubleT(now.ToDoubleT() - | 372 base::Time::FromDoubleT(now.ToDoubleT() - |
| 319 24.0 * 60.0 * 60.0)); // Yesterday, expired. | 373 24.0 * 60.0 * 60.0)); // Yesterday, expired. |
| 320 ASSERT_EQ(1U, GetPasswordProtectionSettingCount()); | 374 ASSERT_EQ(3U, GetStoredVerdictCount()); |
| 321 | 375 |
| 322 // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL with unknown origin. | 376 // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL with unknown origin. |
| 377 LoginReputationClientResponse actual_verdict; | |
| 323 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, | 378 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, |
| 324 password_protection_service_->GetCachedVerdict( | 379 password_protection_service_->GetCachedVerdict( |
| 325 content_setting_map_.get(), GURL("http://www.unknown.com/"))); | 380 content_setting_map_.get(), GURL("http://www.unknown.com/"), |
| 381 &actual_verdict)); | |
| 326 | 382 |
| 327 // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL with http://test.com | 383 // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL with http://test.com |
| 328 // origin, but doesn't match any known cache_expression. | 384 // origin, but doesn't match any known cache_expression. |
| 329 EXPECT_EQ( | 385 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, |
| 330 LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, | 386 password_protection_service_->GetCachedVerdict( |
| 331 password_protection_service_->GetCachedVerdict( | 387 content_setting_map_.get(), GURL("http://test.com/xyz/foo.jsp"), |
| 332 content_setting_map_.get(), GURL("http://test.com/xyz/foo.jsp"))); | 388 &actual_verdict)); |
| 333 | 389 |
| 334 // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL whose variants match | 390 // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL whose variants match |
| 335 // test.com/def, since corresponding entry is expired. | 391 // test.com/def, since corresponding entry is expired. |
| 336 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, | 392 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, |
| 337 password_protection_service_->GetCachedVerdict( | 393 password_protection_service_->GetCachedVerdict( |
| 338 content_setting_map_.get(), | 394 content_setting_map_.get(), |
| 339 GURL("http://test.com/def/ghi/index.html"))); | 395 GURL("http://test.com/def/ghi/index.html"), &actual_verdict)); |
| 340 | 396 |
| 341 // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL whose variants match | 397 // Return VERDICT_TYPE_UNSPECIFIED if look up for a URL whose variants match |
| 342 // test.com, but not match it exactly. Return SAFE if it is a exact match of | 398 // test.com, but not match it exactly. Return SAFE if it is a exact match of |
| 343 // test.com. | 399 // test.com. |
| 344 EXPECT_EQ( | 400 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, |
| 345 LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, | 401 password_protection_service_->GetCachedVerdict( |
| 346 password_protection_service_->GetCachedVerdict( | 402 content_setting_map_.get(), |
| 347 content_setting_map_.get(), GURL("http://test.com/ghi/index.html"))); | 403 GURL("http://test.com/ghi/index.html"), &actual_verdict)); |
| 348 EXPECT_EQ(LoginReputationClientResponse::SAFE, | 404 EXPECT_EQ(LoginReputationClientResponse::SAFE, |
| 349 password_protection_service_->GetCachedVerdict( | 405 password_protection_service_->GetCachedVerdict( |
| 350 content_setting_map_.get(), | 406 content_setting_map_.get(), |
| 351 GURL("http://test.com/term_of_service.html"))); | 407 GURL("http://test.com/term_of_service.html"), &actual_verdict)); |
| 352 | 408 |
| 353 // Return LOW_REPUTATION if look up for a URL whose variants match | 409 // Return LOW_REPUTATION if look up for a URL whose variants match |
| 354 // test.com/abc. | 410 // test.com/abc. |
| 355 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION, | 411 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION, |
| 356 password_protection_service_->GetCachedVerdict( | 412 password_protection_service_->GetCachedVerdict( |
| 357 content_setting_map_.get(), GURL("http://test.com/abc/"))); | 413 content_setting_map_.get(), GURL("http://test.com/abc/"), |
| 358 EXPECT_EQ( | 414 &actual_verdict)); |
| 359 LoginReputationClientResponse::LOW_REPUTATION, | 415 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION, |
| 360 password_protection_service_->GetCachedVerdict( | 416 password_protection_service_->GetCachedVerdict( |
| 361 content_setting_map_.get(), GURL("http://test.com/abc/bar.jsp"))); | 417 content_setting_map_.get(), GURL("http://test.com/abc/bar.jsp"), |
| 418 &actual_verdict)); | |
| 362 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION, | 419 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION, |
| 363 password_protection_service_->GetCachedVerdict( | 420 password_protection_service_->GetCachedVerdict( |
| 364 content_setting_map_.get(), | 421 content_setting_map_.get(), |
| 365 GURL("http://test.com/abc/foo/bar.html"))); | 422 GURL("http://test.com/abc/foo/bar.html"), &actual_verdict)); |
| 366 } | 423 } |
| 367 | 424 |
| 368 TEST_F(PasswordProtectionServiceTest, TestCleanUpCachedVerdicts) { | 425 TEST_F(PasswordProtectionServiceTest, TestCleanUpCachedVerdicts) { |
| 369 ASSERT_EQ(0U, GetPasswordProtectionSettingCount()); | 426 ASSERT_EQ(0U, GetStoredVerdictCount()); |
| 370 // Prepare 2 verdicts. One is for origin "http://foo.com", and the other is | 427 // Prepare 2 verdicts. One is for origin "http://foo.com", and the other is |
| 371 // for "http://bar.com". | 428 // for "http://bar.com". |
| 372 base::Time now = base::Time::Now(); | 429 base::Time now = base::Time::Now(); |
| 373 CacheVerdict(GURL("http://foo.com/abc/index.jsp"), | 430 CacheVerdict(GURL("http://foo.com/abc/index.jsp"), |
| 374 LoginReputationClientResponse::LOW_REPUTATION, 10 * 60, | 431 LoginReputationClientResponse::LOW_REPUTATION, 10 * 60, |
| 375 "foo.com/abc", false, now); | 432 "foo.com/abc", false, now); |
| 376 CacheVerdict(GURL("http://bar.com/index.jsp"), | 433 CacheVerdict(GURL("http://bar.com/index.jsp"), |
| 377 LoginReputationClientResponse::PHISHING, 10 * 60, "bar.com", | 434 LoginReputationClientResponse::PHISHING, 10 * 60, "bar.com", |
| 378 false, now); | 435 false, now); |
| 379 ASSERT_EQ(2U, GetPasswordProtectionSettingCount()); | 436 ASSERT_EQ(2U, GetStoredVerdictCount()); |
| 380 | 437 |
| 381 // Delete a bar.com URL. Corresponding content setting keyed on | 438 // Delete a bar.com URL. Corresponding content setting keyed on |
| 382 // origin "http://bar.com" should be removed, | 439 // origin "http://bar.com" should be removed, |
| 383 history::URLRows deleted_urls; | 440 history::URLRows deleted_urls; |
| 384 deleted_urls.push_back(history::URLRow(GURL("http://bar.com"))); | 441 deleted_urls.push_back(history::URLRow(GURL("http://bar.com"))); |
| 385 password_protection_service_->RemoveContentSettingsOnURLsDeleted( | 442 password_protection_service_->RemoveContentSettingsOnURLsDeleted( |
| 386 false /* all_history */, deleted_urls, content_setting_map_.get()); | 443 false /* all_history */, deleted_urls, content_setting_map_.get()); |
| 387 EXPECT_EQ(1U, GetPasswordProtectionSettingCount()); | 444 EXPECT_EQ(1U, GetStoredVerdictCount()); |
| 388 EXPECT_EQ(LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, | 445 LoginReputationClientResponse actual_verdict; |
| 389 password_protection_service_->GetCachedVerdict( | 446 EXPECT_EQ( |
| 390 content_setting_map_.get(), GURL("http://bar.com"))); | 447 LoginReputationClientResponse::VERDICT_TYPE_UNSPECIFIED, |
| 448 password_protection_service_->GetCachedVerdict( | |
| 449 content_setting_map_.get(), GURL("http://bar.com"), &actual_verdict)); | |
| 391 | 450 |
| 392 // If delete all history. All password protection content settings should be | 451 // If delete all history. All password protection content settings should be |
| 393 // gone. | 452 // gone. |
| 394 password_protection_service_->RemoveContentSettingsOnURLsDeleted( | 453 password_protection_service_->RemoveContentSettingsOnURLsDeleted( |
| 395 true /* all_history */, history::URLRows(), content_setting_map_.get()); | 454 true /* all_history */, history::URLRows(), content_setting_map_.get()); |
| 396 EXPECT_EQ(0U, GetPasswordProtectionSettingCount()); | 455 EXPECT_EQ(0U, GetStoredVerdictCount()); |
| 397 } | 456 } |
| 398 | 457 |
| 458 TEST_F(PasswordProtectionServiceTest, TestNoRequestSentForIncognito) { | |
| 459 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); | |
| 460 InitializeAndStartRequest(true /* extended_reporting */, true /* incognito */, | |
| 461 false /* match whitelist */, 10 /* timeout */); | |
| 462 base::RunLoop().RunUntilIdle(); | |
| 463 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); | |
| 464 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), | |
| 465 testing::ElementsAre(base::Bucket(7 /* INCOGNITO */, 1))); | |
| 466 } | |
| 467 | |
| 468 TEST_F(PasswordProtectionServiceTest, | |
| 469 TestNoRequestSentForNonExtendedReporting) { | |
| 470 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); | |
| 471 | |
| 472 InitializeAndStartRequest(false /* extended_reporting */, | |
| 473 false /* incognito */, false /* match whitelist */, | |
| 474 10000 /* timeout in ms*/); | |
| 475 base::RunLoop().RunUntilIdle(); | |
| 476 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); | |
| 477 EXPECT_THAT( | |
| 478 histograms_.GetAllSamples(kRequestOutcomeHistogramName), | |
| 479 testing::ElementsAre(base::Bucket(6 /* NO_EXTENDED_REPORTING */, 1))); | |
| 480 } | |
| 481 | |
| 482 TEST_F(PasswordProtectionServiceTest, TestNoRequestSentForWhitelistedURL) { | |
| 483 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); | |
| 484 InitializeAndStartRequest(true /* extended_reporting */, | |
| 485 false /* incognito */, true /* match whitelist */, | |
| 486 10000 /* timeout in ms*/); | |
| 487 base::RunLoop().RunUntilIdle(); | |
| 488 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); | |
| 489 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), | |
| 490 testing::ElementsAre(base::Bucket(4 /* MATCHED_WHITELIST */, 1))); | |
| 491 } | |
| 492 | |
| 493 TEST_F(PasswordProtectionServiceTest, TestNoRequestSentIfVerdictAlreadyCached) { | |
| 494 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); | |
| 495 CacheVerdict(GURL(kTargetUrl), LoginReputationClientResponse::LOW_REPUTATION, | |
| 496 600, GURL(kTargetUrl).host(), true, base::Time::Now()); | |
| 497 InitializeAndStartRequest(true /* extended_reporting */, | |
| 498 false /* incognito */, false /* match whitelist */, | |
| 499 10000 /* timeout in ms*/); | |
| 500 base::RunLoop().RunUntilIdle(); | |
| 501 EXPECT_THAT( | |
| 502 histograms_.GetAllSamples(kRequestOutcomeHistogramName), | |
| 503 testing::ElementsAre(base::Bucket(5 /* RESPONSE_ALREADY_CACHED */, 1))); | |
| 504 EXPECT_EQ(LoginReputationClientResponse::LOW_REPUTATION, | |
| 505 password_protection_service_->latest_response()->verdict_type()); | |
| 506 } | |
| 507 | |
| 508 TEST_F(PasswordProtectionServiceTest, TestResponseFetchFailed) { | |
| 509 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); | |
| 510 net::TestURLFetcher failed_fetcher(0, GURL("http://bar.com"), nullptr); | |
| 511 // Set up failed response. | |
| 512 failed_fetcher.set_status( | |
| 513 net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_FAILED)); | |
| 514 | |
| 515 InitializeAndStartRequest(true /* extended_reporting */, | |
| 516 false /* incognito */, false /* match whitelist */, | |
| 517 10000 /* timeout in ms*/); | |
| 518 request_->OnURLFetchComplete(&failed_fetcher); | |
| 519 base::RunLoop().RunUntilIdle(); | |
| 520 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); | |
| 521 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), | |
| 522 testing::ElementsAre(base::Bucket(9 /* FETCH_FAILED */, 1))); | |
| 523 } | |
| 524 | |
| 525 TEST_F(PasswordProtectionServiceTest, TestMalformedResponse) { | |
| 526 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); | |
| 527 // Set up malformed response. | |
| 528 net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr); | |
| 529 fetcher.set_status( | |
| 530 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK)); | |
| 531 fetcher.set_response_code(200); | |
| 532 fetcher.SetResponseString("invalid response"); | |
| 533 | |
| 534 InitializeAndStartRequest(true /* extended_reporting */, | |
| 535 false /* incognito */, false /* match whitelist */, | |
| 536 10000 /* timeout in ms*/); | |
| 537 request_->OnURLFetchComplete(&fetcher); | |
| 538 base::RunLoop().RunUntilIdle(); | |
| 539 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); | |
| 540 EXPECT_THAT( | |
| 541 histograms_.GetAllSamples(kRequestOutcomeHistogramName), | |
| 542 testing::ElementsAre(base::Bucket(10 /* RESPONSE_MALFORMED */, 1))); | |
| 543 } | |
| 544 | |
| 545 TEST_F(PasswordProtectionServiceTest, TestRequestTimedout) { | |
| 546 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); | |
| 547 InitializeAndStartRequest(true /* extended_reporting */, | |
| 548 false /* incognito */, false /* match whitelist */, | |
| 549 0 /* timeout immediately */); | |
| 550 base::RunLoop().RunUntilIdle(); | |
| 551 EXPECT_EQ(nullptr, password_protection_service_->latest_response()); | |
| 552 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), | |
| 553 testing::ElementsAre(base::Bucket(3 /* TIMEDOUT */, 1))); | |
| 554 } | |
| 555 | |
| 556 TEST_F(PasswordProtectionServiceTest, TestRequestAndResponseSuccessfull) { | |
| 557 histograms_.ExpectTotalCount(kRequestOutcomeHistogramName, 0); | |
| 558 // Set up valid response. | |
| 559 net::TestURLFetcher fetcher(0, GURL("http://bar.com"), nullptr); | |
| 560 fetcher.set_status( | |
| 561 net::URLRequestStatus(net::URLRequestStatus::SUCCESS, net::OK)); | |
| 562 fetcher.set_response_code(200); | |
| 563 LoginReputationClientResponse expected_response = | |
| 564 CreateVerdictProto(LoginReputationClientResponse::PHISHING, 600, | |
| 565 GURL(kTargetUrl).host(), true); | |
| 566 fetcher.SetResponseString(expected_response.SerializeAsString()); | |
| 567 | |
| 568 InitializeAndStartRequest(true /* extended_reporting */, | |
| 569 false /* incognito */, false /* match whitelist */, | |
| 570 10000 /* timeout in ms*/); | |
| 571 request_->OnURLFetchComplete(&fetcher); | |
| 572 base::RunLoop().RunUntilIdle(); | |
| 573 EXPECT_THAT(histograms_.GetAllSamples(kRequestOutcomeHistogramName), | |
| 574 testing::ElementsAre(base::Bucket(1 /* SUCCEEDED */, 1))); | |
| 575 LoginReputationClientResponse* actual_response = | |
| 576 password_protection_service_->latest_response(); | |
| 577 EXPECT_EQ(expected_response.verdict_type(), actual_response->verdict_type()); | |
| 578 EXPECT_EQ(expected_response.cache_expression(), | |
| 579 actual_response->cache_expression()); | |
| 580 EXPECT_EQ(expected_response.cache_expression_exact_match(), | |
| 581 actual_response->cache_expression_exact_match()); | |
| 582 EXPECT_EQ(expected_response.cache_duration_sec(), | |
| 583 actual_response->cache_duration_sec()); | |
| 584 } | |
|
Nathan Parker
2017/03/24 00:41:50
Can you test tearing down when there are pending r
Jialiu Lin
2017/03/24 01:42:43
Done.
| |
| 399 } // namespace safe_browsing | 585 } // namespace safe_browsing |
| OLD | NEW |