// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "android_webview/browser/enterprise_authentication_app_link_policy_handler.h"
#include <memory>
#include "base/strings/string_util.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/policy/policy_constants.h"
#include "components/strings/grit/components_strings.h"
#include "url/gurl.h"
namespace policy {
EnterpriseAuthenticationAppLinkPolicyHandler::
EnterpriseAuthenticationAppLinkPolicyHandler(const char* policy_name,
const char* pref_path)
: TypeCheckingPolicyHandler(policy_name, base::Value::Type::LIST),
pref_path_(pref_path) {}
EnterpriseAuthenticationAppLinkPolicyHandler::
~EnterpriseAuthenticationAppLinkPolicyHandler() = default;
bool EnterpriseAuthenticationAppLinkPolicyHandler::CheckPolicySettings(
const PolicyMap& policies,
PolicyErrorMap* errors) {
if (!TypeCheckingPolicyHandler::CheckPolicySettings(policies, errors))
return false;
const base::Value* value =
policies.GetValue(policy_name(), base::Value::Type::LIST);
if (!value) {
return true;
}
const base::Value::List& policy_list = value->GetList();
if (policy_list.empty()) {
return true;
}
// Filters more than |url_util::kMaxFiltersPerPolicy| are ignored, add a
// warning message.
if (policy_list.size() > policy::kMaxUrlFiltersPerPolicy) {
errors->AddError(policy_name(),
IDS_POLICY_URL_ALLOW_BLOCK_LIST_MAX_FILTERS_LIMIT_WARNING,
base::NumberToString(policy::kMaxUrlFiltersPerPolicy));
}
std::vector<std::string> invalid_policies;
for (const auto& entry : policy_list) {
const std::string* url = entry.GetDict().FindString("url");
if (!url) {
invalid_policies.push_back(
"Invalid policy: Required key 'url' does not exists");
} else if (!ValidatePolicyEntry(url)) {
invalid_policies.push_back("Invalid url: " + *url);
}
}
if (!invalid_policies.empty()) {
errors->AddError(policy_name(), IDS_POLICY_PROTO_PARSING_ERROR,
base::JoinString(invalid_policies, ","));
}
return invalid_policies.size() < policy_list.size();
}
void EnterpriseAuthenticationAppLinkPolicyHandler::ApplyPolicySettings(
const PolicyMap& policies,
PrefValueMap* prefs) {
const base::Value* value =
policies.GetValue(policy_name(), base::Value::Type::LIST);
if (!value)
return;
base::Value::List filtered_values;
for (const auto& entry : value->GetList()) {
const std::string* url = entry.GetDict().FindString("url");
if (ValidatePolicyEntry(url))
filtered_values.Append(*url);
}
if (filtered_values.size() > policy::kMaxUrlFiltersPerPolicy) {
filtered_values.erase(
filtered_values.begin() + policy::kMaxUrlFiltersPerPolicy,
filtered_values.end());
}
prefs->SetValue(pref_path_, base::Value(std::move(filtered_values)));
}
// Validates that policy follows official pattern
// https://www.chromium.org/administrators/url-blocklist-filter-format
bool EnterpriseAuthenticationAppLinkPolicyHandler::ValidatePolicyEntry(
const std::string* policy) {
url_matcher::util::FilterComponents components;
return policy && url_matcher::util::FilterToComponents(
*policy, &components.scheme, &components.host,
&components.match_subdomains, &components.port,
&components.path, &components.query);
}
} // namespace policy