Commit cb08fe42 authored by Dominique Fauteux-Chapleau's avatar Dominique Fauteux-Chapleau Committed by Commit Bot

Hook OnFileAttached to ConnectorsManager

This makes OnFileAttached an alternative to legacy policies to
configure scanning settings. This is gated by a new feature.

Bug: 1067631
Change-Id: Ib97200da493176a7a4254d2f891c1625c85d42cd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2162268Reviewed-by: default avatarDominique Fauteux-Chapleau <domfc@chromium.org>
Reviewed-by: default avatarRoger Tawa <rogerta@chromium.org>
Commit-Queue: Dominique Fauteux-Chapleau <domfc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#762071}
parent 5e409647
......@@ -39,6 +39,7 @@ AnalysisServiceSettings::AnalysisServiceSettings(
// Add the patterns to the settings, which configures settings.matcher and
// settings.*_pattern_settings. No enable patterns implies the settings are
// invalid.
matcher_ = std::make_unique<url_matcher::URLMatcher>();
url_matcher::URLMatcherConditionSet::ID id(0);
const base::Value* enable = settings_value.FindListKey(kKeyEnable);
if (enable && enable->is_list()) {
......@@ -94,7 +95,8 @@ base::Optional<AnalysisSettings> AnalysisServiceSettings::GetAnalysisSettings(
if (!IsValid())
return base::nullopt;
auto matches = matcher_.MatchURL(url);
DCHECK(matcher_);
auto matches = matcher_->MatchURL(url);
if (matches.empty())
return base::nullopt;
......@@ -141,7 +143,7 @@ void AnalysisServiceSettings::AddUrlPatternSettings(
const base::ListValue* url_list_value = nullptr;
url_list->GetAsList(&url_list_value);
DCHECK(url_list_value);
policy::url_util::AddFilters(&matcher_, enabled, id, url_list_value);
policy::url_util::AddFilters(matcher_.get(), enabled, id, url_list_value);
} else {
return;
}
......@@ -195,6 +197,8 @@ bool AnalysisServiceSettings::IsValid() const {
return true;
}
AnalysisServiceSettings::AnalysisServiceSettings(AnalysisServiceSettings&&) =
default;
AnalysisServiceSettings::~AnalysisServiceSettings() = default;
AnalysisServiceSettings::URLPatternSettings::URLPatternSettings() = default;
......
......@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_SERVICE_SETTINGS_H_
#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_SERVICE_SETTINGS_H_
#include <memory>
#include "base/values.h"
#include "chrome/browser/enterprise/connectors/common.h"
#include "components/url_matcher/url_matcher.h"
......@@ -15,6 +17,7 @@ namespace enterprise_connectors {
class AnalysisServiceSettings {
public:
explicit AnalysisServiceSettings(const base::Value& settings_value);
AnalysisServiceSettings(AnalysisServiceSettings&&);
~AnalysisServiceSettings();
// Get the settings to apply to a specific analysis. base::nullopt implies no
......@@ -63,7 +66,7 @@ class AnalysisServiceSettings {
// condition set IDs returned after matching against a URL can be used to
// check |enabled_patterns_settings| and |disable_patterns_settings| to
// obtain URL-specific settings.
url_matcher::URLMatcher matcher_;
std::unique_ptr<url_matcher::URLMatcher> matcher_;
// These members map URL patterns to corresponding settings. If an entry in
// the "enabled" or "disabled" lists contains more than one pattern in its
......
......@@ -10,6 +10,7 @@
#include "base/memory/singleton.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/enterprise/connectors/connectors_prefs.h"
#include "components/policy/core/browser/url_util.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
......@@ -18,6 +19,9 @@
namespace enterprise_connectors {
const base::Feature kEnterpriseConnectorsEnabled{
"EnterpriseConnectorsEnabled", base::FEATURE_DISABLED_BY_DEFAULT};
namespace {
base::ListValue AllPatterns() {
......@@ -49,6 +53,18 @@ bool MatchURLAgainstPatterns(const GURL& url,
return has_scan_match;
}
const char* ConnectorToPref(AnalysisConnector connector) {
switch (connector) {
case AnalysisConnector::BULK_DATA_ENTRY:
case AnalysisConnector::FILE_DOWNLOADED:
// TODO(crbug/1067631): Return the corresponding prefs for these analysis
// connectors once they exist.
return nullptr;
case AnalysisConnector::FILE_ATTACHED:
return kOnFileAttachedPref;
}
}
} // namespace
// ConnectorsManager implementation---------------------------------------------
......@@ -61,11 +77,59 @@ ConnectorsManager* ConnectorsManager::GetInstance() {
return base::Singleton<ConnectorsManager>::get();
}
bool ConnectorsManager::IsConnectorEnabled(AnalysisConnector connector) {
if (!base::FeatureList::IsEnabled(kEnterpriseConnectorsEnabled))
return false;
if (connector_settings_.count(connector) == 1)
return true;
const char* pref = ConnectorToPref(connector);
return pref && g_browser_process->local_state()->HasPrefPath(pref);
}
void ConnectorsManager::GetAnalysisSettings(const GURL& url,
AnalysisConnector connector,
AnalysisSettingsCallback callback) {
if (IsConnectorEnabled(connector)) {
GetAnalysisSettingsFromConnectorPolicy(url, connector, std::move(callback));
} else {
std::move(callback).Run(
GetAnalysisSettingsFromLegacyPolicies(url, connector));
}
}
void ConnectorsManager::GetAnalysisSettingsFromConnectorPolicy(
const GURL& url,
AnalysisConnector connector,
AnalysisSettingsCallback callback) {
if (connector_settings_.count(connector) == 0)
CacheConnectorPolicy(connector);
// If the connector is still not in memory, it means the pref is set to an
// empty list or that it is not a list.
if (connector_settings_.count(connector) == 0) {
std::move(callback).Run(base::nullopt);
return;
}
// While multiple services can be set by the connector policies, only the
// first one is considered for now.
std::move(callback).Run(
GetAnalysisSettingsFromLegacyPolicies(url, connector));
connector_settings_[connector][0].GetAnalysisSettings(url));
}
void ConnectorsManager::CacheConnectorPolicy(AnalysisConnector connector) {
// Connectors with non-existing policies should not reach this code.
const char* pref = ConnectorToPref(connector);
DCHECK(pref);
const base::ListValue* policy_value =
g_browser_process->local_state()->GetList(pref);
if (policy_value && policy_value->is_list()) {
for (const base::Value& service_settings : policy_value->GetList())
connector_settings_[connector].emplace_back(service_settings);
}
}
bool ConnectorsManager::DelayUntilVerdict(AnalysisConnector connector) const {
......@@ -201,4 +265,13 @@ std::set<std::string> ConnectorsManager::MatchURLAgainstLegacyPolicies(
return tags;
}
void ConnectorsManager::Reset() {
connector_settings_.clear();
}
const ConnectorsManager::AnalysisConnectorsSettings&
ConnectorsManager::GetAnalysisConnectorsSettingsForTesting() const {
return connector_settings_;
}
} // namespace enterprise_connectors
......@@ -8,7 +8,9 @@
#include <set>
#include "base/callback_forward.h"
#include "base/feature_list.h"
#include "base/optional.h"
#include "chrome/browser/enterprise/connectors/analysis_service_settings.h"
#include "chrome/browser/enterprise/connectors/common.h"
#include "url/gurl.h"
......@@ -19,6 +21,11 @@ struct DefaultSingletonTraits;
namespace enterprise_connectors {
// Controls whether the Enterprise Connectors policies should be read by
// ConnectorsManager. Legacy policies will be read as a fallback if this feature
// is disabled.
extern const base::Feature kEnterpriseConnectorsEnabled;
// Manages access to Connector policies. This class is responsible for caching
// the Connector policies, validate them against approved service providers and
// provide a simple interface to them.
......@@ -29,16 +36,24 @@ class ConnectorsManager {
using AnalysisSettingsCallback =
base::OnceCallback<void(base::Optional<AnalysisSettings>)>;
// Map used to cache analysis connectors settings.
using AnalysisConnectorsSettings =
std::map<AnalysisConnector, std::vector<AnalysisServiceSettings>>;
static ConnectorsManager* GetInstance();
// Validates which settings should be applied to an analysis connector event
// against cached policies.
// against cached policies. This function will prioritize new connector
// policies over legacy ones if they are set.
void GetAnalysisSettings(const GURL& url,
AnalysisConnector connector,
AnalysisSettingsCallback callback);
bool DelayUntilVerdict(AnalysisConnector connector) const;
// Clears any cached values.
void Reset();
// Public legacy functions.
// These functions are used to interact with legacy policies and should only
// be called while the connectors equivalent isn't available. They should be
......@@ -48,6 +63,10 @@ class ConnectorsManager {
bool MatchURLAgainstLegacyDlpPolicies(const GURL& url, bool upload) const;
bool MatchURLAgainstLegacyMalwarePolicies(const GURL& url, bool upload) const;
// Public testing functions.
const AnalysisConnectorsSettings& GetAnalysisConnectorsSettingsForTesting()
const;
private:
friend struct base::DefaultSingletonTraits<ConnectorsManager>;
......@@ -56,6 +75,21 @@ class ConnectorsManager {
ConnectorsManager();
~ConnectorsManager();
// Checks if the corresponding connector is enabled and to be used with the
// given URL.
bool IsConnectorEnabled(AnalysisConnector connector);
// Validates which settings should be applied to an analysis connector event
// against connector policies. Cache the policy value the first time this is
// called for every different connector.
void GetAnalysisSettingsFromConnectorPolicy(
const GURL& url,
AnalysisConnector connector,
AnalysisSettingsCallback callback);
// Read and cache the policy corresponding to |connector|.
void CacheConnectorPolicy(AnalysisConnector connector);
// Private legacy functions.
// These functions are used to interact with legacy policies and should stay
// private. They should be removed once legacy policies are deprecated.
......@@ -72,6 +106,10 @@ class ConnectorsManager {
std::set<std::string> MatchURLAgainstLegacyPolicies(const GURL& url,
bool upload) const;
// Cached values of the connector policies. Updated when a connector is first
// used or when a policy is updated.
AnalysisConnectorsSettings connector_settings_;
};
} // namespace enterprise_connectors
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment