1 // Copyright 2013 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 "chrome/browser/policy/cloud/user_policy_signin_service_base.h"
8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/policy/browser_policy_connector.h"
12 #include "chrome/browser/policy/cloud/device_management_service.h"
13 #include "chrome/browser/policy/cloud/user_cloud_policy_manager.h"
14 #include "chrome/browser/policy/cloud/user_cloud_policy_manager_factory.h"
15 #include "chrome/browser/signin/signin_manager.h"
16 #include "chrome/browser/signin/signin_manager_factory.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "content/public/browser/notification_source.h"
19 #include "net/url_request/url_request_context_getter.h"
23 UserPolicySigninServiceBase::UserPolicySigninServiceBase(
25 PrefService* local_state,
26 scoped_refptr<net::URLRequestContextGetter> request_context,
27 DeviceManagementService* device_management_service)
29 local_state_(local_state),
30 request_context_(request_context),
31 device_management_service_(device_management_service),
33 // Initialize/shutdown the UserCloudPolicyManager when the user signs out.
35 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
36 content::Source<Profile>(profile));
38 // Register a listener to be called back once the current profile has finished
39 // initializing, so we can startup the UserCloudPolicyManager.
41 chrome::NOTIFICATION_PROFILE_ADDED,
42 content::Source<Profile>(profile));
45 UserPolicySigninServiceBase::~UserPolicySigninServiceBase() {}
47 void UserPolicySigninServiceBase::FetchPolicyForSignedInUser(
48 scoped_ptr<CloudPolicyClient> client,
49 const PolicyFetchCallback& callback) {
51 DCHECK(client->is_registered());
52 // The user has just signed in, so the UserCloudPolicyManager should not yet
53 // be initialized. This routine will initialize the UserCloudPolicyManager
54 // with the passed client and will proactively ask the client to fetch
55 // policy without waiting for the CloudPolicyService to finish initialization.
56 UserCloudPolicyManager* manager = GetManager();
58 DCHECK(!manager->core()->client());
59 InitializeUserCloudPolicyManager(client.Pass());
60 DCHECK(manager->IsClientRegistered());
62 // Now initiate a policy fetch.
63 manager->core()->service()->RefreshPolicy(callback);
66 void UserPolicySigninServiceBase::Observe(
68 const content::NotificationSource& source,
69 const content::NotificationDetails& details) {
70 // If using a TestingProfile with no SigninManager or UserCloudPolicyManager,
71 // skip initialization.
72 if (!GetManager() || !GetSigninManager()) {
73 DVLOG(1) << "Skipping initialization for tests due to missing components.";
78 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
79 ShutdownUserCloudPolicyManager();
81 case chrome::NOTIFICATION_PROFILE_ADDED:
82 // A new profile has been loaded - if it's signed in, then initialize the
83 // UCPM, otherwise shut down the UCPM (which deletes any cached policy
84 // data). This must be done here instead of at constructor time because
85 // the Profile is not fully initialized when this object is constructed
86 // (DoFinalInit() has not yet been called, so ProfileIOData and
87 // SSLConfigServiceManager have not been created yet).
88 // TODO(atwilson): Switch to using a timer instead, to avoid contention
89 // with other services at startup (http://crbug.com/165468).
90 InitializeOnProfileReady();
97 void UserPolicySigninServiceBase::OnInitializationCompleted(
98 CloudPolicyService* service) {
99 // This is meant to be overridden by subclasses. Starting and stopping to
100 // observe the CloudPolicyService from this base class avoids the need for
104 void UserPolicySigninServiceBase::OnPolicyFetched(CloudPolicyClient* client) {}
106 void UserPolicySigninServiceBase::OnRegistrationStateChanged(
107 CloudPolicyClient* client) {}
109 void UserPolicySigninServiceBase::OnClientError(CloudPolicyClient* client) {
110 if (client->is_registered()) {
111 // If the client is already registered, it means this error must have
112 // come from a policy fetch.
113 if (client->status() == DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED) {
114 // OK, policy fetch failed with MANAGEMENT_NOT_SUPPORTED - this is our
115 // trigger to revert to "unmanaged" mode (we will check for management
116 // being re-enabled on the next restart and/or login).
117 DVLOG(1) << "DMServer returned NOT_SUPPORTED error - removing policy";
119 // Can't shutdown now because we're in the middle of a callback from
120 // the CloudPolicyClient, so queue up a task to do the shutdown.
121 base::MessageLoop::current()->PostTask(
124 &UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager,
125 weak_factory_.GetWeakPtr()));
127 DVLOG(1) << "Error fetching policy: " << client->status();
132 void UserPolicySigninServiceBase::Shutdown() {
133 PrepareForUserCloudPolicyManagerShutdown();
136 void UserPolicySigninServiceBase::PrepareForUserCloudPolicyManagerShutdown() {
137 UserCloudPolicyManager* manager = GetManager();
138 if (manager && manager->core()->client())
139 manager->core()->client()->RemoveObserver(this);
140 if (manager && manager->core()->service())
141 manager->core()->service()->RemoveObserver(this);
145 bool UserPolicySigninServiceBase::ShouldForceLoadPolicy() {
146 return CommandLine::ForCurrentProcess()->HasSwitch(
147 switches::kForceLoadCloudPolicy);
150 scoped_ptr<CloudPolicyClient> UserPolicySigninServiceBase::PrepareToRegister(
151 const std::string& username) {
152 DCHECK(!username.empty());
153 // We should not be called with a client already initialized.
154 DCHECK(!GetManager() || !GetManager()->core()->client());
156 // If the user should not get policy, just bail out.
157 if (!GetManager() || !ShouldLoadPolicyForUser(username)) {
158 DVLOG(1) << "Signed in user is not in the whitelist";
159 return scoped_ptr<CloudPolicyClient>();
162 // If the DeviceManagementService is not yet initialized, start it up now.
163 device_management_service_->ScheduleInitialization(0);
165 // Create a new CloudPolicyClient for fetching the DMToken.
166 return UserCloudPolicyManager::CreateCloudPolicyClient(
167 device_management_service_);
170 bool UserPolicySigninServiceBase::ShouldLoadPolicyForUser(
171 const std::string& username) {
172 if (username.empty())
173 return false; // Not signed in.
175 if (ShouldForceLoadPolicy())
178 return !BrowserPolicyConnector::IsNonEnterpriseUser(username);
181 void UserPolicySigninServiceBase::InitializeOnProfileReady() {
182 std::string username = GetSigninManager()->GetAuthenticatedUsername();
183 if (username.empty())
184 ShutdownUserCloudPolicyManager();
186 InitializeForSignedInUser(username);
189 void UserPolicySigninServiceBase::InitializeForSignedInUser(
190 const std::string& username) {
191 DCHECK(!username.empty());
192 if (!ShouldLoadPolicyForUser(username)) {
193 DVLOG(1) << "Policy load not enabled for user: " << username;
197 UserCloudPolicyManager* manager = GetManager();
198 // Initialize the UCPM if it is not already initialized.
199 if (!manager->core()->service()) {
200 // If there is no cached DMToken then we can detect this when the
201 // OnInitializationCompleted() callback is invoked and this will
202 // initiate a policy fetch.
203 InitializeUserCloudPolicyManager(
204 UserCloudPolicyManager::CreateCloudPolicyClient(
205 device_management_service_).Pass());
208 // If the CloudPolicyService is initialized, kick off registration.
209 // Otherwise OnInitializationCompleted is invoked as soon as the service
210 // finishes its initialization.
211 if (manager->core()->service()->IsInitializationComplete())
212 OnInitializationCompleted(manager->core()->service());
215 void UserPolicySigninServiceBase::InitializeUserCloudPolicyManager(
216 scoped_ptr<CloudPolicyClient> client) {
217 UserCloudPolicyManager* manager = GetManager();
218 DCHECK(!manager->core()->client());
219 manager->Connect(local_state_, request_context_, client.Pass());
220 DCHECK(manager->core()->service());
222 // Observe the client to detect errors fetching policy.
223 manager->core()->client()->AddObserver(this);
224 // Observe the service to determine when it's initialized.
225 manager->core()->service()->AddObserver(this);
228 void UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager() {
229 PrepareForUserCloudPolicyManagerShutdown();
230 UserCloudPolicyManager* manager = GetManager();
232 manager->DisconnectAndRemovePolicy();
235 UserCloudPolicyManager* UserPolicySigninServiceBase::GetManager() {
236 return UserCloudPolicyManagerFactory::GetForProfile(profile_);
239 SigninManager* UserPolicySigninServiceBase::GetSigninManager() {
240 return SigninManagerFactory::GetForProfile(profile_);
243 } // namespace policy