Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Side by Side Diff: chrome/browser/policy/user_policy_identity_strategy.cc

Issue 6520008: Device policy infrastructure (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix nits Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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_identity_strategy.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 UserPolicyIdentityStrategy::TokenCache
26 : public base::RefCountedThreadSafe<
27 UserPolicyIdentityStrategy::TokenCache> {
28 public:
29 TokenCache(const base::WeakPtr<UserPolicyIdentityStrategy>& identity_strategy,
30 const FilePath& cache_file);
31
32 void Load();
33 void Store(const std::string& token, const std::string& device_id);
34
35 private:
36 friend class base::RefCountedThreadSafe<
37 UserPolicyIdentityStrategy::TokenCache>;
38 ~TokenCache() {}
39 void LoadOnFileThread();
40 void NotifyOnUIThread(const std::string& token,
41 const std::string& device_id);
42 void StoreOnFileThread(const std::string& token,
43 const std::string& device_id);
44
45 const base::WeakPtr<UserPolicyIdentityStrategy> identity_strategy_;
46 const FilePath cache_file_;
47
48 DISALLOW_COPY_AND_ASSIGN(TokenCache);
49 };
50
51 UserPolicyIdentityStrategy::TokenCache::TokenCache(
52 const base::WeakPtr<UserPolicyIdentityStrategy>& identity_strategy,
53 const FilePath& cache_file)
54 : identity_strategy_(identity_strategy),
55 cache_file_(cache_file) {}
56
57 void UserPolicyIdentityStrategy::TokenCache::Load() {
58 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
59 BrowserThread::PostTask(
60 BrowserThread::FILE, FROM_HERE,
61 NewRunnableMethod(
62 this, &UserPolicyIdentityStrategy::TokenCache::LoadOnFileThread));
63 }
64
65 void UserPolicyIdentityStrategy::TokenCache::Store(
66 const std::string& token,
67 const std::string& device_id) {
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
69 BrowserThread::PostTask(
70 BrowserThread::FILE, FROM_HERE,
71 NewRunnableMethod(
72 this,
73 &UserPolicyIdentityStrategy::TokenCache::StoreOnFileThread,
74 token,
75 device_id));
76 }
77
78 void UserPolicyIdentityStrategy::TokenCache::LoadOnFileThread() {
79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
80 std::string device_token;
81 std::string device_id;
82
83 if (file_util::PathExists(cache_file_)) {
84 std::string data;
85 em::DeviceCredentials device_credentials;
86 if (file_util::ReadFileToString(cache_file_, &data) &&
87 device_credentials.ParseFromArray(data.c_str(), data.size())) {
88 device_token = device_credentials.device_token();
89 device_id = device_credentials.device_id();
90 }
91 }
92
93 BrowserThread::PostTask(
94 BrowserThread::UI, FROM_HERE,
95 NewRunnableMethod(
96 this,
97 &UserPolicyIdentityStrategy::TokenCache::NotifyOnUIThread,
98 device_token,
99 device_id));
100 }
101
102 void UserPolicyIdentityStrategy::TokenCache::NotifyOnUIThread(
103 const std::string& token,
104 const std::string& device_id) {
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
106 if (identity_strategy_.get())
107 identity_strategy_->OnCacheLoaded(token, device_id);
108 }
109
110 void UserPolicyIdentityStrategy::TokenCache::StoreOnFileThread(
111 const std::string& token,
112 const std::string& device_id) {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
114 em::DeviceCredentials device_credentials;
115 device_credentials.set_device_token(token);
116 device_credentials.set_device_id(device_id);
117 std::string data;
118 bool success = device_credentials.SerializeToString(&data);
119 if (!success) {
120 LOG(WARNING) << "Failed serialize device token data, will not write "
121 << cache_file_.value();
122 return;
123 }
124
125 file_util::WriteFile(cache_file_, data.c_str(), data.length());
126 }
127
128 UserPolicyIdentityStrategy::UserPolicyIdentityStrategy(
129 Profile* profile,
130 const FilePath& cache_file)
131 : profile_(profile),
132 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
133 cache_ = new TokenCache(weak_ptr_factory_.GetWeakPtr(), cache_file);
134 registrar_.Add(this,
135 NotificationType::TOKEN_AVAILABLE,
136 Source<TokenService>(profile->GetTokenService()));
137
138 // Register for the event of user login. The device management token won't
139 // be fetched until we know the domain of the currently logged in user.
140 #if defined(OS_CHROMEOS)
141 registrar_.Add(this,
142 NotificationType::LOGIN_USER_CHANGED,
143 NotificationService::AllSources());
144 #else
145 registrar_.Add(this,
146 NotificationType::GOOGLE_SIGNIN_SUCCESSFUL,
147 Source<Profile>(profile_));
148 #endif
149
150 cache_->Load();
151 }
152
153 UserPolicyIdentityStrategy::~UserPolicyIdentityStrategy() {}
154
155 std::string UserPolicyIdentityStrategy::GetDeviceToken() {
156 return device_token_;
157 }
158
159 std::string UserPolicyIdentityStrategy::GetDeviceID() {
160 return device_id_;
161 }
162
163 bool UserPolicyIdentityStrategy::GetCredentials(std::string* username,
164 std::string* auth_token) {
165 *username = GetCurrentUser();
166 *auth_token = profile_->GetTokenService()->GetTokenForService(
167 GaiaConstants::kDeviceManagementService);
168
169 return !username->empty() && !auth_token->empty() && !device_id_.empty();
170 }
171
172 void UserPolicyIdentityStrategy::OnDeviceTokenAvailable(
173 const std::string& token) {
174 DCHECK(!device_id_.empty());
175 device_token_ = token;
176 cache_->Store(device_token_, device_id_);
177 NotifyDeviceTokenChanged();
178 }
179
180 std::string UserPolicyIdentityStrategy::GetCurrentUser() {
181 #if defined(OS_CHROMEOS)
182 // TODO(mnissler) On CrOS it seems impossible to figure out what user belongs
183 // to a profile. Revisit after multi-profile support landed.
184 return chromeos::UserManager::Get()->logged_in_user().email();
185 #else
186 return profile_->GetBrowserSignin()->GetSignedInUsername();
187 #endif
188 }
189
190 void UserPolicyIdentityStrategy::CheckAndTriggerFetch() {
191 if (!GetCurrentUser().empty() &&
192 profile_->GetTokenService()->HasTokenForService(
193 GaiaConstants::kDeviceManagementService)) {
194 // For user tokens, there is no actual identifier. We generate a random
195 // identifier instead each time we ask for the token.
196 device_id_ = guid::GenerateGUID();
197 NotifyAuthChanged();
198 }
199 }
200
201 void UserPolicyIdentityStrategy::OnCacheLoaded(const std::string& token,
202 const std::string& device_id) {
203 if (!token.empty() && !device_id.empty()) {
204 device_token_ = token;
205 device_id_ = device_id;
206 NotifyDeviceTokenChanged();
207 } else {
208 CheckAndTriggerFetch();
209 }
210 }
211
212 void UserPolicyIdentityStrategy::Observe(NotificationType type,
213 const NotificationSource& source,
214 const NotificationDetails& details) {
215 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
216 if (type == NotificationType::TOKEN_AVAILABLE) {
217 if (Source<TokenService>(source).ptr() == profile_->GetTokenService()) {
218 const TokenService::TokenAvailableDetails* token_details =
219 Details<const TokenService::TokenAvailableDetails>(details).ptr();
220 if (token_details->service() == GaiaConstants::kDeviceManagementService)
221 CheckAndTriggerFetch();
222 }
223 #if defined(OS_CHROMEOS)
224 } else if (type == NotificationType::LOGIN_USER_CHANGED) {
225 CheckAndTriggerFetch();
226 #else
227 } else if (type == NotificationType::GOOGLE_SIGNIN_SUCCESSFUL) {
228 if (profile_ == Source<Profile>(source).ptr())
229 CheckAndTriggerFetch();
230 #endif
231 } else {
232 NOTREACHED();
233 }
234 }
235
236 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698