Roll src/third_party/WebKit 6b63e20:35e1984 (svn 201060:201061)
[chromium-blink-merge.git] / components / policy / core / browser / browser_policy_connector.cc
blob8abddc524aef34358e453c073adf59c4a4737f20
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/policy/core/browser/browser_policy_connector.h"
7 #include <algorithm>
8 #include <vector>
10 #include "base/command_line.h"
11 #include "base/logging.h"
12 #include "base/metrics/histogram_macros.h"
13 #include "base/metrics/sparse_histogram.h"
14 #include "base/prefs/pref_registry_simple.h"
15 #include "base/strings/string16.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
18 #include "components/policy/core/common/cloud/device_management_service.h"
19 #include "components/policy/core/common/configuration_policy_provider.h"
20 #include "components/policy/core/common/policy_namespace.h"
21 #include "components/policy/core/common/policy_pref_names.h"
22 #include "components/policy/core/common/policy_statistics_collector.h"
23 #include "components/policy/core/common/policy_switches.h"
24 #include "google_apis/gaia/gaia_auth_util.h"
25 #include "policy/policy_constants.h"
26 #include "third_party/icu/source/i18n/unicode/regex.h"
28 namespace policy {
30 namespace {
32 // The URL for the device management server.
33 const char kDefaultDeviceManagementServerUrl[] =
34 "https://m.google.com/devicemanagement/data/api";
37 void ReportRegexSuccessMetric(bool success) {
38 UMA_HISTOGRAM_BOOLEAN("Enterprise.DomainWhitelistRegexSuccess", success);
41 // Regexes that match many of the larger public email providers as we know
42 // these users are not from hosted enterprise domains. Keep this list in sync
43 // with the EnterpriseDomainRegex enum in histograms.xml (i.e. only add things
44 // at the end).
45 const wchar_t* const kNonManagedDomainPatterns[] = {
46 L"aol\\.com",
47 L"googlemail\\.com",
48 L"gmail\\.com",
49 L"hotmail(\\.co|\\.com|)\\.[^.]+", // hotmail.com, hotmail.it, hotmail.co.uk
50 L"live\\.com",
51 L"mail\\.ru",
52 L"msn\\.com",
53 L"qq\\.com",
54 L"yahoo(\\.co|\\.com|)\\.[^.]+", // yahoo.com, yahoo.co.uk, yahoo.com.tw
55 L"yandex\\.ru",
58 // Returns true if |domain| matches the regex |pattern|.
59 bool MatchDomain(const base::string16& domain, const base::string16& pattern,
60 size_t index) {
61 UErrorCode status = U_ZERO_ERROR;
62 const icu::UnicodeString icu_pattern(pattern.data(), pattern.length());
63 icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status);
64 if (!U_SUCCESS(status)) {
65 // http://crbug.com/365351 - if for some reason the matcher creation fails
66 // just return that the pattern doesn't match the domain. This is safe
67 // because the calling method (IsNonEnterpriseUser()) is just used to enable
68 // an optimization for non-enterprise users - better to skip the
69 // optimization than crash.
70 DLOG(ERROR) << "Possible invalid domain pattern: " << pattern
71 << " - Error: " << status;
72 ReportRegexSuccessMetric(false);
73 UMA_HISTOGRAM_ENUMERATION("Enterprise.DomainWhitelistRegexFailure",
74 index, arraysize(kNonManagedDomainPatterns));
75 UMA_HISTOGRAM_SPARSE_SLOWLY("Enterprise.DomainWhitelistRegexFailureStatus",
76 status);
77 return false;
79 ReportRegexSuccessMetric(true);
80 icu::UnicodeString icu_input(domain.data(), domain.length());
81 matcher.reset(icu_input);
82 status = U_ZERO_ERROR;
83 UBool match = matcher.matches(status);
84 DCHECK(U_SUCCESS(status));
85 return !!match; // !! == convert from UBool to bool.
88 } // namespace
90 BrowserPolicyConnector::BrowserPolicyConnector(
91 const HandlerListFactory& handler_list_factory)
92 : BrowserPolicyConnectorBase(handler_list_factory) {
95 BrowserPolicyConnector::~BrowserPolicyConnector() {
98 void BrowserPolicyConnector::InitInternal(
99 PrefService* local_state,
100 scoped_ptr<DeviceManagementService> device_management_service) {
101 DCHECK(!is_initialized());
103 device_management_service_ = device_management_service.Pass();
105 policy_statistics_collector_.reset(new policy::PolicyStatisticsCollector(
106 base::Bind(&GetChromePolicyDetails), GetChromeSchema(),
107 GetPolicyService(), local_state,
108 base::MessageLoop::current()->task_runner()));
109 policy_statistics_collector_->Initialize();
111 InitPolicyProviders();
114 void BrowserPolicyConnector::Shutdown() {
115 BrowserPolicyConnectorBase::Shutdown();
116 device_management_service_.reset();
119 void BrowserPolicyConnector::ScheduleServiceInitialization(
120 int64 delay_milliseconds) {
121 // Skip device initialization if the BrowserPolicyConnector was never
122 // initialized (unit tests).
123 if (device_management_service_)
124 device_management_service_->ScheduleInitialization(delay_milliseconds);
127 // static
128 bool BrowserPolicyConnector::IsNonEnterpriseUser(const std::string& username) {
129 if (username.empty() || username.find('@') == std::string::npos) {
130 // An empty username means incognito user in case of ChromiumOS and
131 // no logged-in user in case of Chromium (SigninService). Many tests use
132 // nonsense email addresses (e.g. 'test') so treat those as non-enterprise
133 // users.
134 return true;
136 const base::string16 domain = base::UTF8ToUTF16(
137 gaia::ExtractDomainName(gaia::CanonicalizeEmail(username)));
138 for (size_t i = 0; i < arraysize(kNonManagedDomainPatterns); i++) {
139 base::string16 pattern = base::WideToUTF16(kNonManagedDomainPatterns[i]);
140 if (MatchDomain(domain, pattern, i))
141 return true;
143 return false;
146 // static
147 std::string BrowserPolicyConnector::GetDeviceManagementUrl() {
148 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
149 if (command_line->HasSwitch(switches::kDeviceManagementUrl))
150 return command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl);
151 else
152 return kDefaultDeviceManagementServerUrl;
155 // static
156 void BrowserPolicyConnector::RegisterPrefs(PrefRegistrySimple* registry) {
157 registry->RegisterIntegerPref(
158 policy_prefs::kUserPolicyRefreshRate,
159 CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs);
163 } // namespace policy