Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / policy / cloud / user_policy_signin_service_base.cc
blob2ae61ea2e10e43110ce69ded9a232f563bb2d729
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"
7 #include "base/bind.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/user_cloud_policy_manager_factory.h"
13 #include "chrome/browser/signin/signin_manager.h"
14 #include "chrome/browser/signin/signin_manager_factory.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "components/policy/core/common/cloud/device_management_service.h"
17 #include "components/policy/core/common/cloud/system_policy_request_context.h"
18 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
19 #include "components/policy/core/common/cloud/user_policy_request_context.h"
20 #include "content/public/browser/notification_source.h"
21 #include "content/public/common/content_client.h"
22 #include "net/url_request/url_request_context_getter.h"
24 namespace policy {
26 UserPolicySigninServiceBase::UserPolicySigninServiceBase(
27 Profile* profile,
28 PrefService* local_state,
29 DeviceManagementService* device_management_service,
30 UserCloudPolicyManager* policy_manager,
31 SigninManager* signin_manager,
32 scoped_refptr<net::URLRequestContextGetter> system_request_context)
33 : policy_manager_(policy_manager),
34 signin_manager_(signin_manager),
35 local_state_(local_state),
36 device_management_service_(device_management_service),
37 system_request_context_(system_request_context),
38 weak_factory_(this) {
39 // Register a listener to be called back once the current profile has finished
40 // initializing, so we can startup/shutdown the UserCloudPolicyManager.
41 registrar_.Add(this,
42 chrome::NOTIFICATION_PROFILE_ADDED,
43 content::Source<Profile>(profile));
46 UserPolicySigninServiceBase::~UserPolicySigninServiceBase() {}
48 void UserPolicySigninServiceBase::FetchPolicyForSignedInUser(
49 const std::string& username,
50 const std::string& dm_token,
51 const std::string& client_id,
52 scoped_refptr<net::URLRequestContextGetter> profile_request_context,
53 const PolicyFetchCallback& callback) {
54 scoped_ptr<CloudPolicyClient> client(
55 UserCloudPolicyManager::CreateCloudPolicyClient(
56 device_management_service_,
57 CreateUserRequestContext(profile_request_context)).Pass());
58 client->SetupRegistration(dm_token, client_id);
59 DCHECK(client->is_registered());
60 // The user has just signed in, so the UserCloudPolicyManager should not yet
61 // be initialized. This routine will initialize the UserCloudPolicyManager
62 // with the passed client and will proactively ask the client to fetch
63 // policy without waiting for the CloudPolicyService to finish initialization.
64 UserCloudPolicyManager* manager = policy_manager();
65 DCHECK(manager);
66 DCHECK(!manager->core()->client());
67 InitializeUserCloudPolicyManager(username, client.Pass());
68 DCHECK(manager->IsClientRegistered());
70 // Now initiate a policy fetch.
71 manager->core()->service()->RefreshPolicy(callback);
74 void UserPolicySigninServiceBase::Observe(
75 int type,
76 const content::NotificationSource& source,
77 const content::NotificationDetails& details) {
78 switch (type) {
79 case chrome::NOTIFICATION_GOOGLE_SIGNED_OUT:
80 ShutdownUserCloudPolicyManager();
81 break;
82 case chrome::NOTIFICATION_PROFILE_ADDED:
83 // A new profile has been loaded - if it's signed in, then initialize the
84 // UCPM, otherwise shut down the UCPM (which deletes any cached policy
85 // data). This must be done here instead of at constructor time because
86 // the Profile is not fully initialized when this object is constructed
87 // (DoFinalInit() has not yet been called, so ProfileIOData and
88 // SSLConfigServiceManager have not been created yet).
89 // TODO(atwilson): Switch to using a timer instead, to avoid contention
90 // with other services at startup (http://crbug.com/165468).
91 InitializeOnProfileReady(content::Source<Profile>(source).ptr());
92 break;
93 default:
94 NOTREACHED();
98 void UserPolicySigninServiceBase::OnInitializationCompleted(
99 CloudPolicyService* service) {
100 // This is meant to be overridden by subclasses. Starting and stopping to
101 // observe the CloudPolicyService from this base class avoids the need for
102 // more virtuals.
105 void UserPolicySigninServiceBase::OnPolicyFetched(CloudPolicyClient* client) {}
107 void UserPolicySigninServiceBase::OnRegistrationStateChanged(
108 CloudPolicyClient* client) {}
110 void UserPolicySigninServiceBase::OnClientError(CloudPolicyClient* client) {
111 if (client->is_registered()) {
112 // If the client is already registered, it means this error must have
113 // come from a policy fetch.
114 if (client->status() == DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED) {
115 // OK, policy fetch failed with MANAGEMENT_NOT_SUPPORTED - this is our
116 // trigger to revert to "unmanaged" mode (we will check for management
117 // being re-enabled on the next restart and/or login).
118 DVLOG(1) << "DMServer returned NOT_SUPPORTED error - removing policy";
120 // Can't shutdown now because we're in the middle of a callback from
121 // the CloudPolicyClient, so queue up a task to do the shutdown.
122 base::MessageLoop::current()->PostTask(
123 FROM_HERE,
124 base::Bind(
125 &UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager,
126 weak_factory_.GetWeakPtr()));
127 } else {
128 DVLOG(1) << "Error fetching policy: " << client->status();
133 void UserPolicySigninServiceBase::Shutdown() {
134 PrepareForUserCloudPolicyManagerShutdown();
137 void UserPolicySigninServiceBase::PrepareForUserCloudPolicyManagerShutdown() {
138 UserCloudPolicyManager* manager = policy_manager();
139 if (manager && manager->core()->client())
140 manager->core()->client()->RemoveObserver(this);
141 if (manager && manager->core()->service())
142 manager->core()->service()->RemoveObserver(this);
145 // static
146 bool UserPolicySigninServiceBase::ShouldForceLoadPolicy() {
147 return CommandLine::ForCurrentProcess()->HasSwitch(
148 switches::kForceLoadCloudPolicy);
151 scoped_ptr<CloudPolicyClient>
152 UserPolicySigninServiceBase::CreateClientForRegistrationOnly(
153 const std::string& username) {
154 DCHECK(!username.empty());
155 // We should not be called with a client already initialized.
156 DCHECK(!policy_manager() || !policy_manager()->core()->client());
158 // If the user should not get policy, just bail out.
159 if (!policy_manager() || !ShouldLoadPolicyForUser(username)) {
160 DVLOG(1) << "Signed in user is not in the whitelist";
161 return scoped_ptr<CloudPolicyClient>();
164 // If the DeviceManagementService is not yet initialized, start it up now.
165 device_management_service_->ScheduleInitialization(0);
167 // Create a new CloudPolicyClient for fetching the DMToken.
168 return UserCloudPolicyManager::CreateCloudPolicyClient(
169 device_management_service_, CreateSystemRequestContext());
172 bool UserPolicySigninServiceBase::ShouldLoadPolicyForUser(
173 const std::string& username) {
174 if (username.empty())
175 return false; // Not signed in.
177 if (ShouldForceLoadPolicy())
178 return true;
180 return !BrowserPolicyConnector::IsNonEnterpriseUser(username);
183 void UserPolicySigninServiceBase::InitializeOnProfileReady(Profile* profile) {
184 // If using a TestingProfile with no SigninManager or UserCloudPolicyManager,
185 // skip initialization.
186 if (!policy_manager() || !signin_manager()) {
187 DVLOG(1) << "Skipping initialization for tests due to missing components.";
188 return;
191 // Shutdown the UserCloudPolicyManager when the user signs out. We do
192 // this here because we don't want to get SIGNED_OUT notifications until
193 // after the profile has started initializing (http://crbug.com/316229).
194 registrar_.Add(this,
195 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
196 content::Source<Profile>(profile));
198 std::string username = signin_manager()->GetAuthenticatedUsername();
199 if (username.empty())
200 ShutdownUserCloudPolicyManager();
201 else
202 InitializeForSignedInUser(username, profile->GetRequestContext());
205 void UserPolicySigninServiceBase::InitializeForSignedInUser(
206 const std::string& username,
207 scoped_refptr<net::URLRequestContextGetter> profile_request_context) {
208 DCHECK(!username.empty());
209 if (!ShouldLoadPolicyForUser(username)) {
210 DVLOG(1) << "Policy load not enabled for user: " << username;
211 return;
214 UserCloudPolicyManager* manager = policy_manager();
215 // Initialize the UCPM if it is not already initialized.
216 if (!manager->core()->service()) {
217 // If there is no cached DMToken then we can detect this when the
218 // OnInitializationCompleted() callback is invoked and this will
219 // initiate a policy fetch.
220 InitializeUserCloudPolicyManager(
221 username,
222 UserCloudPolicyManager::CreateCloudPolicyClient(
223 device_management_service_,
224 CreateUserRequestContext(profile_request_context)).Pass());
225 } else {
226 manager->SetSigninUsername(username);
229 // If the CloudPolicyService is initialized, kick off registration.
230 // Otherwise OnInitializationCompleted is invoked as soon as the service
231 // finishes its initialization.
232 if (manager->core()->service()->IsInitializationComplete())
233 OnInitializationCompleted(manager->core()->service());
236 void UserPolicySigninServiceBase::InitializeUserCloudPolicyManager(
237 const std::string& username,
238 scoped_ptr<CloudPolicyClient> client) {
239 DCHECK(client);
240 UserCloudPolicyManager* manager = policy_manager();
241 manager->SetSigninUsername(username);
242 DCHECK(!manager->core()->client());
243 scoped_refptr<net::URLRequestContextGetter> context =
244 client->GetRequestContext();
245 manager->Connect(local_state_, context, client.Pass());
246 DCHECK(manager->core()->service());
248 // Observe the client to detect errors fetching policy.
249 manager->core()->client()->AddObserver(this);
250 // Observe the service to determine when it's initialized.
251 manager->core()->service()->AddObserver(this);
254 void UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager() {
255 PrepareForUserCloudPolicyManagerShutdown();
256 UserCloudPolicyManager* manager = policy_manager();
257 if (manager)
258 manager->DisconnectAndRemovePolicy();
261 scoped_refptr<net::URLRequestContextGetter>
262 UserPolicySigninServiceBase::CreateSystemRequestContext() {
263 return new SystemPolicyRequestContext(
264 system_request_context(),
265 content::GetUserAgent(GURL(device_management_service_->GetServerUrl())));
268 scoped_refptr<net::URLRequestContextGetter>
269 UserPolicySigninServiceBase::CreateUserRequestContext(
270 scoped_refptr<net::URLRequestContextGetter> profile_request_context) {
271 return new UserPolicyRequestContext(
272 profile_request_context,
273 system_request_context(),
274 content::GetUserAgent(GURL(device_management_service_->GetServerUrl())));
277 } // namespace policy