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"
10 #include "base/command_line.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/message_loop/message_loop_proxy.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_service_impl.h"
23 #include "components/policy/core/common/policy_statistics_collector.h"
24 #include "components/policy/core/common/policy_switches.h"
25 #include "google_apis/gaia/gaia_auth_util.h"
26 #include "net/url_request/url_request_context_getter.h"
27 #include "policy/policy_constants.h"
28 #include "third_party/icu/source/i18n/unicode/regex.h"
34 // The URL for the device management server.
35 const char kDefaultDeviceManagementServerUrl[] =
36 "https://m.google.com/devicemanagement/data/api";
38 // Used in BrowserPolicyConnector::SetPolicyProviderForTesting.
39 bool g_created_policy_service = false;
40 ConfigurationPolicyProvider* g_testing_provider = NULL;
42 // Returns true if |domain| matches the regex |pattern|.
43 bool MatchDomain(const base::string16& domain, const base::string16& pattern) {
44 UErrorCode status = U_ZERO_ERROR;
45 const icu::UnicodeString icu_pattern(pattern.data(), pattern.length());
46 icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status);
47 DCHECK(U_SUCCESS(status)) << "Invalid domain pattern: " << pattern;
48 icu::UnicodeString icu_input(domain.data(), domain.length());
49 matcher.reset(icu_input);
50 status = U_ZERO_ERROR;
51 UBool match = matcher.matches(status);
52 DCHECK(U_SUCCESS(status));
53 return !!match; // !! == convert from UBool to bool.
58 BrowserPolicyConnector::BrowserPolicyConnector(
59 const HandlerListFactory& handler_list_factory)
60 : is_initialized_(false),
61 platform_policy_provider_(NULL) {
62 // GetPolicyService() must be ready after the constructor is done.
63 // The connector is created very early during startup, when the browser
64 // threads aren't running yet; initialize components that need local_state,
65 // the system request context or other threads (e.g. FILE) at Init().
67 // Initialize the SchemaRegistry with the Chrome schema before creating any
68 // of the policy providers in subclasses.
69 chrome_schema_ = Schema::Wrap(GetChromeSchemaData());
70 handler_list_ = handler_list_factory.Run(chrome_schema_);
71 schema_registry_.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""),
75 BrowserPolicyConnector::~BrowserPolicyConnector() {
76 if (is_initialized()) {
77 // Shutdown() wasn't invoked by our owner after having called Init().
78 // This usually means it's an early shutdown and
79 // BrowserProcessImpl::StartTearDown() wasn't invoked.
80 // Cleanup properly in those cases and avoid crashing the ToastCrasher test.
85 void BrowserPolicyConnector::Init(
86 PrefService* local_state,
87 scoped_refptr<net::URLRequestContextGetter> request_context,
88 scoped_ptr<DeviceManagementService> device_management_service) {
89 DCHECK(!is_initialized());
91 device_management_service_ = device_management_service.Pass();
93 if (g_testing_provider)
94 g_testing_provider->Init(GetSchemaRegistry());
95 for (size_t i = 0; i < policy_providers_.size(); ++i)
96 policy_providers_[i]->Init(GetSchemaRegistry());
98 policy_statistics_collector_.reset(
99 new policy::PolicyStatisticsCollector(
100 base::Bind(&GetChromePolicyDetails),
104 base::MessageLoop::current()->message_loop_proxy()));
105 policy_statistics_collector_->Initialize();
107 is_initialized_ = true;
110 void BrowserPolicyConnector::Shutdown() {
111 is_initialized_ = false;
112 if (g_testing_provider)
113 g_testing_provider->Shutdown();
114 for (size_t i = 0; i < policy_providers_.size(); ++i)
115 policy_providers_[i]->Shutdown();
116 // Drop g_testing_provider so that tests executed with --single_process can
117 // call SetPolicyProviderForTesting() again. It is still owned by the test.
118 g_testing_provider = NULL;
119 device_management_service_.reset();
122 PolicyService* BrowserPolicyConnector::GetPolicyService() {
123 if (!policy_service_) {
124 g_created_policy_service = true;
125 std::vector<ConfigurationPolicyProvider*> providers;
126 if (g_testing_provider) {
127 providers.push_back(g_testing_provider);
129 providers.resize(policy_providers_.size());
130 std::copy(policy_providers_.begin(),
131 policy_providers_.end(),
134 policy_service_.reset(new PolicyServiceImpl(providers));
136 return policy_service_.get();
139 ConfigurationPolicyProvider* BrowserPolicyConnector::GetPlatformProvider() {
140 if (g_testing_provider)
141 return g_testing_provider;
142 return platform_policy_provider_;
145 const Schema& BrowserPolicyConnector::GetChromeSchema() const {
146 return chrome_schema_;
149 CombinedSchemaRegistry* BrowserPolicyConnector::GetSchemaRegistry() {
150 return &schema_registry_;
153 void BrowserPolicyConnector::ScheduleServiceInitialization(
154 int64 delay_milliseconds) {
155 // Skip device initialization if the BrowserPolicyConnector was never
156 // initialized (unit tests).
157 if (device_management_service_)
158 device_management_service_->ScheduleInitialization(delay_milliseconds);
161 const ConfigurationPolicyHandlerList*
162 BrowserPolicyConnector::GetHandlerList() const {
163 return handler_list_.get();
167 void BrowserPolicyConnector::SetPolicyProviderForTesting(
168 ConfigurationPolicyProvider* provider) {
169 // If this function is used by a test then it must be called before the
170 // browser is created, and GetPolicyService() gets called.
171 CHECK(!g_created_policy_service);
172 DCHECK(!g_testing_provider);
173 g_testing_provider = provider;
177 bool BrowserPolicyConnector::IsNonEnterpriseUser(const std::string& username) {
178 if (username.empty() || username.find('@') == std::string::npos) {
179 // An empty username means incognito user in case of ChromiumOS and
180 // no logged-in user in case of Chromium (SigninService). Many tests use
181 // nonsense email addresses (e.g. 'test') so treat those as non-enterprise
186 // Exclude many of the larger public email providers as we know these users
187 // are not from hosted enterprise domains.
188 static const wchar_t* kNonManagedDomainPatterns[] = {
192 L"hotmail(\\.co|\\.com|)\\.[^.]+", // hotmail.com, hotmail.it, hotmail.co.uk
197 L"yahoo(\\.co|\\.com|)\\.[^.]+", // yahoo.com, yahoo.co.uk, yahoo.com.tw
200 const base::string16 domain = base::UTF8ToUTF16(
201 gaia::ExtractDomainName(gaia::CanonicalizeEmail(username)));
202 for (size_t i = 0; i < arraysize(kNonManagedDomainPatterns); i++) {
203 base::string16 pattern = base::WideToUTF16(kNonManagedDomainPatterns[i]);
204 if (MatchDomain(domain, pattern))
211 std::string BrowserPolicyConnector::GetDeviceManagementUrl() {
212 CommandLine* command_line = CommandLine::ForCurrentProcess();
213 if (command_line->HasSwitch(switches::kDeviceManagementUrl))
214 return command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl);
216 return kDefaultDeviceManagementServerUrl;
220 void BrowserPolicyConnector::RegisterPrefs(PrefRegistrySimple* registry) {
221 registry->RegisterIntegerPref(
222 policy_prefs::kUserPolicyRefreshRate,
223 CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs);
226 void BrowserPolicyConnector::AddPolicyProvider(
227 scoped_ptr<ConfigurationPolicyProvider> provider) {
228 policy_providers_.push_back(provider.release());
231 void BrowserPolicyConnector::SetPlatformPolicyProvider(
232 scoped_ptr<ConfigurationPolicyProvider> provider) {
233 CHECK(!platform_policy_provider_);
234 platform_policy_provider_ = provider.get();
235 AddPolicyProvider(provider.Pass());
238 } // namespace policy