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