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

Unified Diff: chrome/browser/policy/user_policy_controller.cc

Issue 6312121: Add initial device policy infrastructure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix race condition and tests. Created 9 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/policy/user_policy_controller.h ('k') | chrome/browser/prefs/browser_prefs.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/policy/user_policy_controller.cc
diff --git a/chrome/browser/policy/user_policy_controller.cc b/chrome/browser/policy/user_policy_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..273610deb7540684f3b84aa3634d2d7d6b2beb27
--- /dev/null
+++ b/chrome/browser/policy/user_policy_controller.cc
@@ -0,0 +1,230 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/user_policy_controller.h"
+
+#include "base/file_util.h"
+#include "chrome/browser/browser_signin.h"
+#include "chrome/browser/browser_thread.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
+#include "chrome/browser/net/gaia/token_service.h"
+#include "chrome/browser/policy/proto/device_management_local.pb.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/guid.h"
+#include "chrome/common/net/gaia/gaia_constants.h"
+#include "chrome/common/notification_details.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_source.h"
+
+namespace policy {
+
+namespace em = enterprise_management;
+
+// Responsible for managing the on-disk token cache.
+class UserPolicyController::TokenCache
+ : public base::RefCountedThreadSafe<UserPolicyController::TokenCache> {
+ public:
+ TokenCache(const base::WeakPtr<UserPolicyController>& provider,
+ const FilePath& cache_file);
+
+ void Load();
+ void Store(const std::string& token, const std::string& device_id);
+
+ private:
+ void LoadOnFileThread();
+ void NotifyOnUIThread(const std::string& token,
+ const std::string& device_id);
+ void StoreOnFileThread(const std::string& token,
+ const std::string& device_id);
+
+ const base::WeakPtr<UserPolicyController> provider_;
+ const FilePath& cache_file_;
+
+ DISALLOW_COPY_AND_ASSIGN(TokenCache);
+};
+
+UserPolicyController::TokenCache::TokenCache(
+ const base::WeakPtr<UserPolicyController>& provider,
+ const FilePath& cache_file)
+ : provider_(provider),
+ cache_file_(cache_file) {}
+
+void UserPolicyController::TokenCache::Load() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(
+ this, &UserPolicyController::TokenCache::LoadOnFileThread));
+}
+
+void UserPolicyController::TokenCache::Store(const std::string& token,
+ const std::string& device_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &UserPolicyController::TokenCache::StoreOnFileThread,
+ token,
+ device_id));
+}
+
+void UserPolicyController::TokenCache::LoadOnFileThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ std::string device_token;
+ std::string device_id;
+
+ if (file_util::PathExists(cache_file_)) {
+ std::string data;
+ em::DeviceCredentials device_credentials;
+ if (file_util::ReadFileToString(cache_file_, &data) &&
+ device_credentials.ParseFromArray(data.c_str(), data.size())) {
+ device_token = device_credentials.device_token();
+ device_id = device_credentials.device_id();
+ }
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &UserPolicyController::TokenCache::NotifyOnUIThread,
+ device_token,
+ device_id));
+}
+
+void UserPolicyController::TokenCache::NotifyOnUIThread(
+ const std::string& token,
+ const std::string& device_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (provider_.get())
+ provider_->OnCacheLoaded(token, device_id);
+}
+
+void UserPolicyController::TokenCache::StoreOnFileThread(
+ const std::string& token,
+ const std::string& device_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ em::DeviceCredentials device_credentials;
+ device_credentials.set_device_token(token);
+ device_credentials.set_device_id(device_id);
+ std::string data;
+ bool success = device_credentials.SerializeToString(&data);
+ if (!success) {
+ LOG(WARNING) << "Failed serialize device token data, will not write "
+ << cache_file_.value();
+ return;
+ }
+
+ file_util::WriteFile(cache_file_, data.c_str(), data.length());
+}
+
+UserPolicyController::UserPolicyController(Profile* profile,
+ const FilePath& cache_file)
+ : profile_(profile),
+ ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+ cache_ = new TokenCache(weak_ptr_factory_.GetWeakPtr(), cache_file);
+
+ registrar_.Add(this,
+ NotificationType::TOKEN_AVAILABLE,
+ Source<TokenService>(profile->GetTokenService()));
+
+ // Register for the event of user login. The device management token won't
+ // be fetched until we know the domain of the currently logged in user.
+#if defined(OS_CHROMEOS)
+ registrar_.Add(this,
+ NotificationType::LOGIN_USER_CHANGED,
+ NotificationService::AllSources());
+#else
+ registrar_.Add(this,
+ NotificationType::GOOGLE_SIGNIN_SUCCESSFUL,
+ Source<Profile>(profile_));
+#endif
+
+ cache_->Load();
+}
+
+UserPolicyController::~UserPolicyController() {}
+
+std::string UserPolicyController::GetDeviceToken() {
+ return device_token_;
+}
+
+std::string UserPolicyController::GetDeviceID() {
+ return device_id_;
+}
+
+bool UserPolicyController::GetCredentials(std::string* username,
+ std::string* auth_token) {
+ *username = GetCurrentUser();
+ *auth_token = profile_->GetTokenService()->GetTokenForService(
+ GaiaConstants::kDeviceManagementService);
+
+ return !username->empty() && !auth_token->empty() && !device_id_.empty();
+}
+
+void UserPolicyController::OnTokenAvailable(const std::string& token) {
+ DCHECK(!device_id_.empty());
+ device_token_ = token;
+ cache_->Store(device_token_, device_id_);
+ NotifyTokenChanged();
+}
+
+std::string UserPolicyController::GetCurrentUser() {
+#if defined(OS_CHROMEOS)
+ // TODO(mnissler) On CrOS it seems impossible to figure out what user belongs
+ // to a profile. Revisit after multi-profile support landed.
+ return chromeos::UserManager::Get()->logged_in_user().email();
+#else
+ return profile_->GetBrowserSignin()->GetSignedInUsername();
+#endif
+}
+
+void UserPolicyController::CheckAndTriggerFetch() {
+ if (!GetCurrentUser().empty() &&
+ profile_->GetTokenService()->HasTokenForService(
+ GaiaConstants::kDeviceManagementService)) {
+ // For user tokens, there is no actual identifier. We generate a random
+ // identifier instead each time we ask for the token.
+ device_id_ = guid::GenerateGUID();
+ NotifyAuthChanged();
+ }
+}
+
+void UserPolicyController::OnCacheLoaded(const std::string& token,
+ const std::string& device_id) {
+ if (!token.empty() && !device_id.empty()) {
+ device_token_ = token;
+ device_id_ = device_id;
+ NotifyTokenChanged();
+ } else {
+ CheckAndTriggerFetch();
+ }
+}
+
+void UserPolicyController::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (type == NotificationType::TOKEN_AVAILABLE) {
+ if (Source<TokenService>(source).ptr() == profile_->GetTokenService()) {
+ const TokenService::TokenAvailableDetails* token_details =
+ Details<const TokenService::TokenAvailableDetails>(details).ptr();
+ if (token_details->service() == GaiaConstants::kDeviceManagementService)
+ CheckAndTriggerFetch();
+ }
+#if defined(OS_CHROMEOS)
+ } else if (type == NotificationType::LOGIN_USER_CHANGED) {
+ CheckAndTriggerFetch();
+#else
+ } else if (type == NotificationType::GOOGLE_SIGNIN_SUCCESSFUL) {
+ if (profile_ == Source<Profile>(source).ptr())
+ CheckAndTriggerFetch();
+#endif
+ } else {
+ NOTREACHED();
+ }
+}
+
+} // namespace policy
« no previous file with comments | « chrome/browser/policy/user_policy_controller.h ('k') | chrome/browser/prefs/browser_prefs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698