summaryrefslogtreecommitdiff
path: root/chromium/components/blacklist/opt_out_blacklist/opt_out_blacklist_data.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/blacklist/opt_out_blacklist/opt_out_blacklist_data.cc')
-rw-r--r--chromium/components/blacklist/opt_out_blacklist/opt_out_blacklist_data.cc176
1 files changed, 176 insertions, 0 deletions
diff --git a/chromium/components/blacklist/opt_out_blacklist/opt_out_blacklist_data.cc b/chromium/components/blacklist/opt_out_blacklist/opt_out_blacklist_data.cc
new file mode 100644
index 00000000000..8b519016629
--- /dev/null
+++ b/chromium/components/blacklist/opt_out_blacklist/opt_out_blacklist_data.cc
@@ -0,0 +1,176 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/blacklist/opt_out_blacklist/opt_out_blacklist_data.h"
+
+#include "base/memory/ptr_util.h"
+
+namespace blacklist {
+
+BlacklistData::BlacklistData(std::unique_ptr<Policy> session_policy,
+ std::unique_ptr<Policy> persistent_policy,
+ std::unique_ptr<Policy> host_policy,
+ std::unique_ptr<Policy> type_policy,
+ size_t max_hosts,
+ AllowedTypesAndVersions allowed_types)
+ : session_policy_(std::move(session_policy)),
+ persistent_policy_(std::move(persistent_policy)),
+ host_policy_(std::move(host_policy)),
+ max_hosts_(max_hosts),
+ type_policy_(std::move(type_policy)),
+ allowed_types_(std::move(allowed_types)) {
+ DCHECK_GE(100u, max_hosts);
+}
+BlacklistData::~BlacklistData() {}
+
+void BlacklistData::ClearData() {
+ session_black_list_item_.reset();
+ persistent_black_list_item_.reset();
+ black_list_item_host_map_.clear();
+ black_list_item_type_map_.clear();
+}
+
+void BlacklistData::AddEntry(const std::string& host_name,
+ bool opt_out,
+ int type,
+ base::Time time,
+ bool is_from_persistent_storage) {
+ // Add to the session based rule if it is enabled.
+ if (session_policy_ && !is_from_persistent_storage) {
+ if (!session_black_list_item_) {
+ session_black_list_item_ = std::make_unique<OptOutBlacklistItem>(
+ session_policy_->history, session_policy_->threshold,
+ session_policy_->duration);
+ }
+ session_black_list_item_->AddEntry(opt_out, time);
+ }
+
+ // Add to the persistent rule if it is enabled.
+ if (persistent_policy_) {
+ if (!persistent_black_list_item_) {
+ persistent_black_list_item_ = std::make_unique<OptOutBlacklistItem>(
+ persistent_policy_->history, persistent_policy_->threshold,
+ persistent_policy_->duration);
+ }
+ persistent_black_list_item_->AddEntry(opt_out, time);
+ }
+
+ // Add to the host rule if it is enabled. Remove hosts if there are more than
+ // |max_hosts_| in the map.
+ if (host_policy_) {
+ auto item = black_list_item_host_map_.find(host_name);
+ if (item == black_list_item_host_map_.end()) {
+ auto value = black_list_item_host_map_.emplace(
+ std::piecewise_construct, std::forward_as_tuple(host_name),
+ std::forward_as_tuple(host_policy_->history, host_policy_->threshold,
+ host_policy_->duration));
+ DCHECK(value.second);
+ item = value.first;
+ }
+ item->second.AddEntry(opt_out, time);
+ if (max_hosts_ > 0 && black_list_item_host_map_.size() > max_hosts_)
+ EvictOldestHost();
+ }
+
+ // Only allowed types should be recorded.
+ DCHECK(allowed_types_.find(type) != allowed_types_.end());
+
+ if (type_policy_) {
+ auto item = black_list_item_type_map_.find(type);
+ if (item == black_list_item_type_map_.end()) {
+ auto value = black_list_item_type_map_.emplace(
+ std::piecewise_construct, std::forward_as_tuple(type),
+ std::forward_as_tuple(type_policy_->history, type_policy_->threshold,
+ type_policy_->duration));
+ DCHECK(value.second);
+ item = value.first;
+ }
+ item->second.AddEntry(opt_out, time);
+ }
+}
+
+BlacklistReason BlacklistData::IsAllowed(
+ const std::string& host_name,
+ int type,
+ bool ignore_long_term_black_list_rules,
+ base::Time time,
+ std::vector<BlacklistReason>* passed_reasons) const {
+ // Check the session rule.
+ if (session_policy_) {
+ if (session_black_list_item_ &&
+ session_black_list_item_->IsBlackListed(time)) {
+ return BlacklistReason::kUserOptedOutInSession;
+ }
+ passed_reasons->push_back(BlacklistReason::kUserOptedOutInSession);
+ }
+
+ // Check whether the persistent rules should be checked this time.
+ if (ignore_long_term_black_list_rules)
+ return BlacklistReason::kAllowed;
+
+ // Check the persistent rule.
+ if (persistent_policy_) {
+ if (IsUserOptedOutInGeneral(time)) {
+ return BlacklistReason::kUserOptedOutInGeneral;
+ }
+ passed_reasons->push_back(BlacklistReason::kUserOptedOutInGeneral);
+ }
+
+ // Check the host rule.
+ if (host_policy_) {
+ if (IsHostBlacklisted(host_name, time))
+ return BlacklistReason::kUserOptedOutOfHost;
+ passed_reasons->push_back(BlacklistReason::kUserOptedOutOfHost);
+ }
+
+ // Only allowed types should be recorded.
+ DCHECK(allowed_types_.find(type) != allowed_types_.end());
+
+ // Check the type rule.
+ if (type_policy_) {
+ auto item = black_list_item_type_map_.find(type);
+ if (item != black_list_item_type_map_.end() &&
+ item->second.IsBlackListed(time)) {
+ return BlacklistReason::kUserOptedOutOfType;
+ }
+ passed_reasons->push_back(BlacklistReason::kUserOptedOutOfType);
+ }
+
+ return BlacklistReason::kAllowed;
+}
+
+void BlacklistData::EvictOldestHost() {
+ DCHECK_LT(max_hosts_, black_list_item_host_map_.size());
+ base::Optional<base::Time> oldest_opt_out;
+ std::string key_to_delete;
+ for (auto& item : black_list_item_host_map_) {
+ base::Optional<base::Time> most_recent_opt_out =
+ item.second.most_recent_opt_out_time();
+ if (!most_recent_opt_out) {
+ // If there is no opt out time, this is a good choice to evict.
+ key_to_delete = item.first;
+ break;
+ }
+ if (!oldest_opt_out ||
+ most_recent_opt_out.value() < oldest_opt_out.value()) {
+ oldest_opt_out = most_recent_opt_out.value();
+ key_to_delete = item.first;
+ }
+ }
+ black_list_item_host_map_.erase(key_to_delete);
+}
+
+bool BlacklistData::IsHostBlacklisted(const std::string& host_name,
+ base::Time time) const {
+ auto item = black_list_item_host_map_.find(host_name);
+ return item != black_list_item_host_map_.end() &&
+ item->second.IsBlackListed(time);
+}
+
+bool BlacklistData::IsUserOptedOutInGeneral(base::Time time) const {
+ return persistent_black_list_item_ &&
+ persistent_black_list_item_->IsBlackListed(time);
+}
+
+} // namespace blacklist