Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / policy / cloud / user_policy_signin_service_base.cc
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.
4
5 #include "chrome/browser/policy/cloud/user_policy_signin_service_base.h"
6
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/cloud/user_cloud_policy_manager_factory.h"
12 #include "chrome/browser/signin/signin_manager.h"
13 #include "chrome/browser/signin/signin_manager_factory.h"
14 #include "chrome/common/chrome_content_client.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "components/policy/core/browser/browser_policy_connector.h"
17 #include "components/policy/core/common/cloud/device_management_service.h"
18 #include "components/policy/core/common/cloud/system_policy_request_context.h"
19 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
20 #include "components/policy/core/common/cloud/user_policy_request_context.h"
21 #include "content/public/browser/notification_source.h"
22 #include "net/url_request/url_request_context_getter.h"
23
24 namespace policy {
25
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));
44 }
45
46 UserPolicySigninServiceBase::~UserPolicySigninServiceBase() {}
47
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());
69
70   // Now initiate a policy fetch.
71   manager->core()->service()->RefreshPolicy(callback);
72 }
73
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();
95   }
96 }
97
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.
103 }
104
105 void UserPolicySigninServiceBase::OnPolicyFetched(CloudPolicyClient* client) {}
106
107 void UserPolicySigninServiceBase::OnRegistrationStateChanged(
108     CloudPolicyClient* client) {}
109
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";
119
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();
129     }
130   }
131 }
132
133 void UserPolicySigninServiceBase::Shutdown() {
134   PrepareForUserCloudPolicyManagerShutdown();
135 }
136
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);
143 }
144
145 scoped_ptr<CloudPolicyClient>
146 UserPolicySigninServiceBase::CreateClientForRegistrationOnly(
147     const std::string& username) {
148   DCHECK(!username.empty());
149   // We should not be called with a client already initialized.
150   DCHECK(!policy_manager() || !policy_manager()->core()->client());
151
152   // If the user should not get policy, just bail out.
153   if (!policy_manager() || !ShouldLoadPolicyForUser(username)) {
154     DVLOG(1) << "Signed in user is not in the whitelist";
155     return scoped_ptr<CloudPolicyClient>();
156   }
157
158   // If the DeviceManagementService is not yet initialized, start it up now.
159   device_management_service_->ScheduleInitialization(0);
160
161   // Create a new CloudPolicyClient for fetching the DMToken.
162   return UserCloudPolicyManager::CreateCloudPolicyClient(
163       device_management_service_, CreateSystemRequestContext());
164 }
165
166 bool UserPolicySigninServiceBase::ShouldLoadPolicyForUser(
167     const std::string& username) {
168   if (username.empty())
169     return false;  // Not signed in.
170
171   return !BrowserPolicyConnector::IsNonEnterpriseUser(username);
172 }
173
174 void UserPolicySigninServiceBase::InitializeOnProfileReady(Profile* profile) {
175   // If using a TestingProfile with no SigninManager or UserCloudPolicyManager,
176   // skip initialization.
177   if (!policy_manager() || !signin_manager()) {
178     DVLOG(1) << "Skipping initialization for tests due to missing components.";
179     return;
180   }
181
182   // Shutdown the UserCloudPolicyManager when the user signs out. We do
183   // this here because we don't want to get SIGNED_OUT notifications until
184   // after the profile has started initializing (http://crbug.com/316229).
185   registrar_.Add(this,
186                  chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
187                  content::Source<Profile>(profile));
188
189   std::string username = signin_manager()->GetAuthenticatedUsername();
190   if (username.empty())
191     ShutdownUserCloudPolicyManager();
192   else
193     InitializeForSignedInUser(username, profile->GetRequestContext());
194 }
195
196 void UserPolicySigninServiceBase::InitializeForSignedInUser(
197     const std::string& username,
198     scoped_refptr<net::URLRequestContextGetter> profile_request_context) {
199   DCHECK(!username.empty());
200   if (!ShouldLoadPolicyForUser(username)) {
201     DVLOG(1) << "Policy load not enabled for user: " << username;
202     return;
203   }
204
205   UserCloudPolicyManager* manager = policy_manager();
206   // Initialize the UCPM if it is not already initialized.
207   if (!manager->core()->service()) {
208     // If there is no cached DMToken then we can detect this when the
209     // OnInitializationCompleted() callback is invoked and this will
210     // initiate a policy fetch.
211     InitializeUserCloudPolicyManager(
212         username,
213         UserCloudPolicyManager::CreateCloudPolicyClient(
214             device_management_service_,
215             CreateUserRequestContext(profile_request_context)).Pass());
216   } else {
217     manager->SetSigninUsername(username);
218   }
219
220   // If the CloudPolicyService is initialized, kick off registration.
221   // Otherwise OnInitializationCompleted is invoked as soon as the service
222   // finishes its initialization.
223   if (manager->core()->service()->IsInitializationComplete())
224     OnInitializationCompleted(manager->core()->service());
225 }
226
227 void UserPolicySigninServiceBase::InitializeUserCloudPolicyManager(
228     const std::string& username,
229     scoped_ptr<CloudPolicyClient> client) {
230   DCHECK(client);
231   UserCloudPolicyManager* manager = policy_manager();
232   manager->SetSigninUsername(username);
233   DCHECK(!manager->core()->client());
234   scoped_refptr<net::URLRequestContextGetter> context =
235       client->GetRequestContext();
236   manager->Connect(local_state_, context, client.Pass());
237   DCHECK(manager->core()->service());
238
239   // Observe the client to detect errors fetching policy.
240   manager->core()->client()->AddObserver(this);
241   // Observe the service to determine when it's initialized.
242   manager->core()->service()->AddObserver(this);
243 }
244
245 void UserPolicySigninServiceBase::ShutdownUserCloudPolicyManager() {
246   PrepareForUserCloudPolicyManagerShutdown();
247   UserCloudPolicyManager* manager = policy_manager();
248   if (manager)
249     manager->DisconnectAndRemovePolicy();
250 }
251
252 scoped_refptr<net::URLRequestContextGetter>
253 UserPolicySigninServiceBase::CreateSystemRequestContext() {
254   return new SystemPolicyRequestContext(
255       system_request_context(), GetUserAgent());
256 }
257
258 scoped_refptr<net::URLRequestContextGetter>
259 UserPolicySigninServiceBase::CreateUserRequestContext(
260     scoped_refptr<net::URLRequestContextGetter> profile_request_context) {
261   return new UserPolicyRequestContext(
262       profile_request_context, system_request_context(), GetUserAgent());
263 }
264
265 }  // namespace policy