OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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/user_policy_controller.h" | |
6 | |
7 #include "base/file_util.h" | |
8 #include "chrome/browser/browser_signin.h" | |
9 #include "chrome/browser/browser_thread.h" | |
10 #include "chrome/browser/chromeos/login/user_manager.h" | |
11 #include "chrome/browser/net/gaia/token_service.h" | |
12 #include "chrome/browser/policy/proto/device_management_local.pb.h" | |
13 #include "chrome/browser/profiles/profile.h" | |
14 #include "chrome/common/guid.h" | |
15 #include "chrome/common/net/gaia/gaia_constants.h" | |
16 #include "chrome/common/notification_details.h" | |
17 #include "chrome/common/notification_service.h" | |
18 #include "chrome/common/notification_source.h" | |
19 | |
20 namespace policy { | |
21 | |
22 namespace em = enterprise_management; | |
23 | |
24 // Responsible for managing the on-disk token cache. | |
25 class UserPolicyController::TokenCache | |
26 : public base::RefCountedThreadSafe<UserPolicyController::TokenCache> { | |
27 public: | |
28 TokenCache(const base::WeakPtr<UserPolicyController>& provider, | |
29 const FilePath& cache_file); | |
30 | |
31 void Load(); | |
32 void Store(const std::string& token, const std::string& device_id); | |
33 | |
34 private: | |
35 void LoadOnFileThread(); | |
36 void NotifyOnUIThread(const std::string& token, | |
37 const std::string& device_id); | |
38 void StoreOnFileThread(const std::string& token, | |
39 const std::string& device_id); | |
40 | |
41 const base::WeakPtr<UserPolicyController> provider_; | |
danno
2011/02/04 16:01:33
controller
Jakob Kummerow
2011/02/14 13:50:34
Done.
| |
42 const FilePath& cache_file_; | |
43 | |
44 DISALLOW_COPY_AND_ASSIGN(TokenCache); | |
45 }; | |
46 | |
47 UserPolicyController::TokenCache::TokenCache( | |
48 const base::WeakPtr<UserPolicyController>& provider, | |
49 const FilePath& cache_file) | |
50 : provider_(provider), | |
51 cache_file_(cache_file) {} | |
52 | |
53 void UserPolicyController::TokenCache::Load() { | |
54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
55 BrowserThread::PostTask( | |
56 BrowserThread::FILE, FROM_HERE, | |
57 NewRunnableMethod( | |
58 this, &UserPolicyController::TokenCache::LoadOnFileThread)); | |
59 } | |
60 | |
61 void UserPolicyController::TokenCache::Store(const std::string& token, | |
62 const std::string& device_id) { | |
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
64 BrowserThread::PostTask( | |
65 BrowserThread::FILE, FROM_HERE, | |
66 NewRunnableMethod( | |
67 this, | |
68 &UserPolicyController::TokenCache::StoreOnFileThread, | |
69 token, | |
70 device_id)); | |
71 } | |
72 | |
73 void UserPolicyController::TokenCache::LoadOnFileThread() { | |
74 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
75 std::string device_token; | |
76 std::string device_id; | |
77 | |
78 if (file_util::PathExists(cache_file_)) { | |
79 std::string data; | |
80 em::DeviceCredentials device_credentials; | |
81 if (file_util::ReadFileToString(cache_file_, &data) && | |
82 device_credentials.ParseFromArray(data.c_str(), data.size())) { | |
83 device_token = device_credentials.device_token(); | |
84 device_id = device_credentials.device_id(); | |
85 } | |
86 } | |
87 | |
88 BrowserThread::PostTask( | |
89 BrowserThread::UI, FROM_HERE, | |
90 NewRunnableMethod( | |
91 this, | |
92 &UserPolicyController::TokenCache::NotifyOnUIThread, | |
93 device_token, | |
94 device_id)); | |
95 } | |
96 | |
97 void UserPolicyController::TokenCache::NotifyOnUIThread( | |
98 const std::string& token, | |
99 const std::string& device_id) { | |
100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
101 if (provider_.get()) | |
102 provider_->OnCacheLoaded(token, device_id); | |
103 } | |
104 | |
105 void UserPolicyController::TokenCache::StoreOnFileThread( | |
106 const std::string& token, | |
107 const std::string& device_id) { | |
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
109 em::DeviceCredentials device_credentials; | |
110 device_credentials.set_device_token(token); | |
111 device_credentials.set_device_id(device_id); | |
112 std::string data; | |
113 bool success = device_credentials.SerializeToString(&data); | |
114 if (!success) { | |
115 LOG(WARNING) << "Failed serialize device token data, will not write " | |
116 << cache_file_.value(); | |
117 return; | |
118 } | |
119 | |
120 file_util::WriteFile(cache_file_, data.c_str(), data.length()); | |
121 } | |
122 | |
123 UserPolicyController::UserPolicyController(Profile* profile, | |
124 const FilePath& cache_file) | |
125 : profile_(profile), | |
126 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | |
127 cache_ = new TokenCache(weak_ptr_factory_.GetWeakPtr(), cache_file); | |
128 | |
129 registrar_.Add(this, | |
130 NotificationType::TOKEN_AVAILABLE, | |
131 Source<TokenService>(profile->GetTokenService())); | |
132 | |
133 // Register for the event of user login. The device management token won't | |
134 // be fetched until we know the domain of the currently logged in user. | |
135 #if defined(OS_CHROMEOS) | |
136 registrar_.Add(this, | |
137 NotificationType::LOGIN_USER_CHANGED, | |
138 NotificationService::AllSources()); | |
139 #else | |
140 registrar_.Add(this, | |
141 NotificationType::GOOGLE_SIGNIN_SUCCESSFUL, | |
142 Source<Profile>(profile_)); | |
143 #endif | |
144 | |
145 cache_->Load(); | |
146 } | |
147 | |
148 UserPolicyController::~UserPolicyController() {} | |
149 | |
150 std::string UserPolicyController::GetDeviceToken() { | |
151 return device_token_; | |
152 } | |
153 | |
154 std::string UserPolicyController::GetDeviceID() { | |
155 return device_id_; | |
156 } | |
157 | |
158 bool UserPolicyController::GetCredentials(std::string* username, | |
159 std::string* auth_token) { | |
160 *username = GetCurrentUser(); | |
161 *auth_token = profile_->GetTokenService()->GetTokenForService( | |
162 GaiaConstants::kDeviceManagementService); | |
163 | |
164 return !username->empty() && !auth_token->empty() && !device_id_.empty(); | |
165 } | |
166 | |
167 void UserPolicyController::OnTokenAvailable(const std::string& token) { | |
168 DCHECK(!device_id_.empty()); | |
169 device_token_ = token; | |
170 cache_->Store(device_token_, device_id_); | |
171 NotifyTokenChanged(); | |
172 } | |
173 | |
174 std::string UserPolicyController::GetCurrentUser() { | |
175 #if defined(OS_CHROMEOS) | |
176 // TODO(mnissler) On CrOS it seems impossible to figure out what user belongs | |
177 // to a profile. Revisit after multi-profile support landed. | |
178 return chromeos::UserManager::Get()->logged_in_user().email(); | |
179 #else | |
180 return profile_->GetBrowserSignin()->GetSignedInUsername(); | |
181 #endif | |
182 } | |
183 | |
184 void UserPolicyController::CheckAndTriggerFetch() { | |
185 if (!GetCurrentUser().empty() && | |
186 profile_->GetTokenService()->HasTokenForService( | |
187 GaiaConstants::kDeviceManagementService)) { | |
188 // For user tokens, there is no actual identifier. We generate a random | |
189 // identifier instead each time we ask for the token. | |
190 device_id_ = guid::GenerateGUID(); | |
191 NotifyAuthChanged(); | |
192 } | |
193 } | |
194 | |
195 void UserPolicyController::OnCacheLoaded(const std::string& token, | |
196 const std::string& device_id) { | |
197 if (!token.empty() && !device_id.empty()) { | |
198 device_token_ = token; | |
199 device_id_ = device_id; | |
200 NotifyTokenChanged(); | |
201 } else { | |
202 CheckAndTriggerFetch(); | |
203 } | |
204 } | |
205 | |
206 void UserPolicyController::Observe(NotificationType type, | |
207 const NotificationSource& source, | |
208 const NotificationDetails& details) { | |
209 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
210 if (type == NotificationType::TOKEN_AVAILABLE) { | |
211 if (Source<TokenService>(source).ptr() == profile_->GetTokenService()) { | |
212 const TokenService::TokenAvailableDetails* token_details = | |
213 Details<const TokenService::TokenAvailableDetails>(details).ptr(); | |
214 if (token_details->service() == GaiaConstants::kDeviceManagementService) | |
215 CheckAndTriggerFetch(); | |
216 } | |
217 #if defined(OS_CHROMEOS) | |
218 } else if (type == NotificationType::LOGIN_USER_CHANGED) { | |
219 CheckAndTriggerFetch(); | |
220 #else | |
221 } else if (type == NotificationType::GOOGLE_SIGNIN_SUCCESSFUL) { | |
222 if (profile_ == Source<Profile>(source).ptr()) | |
223 CheckAndTriggerFetch(); | |
224 #endif | |
225 } else { | |
226 NOTREACHED(); | |
227 } | |
228 } | |
229 | |
230 } // namespace policy | |
OLD | NEW |