15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/browser/browser_policy_connector.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector>
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/command_line.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/metrics/histogram.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/metrics/sparse_histogram.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string16.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_refresh_scheduler.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/cloud/device_management_service.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/configuration_policy_provider.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/policy_namespace.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/policy_pref_names.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/policy_service_impl.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/policy_statistics_collector.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/policy/core/common/policy_switches.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "policy/policy_constants.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/icu/source/i18n/unicode/regex.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace policy {
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The URL for the device management server.
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kDefaultDeviceManagementServerUrl[] =
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "https://m.google.com/devicemanagement/data/api";
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Used in BrowserPolicyConnector::SetPolicyProviderForTesting.
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool g_created_policy_service = false;
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ConfigurationPolicyProvider* g_testing_provider = NULL;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ReportRegexSuccessMetric(bool success) {
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Enterprise.DomainWhitelistRegexSuccess", success);
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Regexes that match many of the larger public email providers as we know
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// these users are not from hosted enterprise domains. Keep this list in sync
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// with the EnterpriseDomainRegex enum in histograms.xml (i.e. only add things
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// at the end).
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const wchar_t* const kNonManagedDomainPatterns[] = {
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"aol\\.com",
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"googlemail\\.com",
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"gmail\\.com",
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"hotmail(\\.co|\\.com|)\\.[^.]+", // hotmail.com, hotmail.it, hotmail.co.uk
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"live\\.com",
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"mail\\.ru",
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"msn\\.com",
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"qq\\.com",
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"yahoo(\\.co|\\.com|)\\.[^.]+", // yahoo.com, yahoo.co.uk, yahoo.com.tw
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  L"yandex\\.ru",
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns true if |domain| matches the regex |pattern|.
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool MatchDomain(const base::string16& domain, const base::string16& pattern,
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                 size_t index) {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UErrorCode status = U_ZERO_ERROR;
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const icu::UnicodeString icu_pattern(pattern.data(), pattern.length());
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status);
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!U_SUCCESS(status)) {
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // http://crbug.com/365351 - if for some reason the matcher creation fails
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // just return that the pattern doesn't match the domain. This is safe
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // because the calling method (IsNonEnterpriseUser()) is just used to enable
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // an optimization for non-enterprise users - better to skip the
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // optimization than crash.
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DLOG(ERROR) << "Possible invalid domain pattern: " << pattern
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                << " - Error: " << status;
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ReportRegexSuccessMetric(false);
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Enterprise.DomainWhitelistRegexFailure",
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              index, arraysize(kNonManagedDomainPatterns));
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UMA_HISTOGRAM_SPARSE_SLOWLY("Enterprise.DomainWhitelistRegexFailureStatus",
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                status);
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ReportRegexSuccessMetric(true);
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  icu::UnicodeString icu_input(domain.data(), domain.length());
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  matcher.reset(icu_input);
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  status = U_ZERO_ERROR;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UBool match = matcher.matches(status);
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(U_SUCCESS(status));
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return !!match;  // !! == convert from UBool to bool.
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BrowserPolicyConnector::BrowserPolicyConnector(
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const HandlerListFactory& handler_list_factory)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : is_initialized_(false),
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      platform_policy_provider_(NULL) {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // GetPolicyService() must be ready after the constructor is done.
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The connector is created very early during startup, when the browser
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // threads aren't running yet; initialize components that need local_state,
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the system request context or other threads (e.g. FILE) at Init().
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Initialize the SchemaRegistry with the Chrome schema before creating any
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // of the policy providers in subclasses.
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chrome_schema_ = Schema::Wrap(GetChromeSchemaData());
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  handler_list_ = handler_list_factory.Run(chrome_schema_);
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  schema_registry_.RegisterComponent(PolicyNamespace(POLICY_DOMAIN_CHROME, ""),
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     chrome_schema_);
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BrowserPolicyConnector::~BrowserPolicyConnector() {
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_initialized()) {
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Shutdown() wasn't invoked by our owner after having called Init().
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // This usually means it's an early shutdown and
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // BrowserProcessImpl::StartTearDown() wasn't invoked.
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Cleanup properly in those cases and avoid crashing the ToastCrasher test.
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Shutdown();
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserPolicyConnector::Init(
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PrefService* local_state,
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_refptr<net::URLRequestContextGetter> request_context,
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<DeviceManagementService> device_management_service) {
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_initialized());
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  device_management_service_ = device_management_service.Pass();
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (g_testing_provider)
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    g_testing_provider->Init(GetSchemaRegistry());
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < policy_providers_.size(); ++i)
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy_providers_[i]->Init(GetSchemaRegistry());
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy_statistics_collector_.reset(
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new policy::PolicyStatisticsCollector(
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&GetChromePolicyDetails),
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GetChromeSchema(),
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          GetPolicyService(),
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          local_state,
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::MessageLoop::current()->message_loop_proxy()));
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy_statistics_collector_->Initialize();
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  is_initialized_ = true;
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserPolicyConnector::Shutdown() {
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  is_initialized_ = false;
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (g_testing_provider)
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    g_testing_provider->Shutdown();
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < policy_providers_.size(); ++i)
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy_providers_[i]->Shutdown();
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Drop g_testing_provider so that tests executed with --single_process can
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // call SetPolicyProviderForTesting() again. It is still owned by the test.
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  g_testing_provider = NULL;
15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  g_created_policy_service = false;
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  device_management_service_.reset();
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PolicyService* BrowserPolicyConnector::GetPolicyService() {
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!policy_service_) {
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    g_created_policy_service = true;
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::vector<ConfigurationPolicyProvider*> providers;
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (g_testing_provider) {
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      providers.push_back(g_testing_provider);
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      providers.resize(policy_providers_.size());
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::copy(policy_providers_.begin(),
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                policy_providers_.end(),
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                providers.begin());
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    policy_service_.reset(new PolicyServiceImpl(providers));
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return policy_service_.get();
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ConfigurationPolicyProvider* BrowserPolicyConnector::GetPlatformProvider() {
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (g_testing_provider)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return g_testing_provider;
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return platform_policy_provider_;
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const Schema& BrowserPolicyConnector::GetChromeSchema() const {
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return chrome_schema_;
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CombinedSchemaRegistry* BrowserPolicyConnector::GetSchemaRegistry() {
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return &schema_registry_;
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserPolicyConnector::ScheduleServiceInitialization(
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 delay_milliseconds) {
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Skip device initialization if the BrowserPolicyConnector was never
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // initialized (unit tests).
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (device_management_service_)
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    device_management_service_->ScheduleInitialization(delay_milliseconds);
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const ConfigurationPolicyHandlerList*
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BrowserPolicyConnector::GetHandlerList() const {
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return handler_list_.get();
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserPolicyConnector::SetPolicyProviderForTesting(
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ConfigurationPolicyProvider* provider) {
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If this function is used by a test then it must be called before the
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // browser is created, and GetPolicyService() gets called.
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(!g_created_policy_service);
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!g_testing_provider);
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  g_testing_provider = provider;
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool BrowserPolicyConnector::IsNonEnterpriseUser(const std::string& username) {
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (username.empty() || username.find('@') == std::string::npos) {
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // An empty username means incognito user in case of ChromiumOS and
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // no logged-in user in case of Chromium (SigninService). Many tests use
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // nonsense email addresses (e.g. 'test') so treat those as non-enterprise
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // users.
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::string16 domain = base::UTF8ToUTF16(
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gaia::ExtractDomainName(gaia::CanonicalizeEmail(username)));
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kNonManagedDomainPatterns); i++) {
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 pattern = base::WideToUTF16(kNonManagedDomainPatterns[i]);
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (MatchDomain(domain, pattern, i))
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string BrowserPolicyConnector::GetDeviceManagementUrl() {
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (command_line->HasSwitch(switches::kDeviceManagementUrl))
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl);
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return kDefaultDeviceManagementServerUrl;
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserPolicyConnector::RegisterPrefs(PrefRegistrySimple* registry) {
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  registry->RegisterIntegerPref(
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      policy_prefs::kUserPolicyRefreshRate,
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CloudPolicyRefreshScheduler::kDefaultRefreshDelayMs);
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserPolicyConnector::AddPolicyProvider(
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<ConfigurationPolicyProvider> provider) {
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  policy_providers_.push_back(provider.release());
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserPolicyConnector::SetPlatformPolicyProvider(
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<ConfigurationPolicyProvider> provider) {
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(!platform_policy_provider_);
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  platform_policy_provider_ = provider.get();
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddPolicyProvider(provider.Pass());
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace policy
264