Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 | 4 |
| 5 #include "chrome/browser/safe_browsing/permission_reporter.h" | 5 #include "chrome/browser/safe_browsing/permission_reporter.h" |
| 6 | 6 |
| 7 #include "base/feature_list.h" | 7 #include "base/feature_list.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/metrics/field_trial.h" | 9 #include "base/metrics/field_trial.h" |
| 10 #include "base/test/simple_test_clock.h" | |
| 11 #include "base/time/time.h" | |
| 10 #include "chrome/common/safe_browsing/permission_report.pb.h" | 12 #include "chrome/common/safe_browsing/permission_report.pb.h" |
| 11 #include "components/variations/active_field_trials.h" | 13 #include "components/variations/active_field_trials.h" |
| 12 #include "content/public/browser/permission_type.h" | 14 #include "content/public/browser/permission_type.h" |
| 13 #include "net/url_request/report_sender.h" | 15 #include "net/url_request/report_sender.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 17 |
| 16 using content::PermissionType; | 18 using content::PermissionType; |
| 17 | 19 |
| 18 namespace safe_browsing { | 20 namespace safe_browsing { |
| 19 | 21 |
| 20 namespace { | 22 namespace { |
| 21 | 23 |
| 22 // URL to upload permission action reports. | 24 // URL to upload permission action reports. |
| 23 const char kPermissionActionReportingUploadUrl[] = | 25 const char kPermissionActionReportingUploadUrl[] = |
| 24 "http://safebrowsing.googleusercontent.com/safebrowsing/clientreport/" | 26 "http://safebrowsing.googleusercontent.com/safebrowsing/clientreport/" |
| 25 "permission-action"; | 27 "permission-action"; |
| 26 | 28 |
| 27 const char kDummyOrigin[] = "http://example.test/"; | 29 const int kMaximumReportsPerOriginPerPermissionPerMinute = 5; |
| 28 const PermissionType kDummyPermission = PermissionType::GEOLOCATION; | 30 |
| 31 const char kDummyOriginOne[] = "http://example.test/"; | |
| 32 const char kDummyOriginTwo[] = "http://example2.test/"; | |
| 33 const PermissionType kDummyPermissionOne = PermissionType::GEOLOCATION; | |
| 34 const PermissionType kDummyPermissionTwo = PermissionType::NOTIFICATIONS; | |
| 29 const PermissionAction kDummyAction = GRANTED; | 35 const PermissionAction kDummyAction = GRANTED; |
| 30 const PermissionReport::PermissionType kDummyPermissionReportPermission = | |
| 31 PermissionReport::GEOLOCATION; | |
| 32 const PermissionReport::Action kDummyPermissionReportAction = | |
| 33 PermissionReport::GRANTED; | |
| 34 | 36 |
| 35 const char kDummyTrialOne[] = "trial one"; | 37 const char kDummyTrialOne[] = "trial one"; |
| 36 const char kDummyGroupOne[] = "group one"; | 38 const char kDummyGroupOne[] = "group one"; |
| 37 const char kDummyTrialTwo[] = "trial two"; | 39 const char kDummyTrialTwo[] = "trial two"; |
| 38 const char kDummyGroupTwo[] = "group two"; | 40 const char kDummyGroupTwo[] = "group two"; |
| 39 | 41 |
| 40 const char kFeatureOnByDefaultName[] = "OnByDefault"; | 42 const char kFeatureOnByDefaultName[] = "OnByDefault"; |
| 41 struct base::Feature kFeatureOnByDefault { | 43 struct base::Feature kFeatureOnByDefault { |
| 42 kFeatureOnByDefaultName, base::FEATURE_ENABLED_BY_DEFAULT | 44 kFeatureOnByDefaultName, base::FEATURE_ENABLED_BY_DEFAULT |
| 43 }; | 45 }; |
| 44 | 46 |
| 45 const char kFeatureOffByDefaultName[] = "OffByDefault"; | 47 const char kFeatureOffByDefaultName[] = "OffByDefault"; |
| 46 struct base::Feature kFeatureOffByDefault { | 48 struct base::Feature kFeatureOffByDefault { |
| 47 kFeatureOffByDefaultName, base::FEATURE_DISABLED_BY_DEFAULT | 49 kFeatureOffByDefaultName, base::FEATURE_DISABLED_BY_DEFAULT |
| 48 }; | 50 }; |
| 49 | 51 |
| 50 // A mock ReportSender that keeps track of the last report sent. | 52 // A mock ReportSender that keeps track of the last report sent. |
| 51 class MockReportSender : public net::ReportSender { | 53 class MockReportSender : public net::ReportSender { |
| 52 public: | 54 public: |
| 53 MockReportSender() : net::ReportSender(nullptr, DO_NOT_SEND_COOKIES) {} | 55 MockReportSender() : net::ReportSender(nullptr, DO_NOT_SEND_COOKIES) { |
| 56 number_of_reports_ = 0; | |
| 57 } | |
| 58 | |
| 54 ~MockReportSender() override {} | 59 ~MockReportSender() override {} |
| 55 | 60 |
| 56 void Send(const GURL& report_uri, const std::string& report) override { | 61 void Send(const GURL& report_uri, const std::string& report) override { |
| 57 latest_report_uri_ = report_uri; | 62 latest_report_uri_ = report_uri; |
| 58 latest_report_ = report; | 63 latest_report_ = report; |
| 64 number_of_reports_++; | |
| 59 } | 65 } |
| 60 | 66 |
| 61 const GURL& latest_report_uri() { return latest_report_uri_; } | 67 const GURL& latest_report_uri() { return latest_report_uri_; } |
| 62 | 68 |
| 63 const std::string& latest_report() { return latest_report_; } | 69 const std::string& latest_report() { return latest_report_; } |
| 64 | 70 |
| 71 int GetAndResetNumberReports() { | |
|
kcarattini
2016/07/06 06:28:20
How about "GetAndResetNumberOfReportsSent"?
stefanocs
2016/07/06 07:17:38
Done.
| |
| 72 int new_reports = number_of_reports_; | |
| 73 number_of_reports_ = 0; | |
| 74 return new_reports; | |
| 75 } | |
| 76 | |
| 65 private: | 77 private: |
| 66 GURL latest_report_uri_; | 78 GURL latest_report_uri_; |
| 67 std::string latest_report_; | 79 std::string latest_report_; |
| 80 int number_of_reports_; | |
| 68 | 81 |
| 69 DISALLOW_COPY_AND_ASSIGN(MockReportSender); | 82 DISALLOW_COPY_AND_ASSIGN(MockReportSender); |
| 70 }; | 83 }; |
| 71 | 84 |
| 72 } // namespace | 85 } // namespace |
| 73 | 86 |
| 74 class PermissionReporterTest : public ::testing::Test { | 87 class PermissionReporterTest : public ::testing::Test { |
| 75 protected: | 88 protected: |
| 76 PermissionReporterTest() | 89 void SetUp() override { |
| 77 : mock_report_sender_(new MockReportSender()), | 90 mock_report_sender_ = new MockReportSender; |
| 78 permission_reporter_( | 91 clock_ = new base::SimpleTestClock; |
| 79 new PermissionReporter(base::WrapUnique(mock_report_sender_))) {} | 92 permission_reporter_.reset(new PermissionReporter( |
| 93 base::WrapUnique(mock_report_sender_), base::WrapUnique(clock_))); | |
| 94 } | |
| 80 | 95 |
| 81 // Owned by |permission_reporter_|. | 96 // Owned by |permission_reporter_|. |
| 82 MockReportSender* mock_report_sender_; | 97 MockReportSender* mock_report_sender_; |
| 83 | 98 |
| 99 // Owned by |permission_reporter_|. | |
| 100 base::SimpleTestClock* clock_; | |
| 101 | |
| 84 std::unique_ptr<PermissionReporter> permission_reporter_; | 102 std::unique_ptr<PermissionReporter> permission_reporter_; |
| 85 }; | 103 }; |
| 86 | 104 |
| 87 // Test that PermissionReporter::SendReport sends a serialized report string to | 105 // Test that PermissionReporter::SendReport sends a serialized report string to |
| 88 // SafeBrowsing CSD servers. | 106 // SafeBrowsing CSD servers. |
| 89 TEST_F(PermissionReporterTest, SendReport) { | 107 TEST_F(PermissionReporterTest, SendReport) { |
| 90 permission_reporter_->SendReport(GURL(kDummyOrigin), kDummyPermission, | 108 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, |
| 91 kDummyAction); | 109 kDummyAction); |
| 92 | 110 |
| 93 PermissionReport permission_report; | 111 PermissionReport permission_report; |
| 94 ASSERT_TRUE( | 112 ASSERT_TRUE( |
| 95 permission_report.ParseFromString(mock_report_sender_->latest_report())); | 113 permission_report.ParseFromString(mock_report_sender_->latest_report())); |
| 96 EXPECT_EQ(kDummyPermissionReportPermission, permission_report.permission()); | 114 EXPECT_EQ(PermissionReport::GEOLOCATION, permission_report.permission()); |
| 97 EXPECT_EQ(kDummyPermissionReportAction, permission_report.action()); | 115 EXPECT_EQ(PermissionReport::GRANTED, permission_report.action()); |
| 98 EXPECT_EQ(kDummyOrigin, permission_report.origin()); | 116 EXPECT_EQ(kDummyOriginOne, permission_report.origin()); |
| 99 #if defined(OS_ANDROID) | 117 #if defined(OS_ANDROID) |
| 100 EXPECT_EQ(PermissionReport::ANDROID_PLATFORM, | 118 EXPECT_EQ(PermissionReport::ANDROID_PLATFORM, |
| 101 permission_report.platform_type()); | 119 permission_report.platform_type()); |
| 102 #elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \ | 120 #elif defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_CHROMEOS) || \ |
| 103 defined(OS_LINUX) | 121 defined(OS_LINUX) |
| 104 EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM, | 122 EXPECT_EQ(PermissionReport::DESKTOP_PLATFORM, |
| 105 permission_report.platform_type()); | 123 permission_report.platform_type()); |
| 106 #endif | 124 #endif |
| 107 | 125 |
| 108 EXPECT_EQ(GURL(kPermissionActionReportingUploadUrl), | 126 EXPECT_EQ(GURL(kPermissionActionReportingUploadUrl), |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 133 base::FeatureList::ClearInstanceForTesting(); | 151 base::FeatureList::ClearInstanceForTesting(); |
| 134 base::FeatureList::SetInstance(std::move(feature_list)); | 152 base::FeatureList::SetInstance(std::move(feature_list)); |
| 135 | 153 |
| 136 // This is necessary to activate both field trials. | 154 // This is necessary to activate both field trials. |
| 137 base::FeatureList::IsEnabled(kFeatureOnByDefault); | 155 base::FeatureList::IsEnabled(kFeatureOnByDefault); |
| 138 base::FeatureList::IsEnabled(kFeatureOffByDefault); | 156 base::FeatureList::IsEnabled(kFeatureOffByDefault); |
| 139 | 157 |
| 140 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_one->trial_name())); | 158 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_one->trial_name())); |
| 141 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_two->trial_name())); | 159 EXPECT_TRUE(base::FieldTrialList::IsTrialActive(trial_two->trial_name())); |
| 142 | 160 |
| 143 permission_reporter_->SendReport(GURL(kDummyOrigin), kDummyPermission, | 161 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, |
| 144 kDummyAction); | 162 kDummyAction); |
| 145 | 163 |
| 146 PermissionReport permission_report; | 164 PermissionReport permission_report; |
| 147 ASSERT_TRUE( | 165 ASSERT_TRUE( |
| 148 permission_report.ParseFromString(mock_report_sender_->latest_report())); | 166 permission_report.ParseFromString(mock_report_sender_->latest_report())); |
| 149 | 167 |
| 150 variations::ActiveGroupId field_trial_one = | 168 variations::ActiveGroupId field_trial_one = |
| 151 variations::MakeActiveGroupId(kDummyTrialOne, kDummyGroupOne); | 169 variations::MakeActiveGroupId(kDummyTrialOne, kDummyGroupOne); |
| 152 variations::ActiveGroupId field_trial_two = | 170 variations::ActiveGroupId field_trial_two = |
| 153 variations::MakeActiveGroupId(kDummyTrialTwo, kDummyGroupTwo); | 171 variations::MakeActiveGroupId(kDummyTrialTwo, kDummyGroupTwo); |
| 154 ActiveGroupIdSet expected_group_ids = {field_trial_one, field_trial_two}; | 172 ActiveGroupIdSet expected_group_ids = {field_trial_one, field_trial_two}; |
| 155 | 173 |
| 156 EXPECT_EQ(2, permission_report.field_trials().size()); | 174 EXPECT_EQ(2, permission_report.field_trials().size()); |
| 157 for (auto field_trial : permission_report.field_trials()) { | 175 for (auto field_trial : permission_report.field_trials()) { |
| 158 variations::ActiveGroupId group_id = {field_trial.name_id(), | 176 variations::ActiveGroupId group_id = {field_trial.name_id(), |
| 159 field_trial.group_id()}; | 177 field_trial.group_id()}; |
| 160 EXPECT_EQ(1U, expected_group_ids.erase(group_id)); | 178 EXPECT_EQ(1U, expected_group_ids.erase(group_id)); |
| 161 } | 179 } |
| 162 EXPECT_EQ(0U, expected_group_ids.size()); | 180 EXPECT_EQ(0U, expected_group_ids.size()); |
| 163 } | 181 } |
| 164 | 182 |
| 183 // Test that PermissionReporter::IsAllowedToSend returns true only when the | |
| 184 // number of reports sent in the last one minute per origin per permission is | |
| 185 // under a threshold. | |
| 186 TEST_F(PermissionReporterTest, IsAllowedToSend) { | |
| 187 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberReports()); | |
| 188 | |
| 189 int reports_to_send = kMaximumReportsPerOriginPerPermissionPerMinute; | |
| 190 while (reports_to_send--) | |
| 191 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
| 192 kDummyAction); | |
| 193 EXPECT_EQ(5, mock_report_sender_->GetAndResetNumberReports()); | |
| 194 | |
| 195 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
| 196 kDummyAction); | |
| 197 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberReports()); | |
| 198 | |
| 199 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionTwo, | |
| 200 kDummyAction); | |
| 201 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberReports()); | |
| 202 | |
| 203 permission_reporter_->SendReport(GURL(kDummyOriginTwo), kDummyPermissionOne, | |
| 204 kDummyAction); | |
| 205 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberReports()); | |
| 206 | |
| 207 clock_->Advance(base::TimeDelta::FromMinutes(1)); | |
| 208 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
| 209 kDummyAction); | |
| 210 EXPECT_EQ(0, mock_report_sender_->GetAndResetNumberReports()); | |
| 211 | |
| 212 clock_->Advance(base::TimeDelta::FromMicroseconds(1)); | |
| 213 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
| 214 kDummyAction); | |
| 215 EXPECT_EQ(1, mock_report_sender_->GetAndResetNumberReports()); | |
| 216 | |
| 217 clock_->Advance(base::TimeDelta::FromMinutes(1)); | |
| 218 reports_to_send = 12; | |
| 219 while (reports_to_send--) { | |
| 220 clock_->Advance(base::TimeDelta::FromSeconds(5)); | |
| 221 permission_reporter_->SendReport(GURL(kDummyOriginOne), kDummyPermissionOne, | |
| 222 kDummyAction); | |
| 223 } | |
| 224 EXPECT_EQ(kMaximumReportsPerOriginPerPermissionPerMinute, | |
| 225 mock_report_sender_->GetAndResetNumberReports()); | |
| 226 } | |
| 227 | |
| 165 } // namespace safe_browsing | 228 } // namespace safe_browsing |
| OLD | NEW |