summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/chromeos/chrome_browser_main_chromeos.cc18
-rw-r--r--chrome/browser/chromeos/chrome_browser_main_chromeos.h1
-rw-r--r--chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc3
-rw-r--r--chrome/browser/chromeos/locale_change_guard.cc8
-rw-r--r--chrome/browser/chromeos/login/base_login_display_host.cc6
-rw-r--r--chrome/browser/chromeos/login/base_login_display_host.h6
-rw-r--r--chrome/browser/chromeos/login/existing_user_controller.cc59
-rw-r--r--chrome/browser/chromeos/login/existing_user_controller.h16
-rw-r--r--chrome/browser/chromeos/login/language_switch_menu.cc1
-rw-r--r--chrome/browser/chromeos/login/login_performer.cc61
-rw-r--r--chrome/browser/chromeos/login/login_performer.h25
-rw-r--r--chrome/browser/chromeos/login/login_utils.cc1
-rw-r--r--chrome/browser/chromeos/login/login_utils_browsertest.cc7
-rw-r--r--chrome/browser/chromeos/login/parallel_authenticator.cc39
-rw-r--r--chrome/browser/chromeos/login/parallel_authenticator.h11
-rw-r--r--chrome/browser/chromeos/login/parallel_authenticator_unittest.cc11
-rw-r--r--chrome/browser/chromeos/login/screen_locker.cc5
-rw-r--r--chrome/browser/chromeos/login/user_manager_impl.cc72
-rw-r--r--chrome/browser/chromeos/login/user_manager_impl.h14
-rw-r--r--chrome/browser/chromeos/login/wizard_controller.cc1
-rw-r--r--chrome/browser/chromeos/settings/cros_settings.cc173
-rw-r--r--chrome/browser/chromeos/settings/cros_settings.h18
-rw-r--r--chrome/browser/chromeos/settings/cros_settings_provider.h3
-rw-r--r--chrome/browser/chromeos/settings/cros_settings_unittest.cc81
-rw-r--r--chrome/browser/chromeos/settings/device_settings_cache.cc59
-rw-r--r--chrome/browser/chromeos/settings/device_settings_provider.cc415
-rw-r--r--chrome/browser/chromeos/settings/device_settings_provider.h121
-rw-r--r--chrome/browser/chromeos/settings/device_settings_provider_unittest.cc242
-rw-r--r--chrome/browser/chromeos/settings/owner_manager.cc2
-rw-r--r--chrome/browser/chromeos/settings/session_manager_observer.cc4
-rw-r--r--chrome/browser/chromeos/settings/signed_settings_cache.cc133
-rw-r--r--chrome/browser/chromeos/settings/signed_settings_cache.h (renamed from chrome/browser/chromeos/settings/device_settings_cache.h)22
-rw-r--r--chrome/browser/chromeos/settings/signed_settings_cache_unittest.cc (renamed from chrome/browser/chromeos/settings/device_settings_cache_unittest.cc)20
-rw-r--r--chrome/browser/chromeos/settings/signed_settings_migration_helper.cc66
-rw-r--r--chrome/browser/chromeos/settings/signed_settings_migration_helper.h59
-rw-r--r--chrome/browser/chromeos/settings/stub_cros_settings_provider.cc3
-rw-r--r--chrome/browser/chromeos/settings/stub_cros_settings_provider.h1
-rw-r--r--chrome/browser/chromeos/settings/system_settings_provider.cc5
-rw-r--r--chrome/browser/chromeos/settings/system_settings_provider.h1
-rw-r--r--chrome/browser/policy/device_policy_cache.cc168
-rw-r--r--chrome/browser/policy/device_policy_cache.h36
-rw-r--r--chrome/browser/policy/device_policy_cache_unittest.cc309
-rw-r--r--chrome/browser/prefs/browser_prefs.cc4
43 files changed, 1396 insertions, 914 deletions
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index a03b156..0a8a01c 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -50,8 +50,8 @@
#include "chrome/browser/chromeos/power/screen_lock_observer.h"
#include "chrome/browser/chromeos/power/user_activity_notifier.h"
#include "chrome/browser/chromeos/power/video_activity_notifier.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/chromeos/settings/owner_key_util.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
+#include "chrome/browser/chromeos/settings/session_manager_observer.h"
#include "chrome/browser/chromeos/system/statistics_provider.h"
#include "chrome/browser/chromeos/system_key_event_listener.h"
#include "chrome/browser/chromeos/upgrade_detector_chromeos.h"
@@ -294,11 +294,9 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() {
chromeos::CrosDBusService::Initialize();
- // Initialize the device settings service so that we'll take actions per
- // signals sent from the session manager.
- chromeos::DeviceSettingsService::Get()->Initialize(
- chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
- chromeos::OwnerKeyUtil::Create());
+ // Initialize the session manager observer so that we'll take actions
+ // per signals sent from the session manager.
+ session_manager_observer_.reset(new chromeos::SessionManagerObserver);
chromeos::disks::DiskMountManager::Initialize();
chromeos::mtp::MediaTransferProtocolManager::Initialize();
@@ -351,7 +349,7 @@ void ChromeBrowserMainPartsChromeos::PreProfileInit() {
chromeos::BootTimesLoader::Get()->RecordChromeMainStats();
// Trigger prefetching of ownership status.
- chromeos::DeviceSettingsService::Get()->Load();
+ chromeos::OwnershipService::GetSharedInstance()->Prewarm();
// -- This used to be in ChromeBrowserMainParts::PreMainMessageLoopRun()
// -- just before CreateProfile().
@@ -522,11 +520,9 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopRun() {
if (chromeos::CrosNetworkChangeNotifierFactory::GetInstance())
chromeos::CrosNetworkChangeNotifierFactory::GetInstance()->Shutdown();
- // Tell DeviceSettingsService to stop talking to session_manager.
- chromeos::DeviceSettingsService::Get()->Shutdown();
-
// We should remove observers attached to D-Bus clients before
// DBusThreadManager is shut down.
+ session_manager_observer_.reset();
screen_lock_observer_.reset();
resume_observer_.reset();
brightness_observer_.reset();
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
index cb0ddd1..c4df57e 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -62,6 +62,7 @@ class ChromeBrowserMainPartsChromeos : public ChromeBrowserMainPartsLinux {
scoped_ptr<chromeos::OutputObserver> output_observer_;
scoped_ptr<chromeos::ResumeObserver> resume_observer_;
scoped_ptr<chromeos::ScreenLockObserver> screen_lock_observer_;
+ scoped_ptr<chromeos::SessionManagerObserver> session_manager_observer_;
scoped_ptr<chromeos::PowerButtonObserver> power_button_observer_;
scoped_ptr<chromeos::PowerStateOverride> power_state_override_;
scoped_ptr<chromeos::UserActivityNotifier> user_activity_notifier_;
diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc
index f0c8fc6..da3331c8 100644
--- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc
+++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_idle_logout_unittest.cc
@@ -10,7 +10,6 @@
#include "base/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
#include "chrome/common/chrome_notification_types.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "content/public/browser/browser_thread.h"
@@ -57,8 +56,6 @@ class KioskModeIdleLogoutTest : public ash::test::AshTestBase {
content::TestBrowserThread ui_thread_;
- ScopedDeviceSettingsTestHelper device_settings_test_helper_;
-
KioskModeIdleLogout* idle_logout_;
content::NotificationRegistrar registrar_;
};
diff --git a/chrome/browser/chromeos/locale_change_guard.cc b/chrome/browser/chromeos/locale_change_guard.cc
index fe076b4..6687dad 100644
--- a/chrome/browser/chromeos/locale_change_guard.cc
+++ b/chrome/browser/chromeos/locale_change_guard.cc
@@ -12,7 +12,7 @@
#include "base/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/notifications/notification_delegate.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
@@ -60,7 +60,7 @@ LocaleChangeGuard::LocaleChangeGuard(Profile* profile)
note_(NULL),
reverted_(false) {
DCHECK(profile_);
- registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
+ registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_CHECKED,
content::NotificationService::AllSources());
}
@@ -112,8 +112,8 @@ void LocaleChangeGuard::Observe(int type,
}
break;
}
- case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED: {
- if (DeviceSettingsService::Get()->HasPrivateOwnerKey()) {
+ case chrome::NOTIFICATION_OWNERSHIP_CHECKED: {
+ if (UserManager::Get()->IsCurrentUserOwner()) {
PrefService* local_state = g_browser_process->local_state();
if (local_state) {
PrefService* prefs = profile_->GetPrefs();
diff --git a/chrome/browser/chromeos/login/base_login_display_host.cc b/chrome/browser/chromeos/login/base_login_display_host.cc
index 5d70c27..964e09f 100644
--- a/chrome/browser/chromeos/login/base_login_display_host.cc
+++ b/chrome/browser/chromeos/login/base_login_display_host.cc
@@ -262,7 +262,7 @@ void BaseLoginDisplayHost::CheckForAutoEnrollment() {
// Start by checking if the device has already been owned.
pointer_factory_.InvalidateWeakPtrs();
- DeviceSettingsService::Get()->GetOwnershipStatusAsync(
+ OwnershipService::GetSharedInstance()->GetStatusAsync(
base::Bind(&BaseLoginDisplayHost::OnOwnershipStatusCheckDone,
pointer_factory_.GetWeakPtr()));
}
@@ -407,9 +407,9 @@ void BaseLoginDisplayHost::StartAnimation() {
}
void BaseLoginDisplayHost::OnOwnershipStatusCheckDone(
- DeviceSettingsService::OwnershipStatus status,
+ OwnershipService::Status status,
bool current_user_is_owner) {
- if (status != DeviceSettingsService::OWNERSHIP_NONE) {
+ if (status != OwnershipService::OWNERSHIP_NONE) {
// The device is already owned. No need for auto-enrollment checks.
VLOG(1) << "CheckForAutoEnrollment: device already owned";
return;
diff --git a/chrome/browser/chromeos/login/base_login_display_host.h b/chrome/browser/chromeos/login/base_login_display_host.h
index 453e408..ea9300c 100644
--- a/chrome/browser/chromeos/login/base_login_display_host.h
+++ b/chrome/browser/chromeos/login/base_login_display_host.h
@@ -12,7 +12,7 @@
#include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/login/login_display.h"
#include "chrome/browser/chromeos/login/login_display_host.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/gfx/rect.h"
@@ -74,8 +74,8 @@ class BaseLoginDisplayHost : public LoginDisplayHost,
// Start sign in transition animation.
void StartAnimation();
- // Callback for the ownership status check.
- void OnOwnershipStatusCheckDone(DeviceSettingsService::OwnershipStatus status,
+ // Callback for completion of the |ownership_status_checker_|.
+ void OnOwnershipStatusCheckDone(OwnershipService::Status status,
bool current_user_is_owner);
// Callback for completion of the |auto_enrollment_client_|.
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index 40da2ca..1662ff7 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -229,11 +229,10 @@ void ExistingUserController::Observe(
}
if (type == chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED ||
type == chrome::NOTIFICATION_POLICY_USER_LIST_CHANGED) {
- if (host_ != NULL) {
- // Signed settings or user list changed. Notify views and update them.
- UpdateLoginDisplay(chromeos::UserManager::Get()->GetUsers());
- return;
- }
+ // Signed settings or user list changed. Notify views and update them.
+ const chromeos::UserList& users = chromeos::UserManager::Get()->GetUsers();
+ UpdateLoginDisplay(users);
+ return;
}
if (type == chrome::NOTIFICATION_AUTH_SUPPLIED) {
// Possibly the user has authenticated against a proxy server and we might
@@ -340,10 +339,22 @@ void ExistingUserController::CompleteLoginInternal(std::string username,
std::string password) {
resume_login_callback_.Reset();
- DeviceSettingsService::Get()->GetOwnershipStatusAsync(
- base::Bind(&ExistingUserController::PerformLogin,
- weak_factory_.GetWeakPtr(), username, password,
- LoginPerformer::AUTH_MODE_EXTENSION));
+ if (!login_performer_.get()) {
+ LoginPerformer::Delegate* delegate = this;
+ if (login_performer_delegate_.get())
+ delegate = login_performer_delegate_.get();
+ // Only one instance of LoginPerformer should exist at a time.
+ login_performer_.reset(new LoginPerformer(delegate));
+ }
+
+ // If the device is not owned yet, successfully logged in user will be owner.
+ is_owner_login_ = OwnershipService::GetSharedInstance()->GetStatus(true) ==
+ OwnershipService::OWNERSHIP_NONE;
+
+ is_login_in_progress_ = true;
+ login_performer_->CompleteLogin(username, password);
+ accessibility::MaybeSpeak(
+ l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNING_IN));
}
void ExistingUserController::Login(const std::string& username,
@@ -353,6 +364,10 @@ void ExistingUserController::Login(const std::string& username,
// Disable clicking on other windows.
login_display_->SetUIEnabled(false);
+ // If the device is not owned yet, successfully logged in user will be owner.
+ is_owner_login_ = OwnershipService::GetSharedInstance()->GetStatus(true) ==
+ OwnershipService::OWNERSHIP_NONE;
+
BootTimesLoader::Get()->RecordLoginAttempted();
if (last_login_attempt_username_ != username) {
@@ -364,21 +379,6 @@ void ExistingUserController::Login(const std::string& username,
}
num_login_attempts_++;
- DeviceSettingsService::Get()->GetOwnershipStatusAsync(
- base::Bind(&ExistingUserController::PerformLogin,
- weak_factory_.GetWeakPtr(), username, password,
- LoginPerformer::AUTH_MODE_INTERNAL));
-}
-
-void ExistingUserController::PerformLogin(
- const std::string& username,
- const std::string& password,
- LoginPerformer::AuthorizationMode auth_mode,
- DeviceSettingsService::OwnershipStatus ownership_status,
- bool is_owner) {
- // If the device is not owned yet, successfully logged in user will be owner.
- is_owner_login_ = ownership_status == DeviceSettingsService::OWNERSHIP_NONE;
-
// Use the same LoginPerformer for subsequent login as it has state
// such as Authenticator instance.
if (!login_performer_.get() || num_login_attempts_ <= 1) {
@@ -389,9 +389,8 @@ void ExistingUserController::PerformLogin(
login_performer_.reset(NULL);
login_performer_.reset(new LoginPerformer(delegate));
}
-
is_login_in_progress_ = true;
- login_performer_->PerformLogin(username, password, auth_mode);
+ login_performer_->Login(username, password);
accessibility::MaybeSpeak(
l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNING_IN));
}
@@ -466,17 +465,17 @@ void ExistingUserController::OnUserSelected(const std::string& username) {
}
void ExistingUserController::OnStartEnterpriseEnrollment() {
- DeviceSettingsService::Get()->GetOwnershipStatusAsync(
+ OwnershipService::GetSharedInstance()->GetStatusAsync(
base::Bind(&ExistingUserController::OnEnrollmentOwnershipCheckCompleted,
weak_factory_.GetWeakPtr()));
}
void ExistingUserController::OnEnrollmentOwnershipCheckCompleted(
- DeviceSettingsService::OwnershipStatus status,
+ OwnershipService::Status status,
bool current_user_is_owner) {
- if (status == DeviceSettingsService::OWNERSHIP_NONE) {
+ if (status == OwnershipService::OWNERSHIP_NONE) {
ShowEnrollmentScreen(false, std::string());
- } else if (status == DeviceSettingsService::OWNERSHIP_TAKEN) {
+ } else if (status == OwnershipService::OWNERSHIP_TAKEN) {
// On a device that is already owned we might want to allow users to
// re-enroll if the policy information is invalid.
CrosSettingsProvider::TrustedStatus trusted_status =
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h
index adfe116..1b62b09 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.h
+++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -20,7 +20,7 @@
#include "chrome/browser/chromeos/login/login_utils.h"
#include "chrome/browser/chromeos/login/password_changed_view.h"
#include "chrome/browser/chromeos/login/user.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "googleurl/src/gurl.h"
@@ -28,8 +28,8 @@
namespace chromeos {
-class CrosSettings;
class LoginDisplayHost;
+class CrosSettings;
// ExistingUserController is used to handle login when someone has
// already logged into the machine.
@@ -149,9 +149,8 @@ class ExistingUserController : public LoginDisplay::Delegate,
// Handles result of ownership check and starts enterprise enrollment if
// applicable.
- void OnEnrollmentOwnershipCheckCompleted(
- DeviceSettingsService::OwnershipStatus status,
- bool current_user_is_owner);
+ void OnEnrollmentOwnershipCheckCompleted(OwnershipService::Status status,
+ bool current_user_is_owner);
// Enters the enterprise enrollment screen. |forced| is true if this is the
// result of an auto-enrollment check, and the user shouldn't be able to
@@ -163,13 +162,6 @@ class ExistingUserController : public LoginDisplay::Delegate,
// has to be performed, and will resume once auto-enrollment completes.
void CompleteLoginInternal(std::string username, std::string password);
- // Creates |login_performer_| if necessary and calls login() on it.
- void PerformLogin(const std::string& username,
- const std::string& password,
- LoginPerformer::AuthorizationMode auth_mode,
- DeviceSettingsService::OwnershipStatus ownership_status,
- bool is_owner);
-
void set_login_performer_delegate(LoginPerformer::Delegate* d) {
login_performer_delegate_.reset(d);
}
diff --git a/chrome/browser/chromeos/login/language_switch_menu.cc b/chrome/browser/chromeos/login/language_switch_menu.cc
index 8312390..14d5335 100644
--- a/chrome/browser/chromeos/login/language_switch_menu.cc
+++ b/chrome/browser/chromeos/login/language_switch_menu.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/chromeos/input_method/input_method_util.h"
#include "chrome/browser/chromeos/login/language_list.h"
#include "chrome/browser/chromeos/login/screen_observer.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/pref_names.h"
#include "grit/generated_resources.h"
diff --git a/chrome/browser/chromeos/login/login_performer.cc b/chrome/browser/chromeos/login/login_performer.cc
index 169d6d4..7a364d7 100644
--- a/chrome/browser/chromeos/login/login_performer.cc
+++ b/chrome/browser/chromeos/login/login_performer.cc
@@ -258,10 +258,9 @@ void LoginPerformer::Observe(int type,
////////////////////////////////////////////////////////////////////////////////
// LoginPerformer, public:
-void LoginPerformer::PerformLogin(const std::string& username,
- const std::string& password,
- AuthorizationMode auth_mode) {
- auth_mode_ = auth_mode;
+void LoginPerformer::CompleteLogin(const std::string& username,
+ const std::string& password) {
+ auth_mode_ = AUTH_MODE_EXTENSION;
username_ = username;
password_ = password;
@@ -272,9 +271,9 @@ void LoginPerformer::PerformLogin(const std::string& username,
if (!ScreenLocker::default_screen_locker()) {
CrosSettingsProvider::TrustedStatus status =
cros_settings->PrepareTrustedValues(
- base::Bind(&LoginPerformer::PerformLogin,
+ base::Bind(&LoginPerformer::CompleteLogin,
weak_factory_.GetWeakPtr(),
- username, password, auth_mode));
+ username, password));
// Must not proceed without signature verification.
if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
if (delegate_)
@@ -292,14 +291,50 @@ void LoginPerformer::PerformLogin(const std::string& username,
bool is_whitelisted = LoginUtils::IsWhitelisted(
gaia::CanonicalizeEmail(username));
if (ScreenLocker::default_screen_locker() || is_whitelisted) {
- switch (auth_mode_) {
- case AUTH_MODE_EXTENSION:
- StartLoginCompletion();
- break;
- case AUTH_MODE_INTERNAL:
- StartAuthentication();
- break;
+ // Starts authentication if guest login is allowed or online auth pending.
+ StartLoginCompletion();
+ } else {
+ if (delegate_)
+ delegate_->WhiteListCheckFailed(username);
+ else
+ NOTREACHED();
+ }
+}
+
+void LoginPerformer::Login(const std::string& username,
+ const std::string& password) {
+ auth_mode_ = AUTH_MODE_INTERNAL;
+ username_ = username;
+ password_ = password;
+
+ CrosSettings* cros_settings = CrosSettings::Get();
+
+ // Whitelist check is always performed during initial login and
+ // should not be performed when ScreenLock is active (pending online auth).
+ if (!ScreenLocker::default_screen_locker()) {
+ CrosSettingsProvider::TrustedStatus status =
+ cros_settings->PrepareTrustedValues(
+ base::Bind(&LoginPerformer::Login,
+ weak_factory_.GetWeakPtr(),
+ username, password));
+ // Must not proceed without signature verification.
+ if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
+ if (delegate_)
+ delegate_->PolicyLoadFailed();
+ else
+ NOTREACHED();
+ return;
+ } else if (status != CrosSettingsProvider::TRUSTED) {
+ // Value of AllowNewUser setting is still not verified.
+ // Another attempt will be invoked after verification completion.
+ return;
}
+ }
+
+ bool is_whitelisted = LoginUtils::IsWhitelisted(username);
+ if (ScreenLocker::default_screen_locker() || is_whitelisted) {
+ // Starts authentication if guest login is allowed or online auth pending.
+ StartAuthentication();
} else {
if (delegate_)
delegate_->WhiteListCheckFailed(username);
diff --git a/chrome/browser/chromeos/login/login_performer.h b/chrome/browser/chromeos/login/login_performer.h
index db7611a..43da2a5 100644
--- a/chrome/browser/chromeos/login/login_performer.h
+++ b/chrome/browser/chromeos/login/login_performer.h
@@ -54,13 +54,6 @@ class LoginPerformer : public LoginStatusConsumer,
public content::NotificationObserver,
public OnlineAttemptHost::Delegate {
public:
- typedef enum AuthorizationMode {
- // Authorization performed internally by Chrome.
- AUTH_MODE_INTERNAL,
- // Authorization performed by an extension.
- AUTH_MODE_EXTENSION
- } AuthorizationMode;
-
// Delegate class to get notifications from the LoginPerformer.
class Delegate : public LoginStatusConsumer {
public:
@@ -91,12 +84,12 @@ class LoginPerformer : public LoginStatusConsumer,
virtual void OnOffTheRecordLoginSuccess() OVERRIDE;
virtual void OnPasswordChangeDetected() OVERRIDE;
- // Performs a login for |username| and |password|. If auth_mode is
- // AUTH_MODE_EXTENSION, there are no further auth checks, AUTH_MODE_INTERNAL
- // will perform auth checks.
- void PerformLogin(const std::string& username,
- const std::string& password,
- AuthorizationMode auth_mode);
+ // Completes login process that has already been authenticated with
+ // provided |username| and |password|.
+ void CompleteLogin(const std::string& username, const std::string& password);
+
+ // Performs login with the |username| and |password| specified.
+ void Login(const std::string& username, const std::string& password);
// Performs login for the demo user.
void LoginDemoUser();
@@ -134,6 +127,12 @@ class LoginPerformer : public LoginStatusConsumer,
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
+ typedef enum AuthorizationMode {
+ // Authorization performed internally by Chrome.
+ AUTH_MODE_INTERNAL,
+ // Authorization performed by an extension.
+ AUTH_MODE_EXTENSION
+ } AuthorizationMode;
AuthorizationMode auth_mode() const { return auth_mode_; }
protected:
diff --git a/chrome/browser/chromeos/login/login_utils.cc b/chrome/browser/chromeos/login/login_utils.cc
index 3b41805..52bd4be 100644
--- a/chrome/browser/chromeos/login/login_utils.cc
+++ b/chrome/browser/chromeos/login/login_utils.cc
@@ -44,6 +44,7 @@
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/net/chrome_url_request_context.h"
diff --git a/chrome/browser/chromeos/login/login_utils_browsertest.cc b/chrome/browser/chromeos/login/login_utils_browsertest.cc
index 97046c7..2c2ed0f 100644
--- a/chrome/browser/chromeos/login/login_utils_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_utils_browsertest.cc
@@ -17,7 +17,6 @@
#include "chrome/browser/chromeos/login/authenticator.h"
#include "chrome/browser/chromeos/login/login_status_consumer.h"
#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/predictor.h"
#include "chrome/browser/policy/browser_policy_connector.h"
@@ -288,10 +287,9 @@ class LoginUtilsTest : public testing::Test,
}
void PrepareProfile(const std::string& username) {
- ScopedDeviceSettingsTestHelper device_settings_test_helper;
- MockSessionManagerClient* session_manager_client =
+ MockSessionManagerClient* session_managed_client =
mock_dbus_thread_manager_.mock_session_manager_client();
- EXPECT_CALL(*session_manager_client, StartSession(_));
+ EXPECT_CALL(*session_managed_client, StartSession(_));
EXPECT_CALL(*cryptohome_, GetSystemSalt())
.WillRepeatedly(Return(std::string("stub_system_salt")));
EXPECT_CALL(*mock_async_method_caller_, AsyncMount(_, _, _, _))
@@ -305,7 +303,6 @@ class LoginUtilsTest : public testing::Test,
LoginUtils::Get()->PrepareProfile(username, std::string(), "password",
false, true, false, this);
- device_settings_test_helper.Flush();
RunAllPending();
}
diff --git a/chrome/browser/chromeos/login/parallel_authenticator.cc b/chrome/browser/chromeos/login/parallel_authenticator.cc
index 83a576d..9a59998 100644
--- a/chrome/browser/chromeos/login/parallel_authenticator.cc
+++ b/chrome/browser/chromeos/login/parallel_authenticator.cc
@@ -19,6 +19,7 @@
#include "chrome/browser/chromeos/login/login_status_consumer.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/net/gaia/gaia_auth_util.h"
@@ -200,6 +201,9 @@ ParallelAuthenticator::ParallelAuthenticator(LoginStatusConsumer* consumer)
using_oauth_(
!CommandLine::ForCurrentProcess()->HasSwitch(
switches::kSkipOAuthLogin)) {
+ // If not already owned, this is a no-op. If it is, this loads the owner's
+ // public key off of disk.
+ OwnershipService::GetSharedInstance()->StartLoadOwnerKeyAttempt();
}
void ParallelAuthenticator::AuthenticateToLogin(
@@ -218,8 +222,11 @@ void ParallelAuthenticator::AuthenticateToLogin(
login_token,
login_captcha,
!UserManager::Get()->IsKnownUser(canonicalized)));
- // Reset the verified flag.
- owner_is_verified_ = false;
+ {
+ // Reset the verified flag.
+ base::AutoLock for_this_block(owner_verified_lock_);
+ owner_is_verified_ = false;
+ }
const bool create_if_missing = false;
BrowserThread::PostTask(
@@ -250,9 +257,11 @@ void ParallelAuthenticator::CompleteLogin(Profile* profile,
password,
HashPassword(password),
!UserManager::Get()->IsKnownUser(canonicalized)));
-
- // Reset the verified flag.
- owner_is_verified_ = false;
+ {
+ // Reset the verified flag.
+ base::AutoLock for_this_block(owner_verified_lock_);
+ owner_is_verified_ = false;
+ }
const bool create_if_missing = false;
BrowserThread::PostTask(
@@ -406,6 +415,7 @@ void ParallelAuthenticator::ResyncEncryptedData() {
}
bool ParallelAuthenticator::VerifyOwner() {
+ base::AutoLock for_this_block(owner_verified_lock_);
if (owner_is_verified_)
return true;
// Check if policy data is fine and continue in safe mode if needed.
@@ -420,19 +430,21 @@ bool ParallelAuthenticator::VerifyOwner() {
// First we have to make sure the current user's cert store is available.
CrosLibrary::Get()->GetCertLibrary()->LoadKeyStore();
// Now we can continue reading the private key.
- DeviceSettingsService::Get()->SetUsername(current_state_->username);
- DeviceSettingsService::Get()->GetOwnershipStatusAsync(
- base::Bind(&ParallelAuthenticator::OnOwnershipChecked, this));
+ BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&ParallelAuthenticator::FinishVerifyOwnerOnFileThread, this));
return false;
}
-void ParallelAuthenticator::OnOwnershipChecked(
- DeviceSettingsService::OwnershipStatus status,
- bool is_owner) {
+void ParallelAuthenticator::FinishVerifyOwnerOnFileThread() {
+ base::AutoLock for_this_block(owner_verified_lock_);
// Now we can check if this user is the owner.
- user_can_login_ = is_owner;
+ user_can_login_ =
+ OwnershipService::GetSharedInstance()->IsCurrentUserOwner();
owner_is_verified_ = true;
- Resolve();
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&ParallelAuthenticator::Resolve, this));
}
void ParallelAuthenticator::RetryAuth(Profile* profile,
@@ -791,6 +803,7 @@ void ParallelAuthenticator::ResolveLoginCompletionStatus() {
void ParallelAuthenticator::SetOwnerState(bool owner_check_finished,
bool check_result) {
+ base::AutoLock for_this_block(owner_verified_lock_);
owner_is_verified_ = owner_check_finished;
user_can_login_ = check_result;
}
diff --git a/chrome/browser/chromeos/login/parallel_authenticator.h b/chrome/browser/chromeos/login/parallel_authenticator.h
index a7ab996..8f29a44 100644
--- a/chrome/browser/chromeos/login/parallel_authenticator.h
+++ b/chrome/browser/chromeos/login/parallel_authenticator.h
@@ -12,12 +12,11 @@
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
+#include "chrome/browser/chromeos/login/authenticator.h"
#include "chrome/browser/chromeos/login/auth_attempt_state.h"
#include "chrome/browser/chromeos/login/auth_attempt_state_resolver.h"
-#include "chrome/browser/chromeos/login/authenticator.h"
#include "chrome/browser/chromeos/login/online_attempt.h"
#include "chrome/browser/chromeos/login/test_attempt_state.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
#include "chrome/common/net/gaia/gaia_auth_consumer.h"
class LoginFailure;
@@ -220,9 +219,9 @@ class ParallelAuthenticator : public Authenticator,
// Returns true if the owner check has been successful or if it is not needed.
bool VerifyOwner();
- // Handles completion of the ownership check and continues login.
- void OnOwnershipChecked(DeviceSettingsService::OwnershipStatus status,
- bool is_owner);
+ // checks if the current mounted home contains the owner case and either
+ // continues or fails the log-in. Used for policy lost mitigation "safe-mode".
+ void FinishVerifyOwnerOnFileThread();
// Records OAuth1 access token verification failure for |user_account|.
void RecordOAuthCheckFailure(const std::string& user_account);
@@ -253,6 +252,8 @@ class ParallelAuthenticator : public Authenticator,
// of it.
bool owner_is_verified_;
bool user_can_login_;
+ // A lock for |owner_is_verified_| and |user_can_login_|.
+ base::Lock owner_verified_lock_;
// True if we use OAuth-based authentication flow.
bool using_oauth_;
diff --git a/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc b/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc
index 3b6bc70..4296fca2 100644
--- a/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc
+++ b/chrome/browser/chromeos/login/parallel_authenticator_unittest.cc
@@ -20,7 +20,6 @@
#include "chrome/browser/chromeos/login/mock_user_manager.h"
#include "chrome/browser/chromeos/login/test_attempt_state.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
#include "chrome/common/net/gaia/mock_url_fetcher_factory.h"
#include "chrome/test/base/testing_profile.h"
@@ -35,13 +34,13 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
+using content::BrowserThread;
using ::testing::AnyNumber;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::_;
-using content::BrowserThread;
namespace chromeos {
@@ -209,10 +208,8 @@ class ParallelAuthenticatorTest : public testing::Test {
std::string password_;
std::string hash_ascii_;
- ScopedDeviceSettingsTestHelper device_settings_test_helper_;
-
// Initializes / shuts down a stub CrosLibrary.
- ScopedStubCrosEnabler stub_cros_enabler_;
+ chromeos::ScopedStubCrosEnabler stub_cros_enabler_;
// Mocks, destroyed by CrosLibrary class.
MockCertLibrary* mock_cert_library_;
@@ -343,8 +340,8 @@ TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) {
EXPECT_EQ(ParallelAuthenticator::CONTINUE,
SetAndResolveState(auth_, state_.release()));
- // Let the owner verification run.
- device_settings_test_helper_.Flush();
+ // Let the owner verification run on the FILE thread...
+ message_loop_.RunAllPending();
// and test that the mount has succeeded.
state_.reset(new TestAttemptState(username_,
password_,
diff --git a/chrome/browser/chromeos/login/screen_locker.cc b/chrome/browser/chromeos/login/screen_locker.cc
index a9a8d4a..4ea2184 100644
--- a/chrome/browser/chromeos/login/screen_locker.cc
+++ b/chrome/browser/chromeos/login/screen_locker.cc
@@ -226,9 +226,8 @@ void ScreenLocker::Authenticate(const string16& password) {
// initial online login phase is still active.
if (LoginPerformer::default_performer()) {
DVLOG(1) << "Delegating authentication to LoginPerformer.";
- LoginPerformer::default_performer()->PerformLogin(
- user_.email(), UTF16ToUTF8(password),
- LoginPerformer::AUTH_MODE_INTERNAL);
+ LoginPerformer::default_performer()->Login(user_.email(),
+ UTF16ToUTF8(password));
} else {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
diff --git a/chrome/browser/chromeos/login/user_manager_impl.cc b/chrome/browser/chromeos/login/user_manager_impl.cc
index 33d4ae8..a06c0d9 100644
--- a/chrome/browser/chromeos/login/user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/user_manager_impl.cc
@@ -34,6 +34,7 @@
#include "chrome/browser/chromeos/login/user_image.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
@@ -202,7 +203,7 @@ UserManagerImpl::UserManagerImpl()
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
MigrateWallpaperData();
- registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
+ registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED,
content::NotificationService::AllSources());
registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
content::NotificationService::AllSources());
@@ -211,7 +212,7 @@ UserManagerImpl::UserManagerImpl()
UserManagerImpl::~UserManagerImpl() {
// Can't use STLDeleteElements because of the private destructor of User.
- for (size_t i = 0; i < users_.size(); ++i)
+ for (size_t i = 0; i < users_.size();++i)
delete users_[i];
users_.clear();
if (is_current_user_ephemeral_)
@@ -584,9 +585,13 @@ void UserManagerImpl::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
switch (type) {
- case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
- CheckOwnership();
- RetrieveTrustedDevicePolicies();
+ case chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED:
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&UserManagerImpl::CheckOwnership,
+ base::Unretained(this)));
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
+ base::Unretained(this)));
break;
case chrome::NOTIFICATION_PROFILE_ADDED:
if (IsUserLoggedIn() && !IsLoggedInAsGuest()) {
@@ -613,13 +618,13 @@ void UserManagerImpl::OnStateChanged() {
state != AuthError::CONNECTION_FAILED &&
state != AuthError::SERVICE_UNAVAILABLE &&
state != AuthError::REQUEST_CANCELED) {
- // Invalidate OAuth token to force Gaia sign-in flow. This is needed
- // because sign-out/sign-in solution is suggested to the user.
- // TODO(altimofeev): this code isn't needed after crosbug.com/25978 is
- // implemented.
- DVLOG(1) << "Invalidate OAuth token because of a sync error.";
- SaveUserOAuthStatus(GetLoggedInUser().email(),
- User::OAUTH_TOKEN_STATUS_INVALID);
+ // Invalidate OAuth token to force Gaia sign-in flow. This is needed
+ // because sign-out/sign-in solution is suggested to the user.
+ // TODO(altimofeev): this code isn't needed after crosbug.com/25978 is
+ // implemented.
+ DVLOG(1) << "Invalidate OAuth token because of a sync error.";
+ SaveUserOAuthStatus(GetLoggedInUser().email(),
+ User::OAUTH_TOKEN_STATUS_INVALID);
}
}
@@ -693,12 +698,12 @@ bool UserManagerImpl::IsEphemeralUser(const std::string& email) const {
HasSwitch(switches::kLoginManager));
}
-void UserManagerImpl::AddObserver(UserManager::Observer* obs) {
+void UserManagerImpl::AddObserver(Observer* obs) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
observer_list_.AddObserver(obs);
}
-void UserManagerImpl::RemoveObserver(UserManager::Observer* obs) {
+void UserManagerImpl::RemoveObserver(Observer* obs) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
observer_list_.RemoveObserver(obs);
}
@@ -710,8 +715,10 @@ const gfx::ImageSkia& UserManagerImpl::DownloadedProfileImage() const {
void UserManagerImpl::NotifyLocalStateChanged() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
- LocalStateChanged(this));
+ FOR_EACH_OBSERVER(
+ Observer,
+ observer_list_,
+ LocalStateChanged(this));
}
FilePath UserManagerImpl::GetImagePathForUser(const std::string& username) {
@@ -888,9 +895,10 @@ void UserManagerImpl::NotifyOnLogin() {
CrosLibrary::Get()->GetCertLibrary()->LoadKeyStore();
- // Indicate to DeviceSettingsService that the owner key may have become
- // available.
- DeviceSettingsService::Get()->SetUsername(logged_in_user_->email());
+ // Schedules current user ownership check on file thread.
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ base::Bind(&UserManagerImpl::CheckOwnership,
+ base::Unretained(this)));
}
void UserManagerImpl::SetInitialUserImage(const std::string& username) {
@@ -1147,18 +1155,32 @@ void UserManagerImpl::DeleteUserImage(const FilePath& image_path) {
}
}
-void UserManagerImpl::UpdateOwnership(
- DeviceSettingsService::OwnershipStatus status,
- bool is_owner) {
- VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
+void UserManagerImpl::UpdateOwnership(bool is_owner) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
SetCurrentUserIsOwner(is_owner);
+ content::NotificationService::current()->Notify(
+ chrome::NOTIFICATION_OWNERSHIP_CHECKED,
+ content::NotificationService::AllSources(),
+ content::NotificationService::NoDetails());
+ if (is_owner) {
+ // Also update cached value.
+ CrosSettings::Get()->SetString(kDeviceOwner, GetLoggedInUser().email());
+ }
}
void UserManagerImpl::CheckOwnership() {
- DeviceSettingsService::Get()->GetOwnershipStatusAsync(
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ bool is_owner = OwnershipService::GetSharedInstance()->IsCurrentUserOwner();
+ VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
+
+ // UserManagerImpl should be accessed only on UI thread.
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
base::Bind(&UserManagerImpl::UpdateOwnership,
- base::Unretained(this)));
+ base::Unretained(this),
+ is_owner));
}
// ProfileDownloaderDelegate override.
diff --git a/chrome/browser/chromeos/login/user_manager_impl.h b/chrome/browser/chromeos/login/user_manager_impl.h
index 3aec437..7ba782c 100644
--- a/chrome/browser/chromeos/login/user_manager_impl.h
+++ b/chrome/browser/chromeos/login/user_manager_impl.h
@@ -20,18 +20,17 @@
#include "chrome/browser/chromeos/login/user_image_loader.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/login/wallpaper_manager.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
#include "chrome/browser/profiles/profile_downloader_delegate.h"
#include "chrome/browser/sync/profile_sync_service_observer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/gfx/image/image_skia.h"
+class SkBitmap;
class FilePath;
class PrefService;
class ProfileDownloader;
class ProfileSyncService;
-class SkBitmap;
namespace chromeos {
@@ -94,8 +93,8 @@ class UserManagerImpl : public UserManager,
virtual bool IsLoggedInAsStub() const OVERRIDE;
virtual bool IsSessionStarted() const OVERRIDE;
virtual bool IsEphemeralUser(const std::string& email) const OVERRIDE;
- virtual void AddObserver(UserManager::Observer* obs) OVERRIDE;
- virtual void RemoveObserver(UserManager::Observer* obs) OVERRIDE;
+ virtual void AddObserver(Observer* obs) OVERRIDE;
+ virtual void RemoveObserver(Observer* obs) OVERRIDE;
virtual void NotifyLocalStateChanged() OVERRIDE;
virtual const gfx::ImageSkia& DownloadedProfileImage() const OVERRIDE;
@@ -214,10 +213,9 @@ class UserManagerImpl : public UserManager,
void DeleteUserImage(const FilePath& image_path);
// Updates current user ownership on UI thread.
- void UpdateOwnership(DeviceSettingsService::OwnershipStatus status,
- bool is_owner);
+ void UpdateOwnership(bool is_owner);
- // Triggers an asynchronous ownership check.
+ // Checks current user's ownership on file thread.
void CheckOwnership();
// ProfileDownloaderDelegate implementation.
@@ -283,7 +281,7 @@ class UserManagerImpl : public UserManager,
// service, so do NOT use it outside |OnStateChanged| method.
ProfileSyncService* observed_sync_service_;
- ObserverList<UserManager::Observer> observer_list_;
+ ObserverList<Observer> observer_list_;
// Download user profile image on login to update it if it's changed.
scoped_ptr<ProfileDownloader> profile_image_downloader_;
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index 53a9b00..8a08f07 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -43,7 +43,6 @@
#include "chrome/browser/ui/options/options_util.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/pref_names.h"
-#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "ui/base/accelerators/accelerator.h"
diff --git a/chrome/browser/chromeos/settings/cros_settings.cc b/chrome/browser/chromeos/settings/cros_settings.cc
index f0592f3..a0622b4 100644
--- a/chrome/browser/chromeos/settings/cros_settings.cc
+++ b/chrome/browser/chromeos/settings/cros_settings.cc
@@ -11,7 +11,7 @@
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/browser/chromeos/settings/device_settings_provider.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chrome/browser/chromeos/settings/signed_settings_helper.h"
#include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
#include "chrome/browser/chromeos/settings/system_settings_provider.h"
#include "chrome/common/chrome_notification_types.h"
@@ -35,6 +35,22 @@ bool CrosSettings::IsCrosSettings(const std::string& path) {
return StartsWithASCII(path, kCrosSettingsPrefix, true);
}
+void CrosSettings::FireObservers(const std::string& path) {
+ DCHECK(CalledOnValidThread());
+ SettingsObserverMap::iterator observer_iterator =
+ settings_observers_.find(path);
+ if (observer_iterator == settings_observers_.end())
+ return;
+
+ NotificationObserverList::Iterator it(*(observer_iterator->second));
+ content::NotificationObserver* observer;
+ while ((observer = it.GetNext()) != NULL) {
+ observer->Observe(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED,
+ content::Source<CrosSettings>(this),
+ content::Details<const std::string>(&path));
+ }
+}
+
void CrosSettings::Set(const std::string& path, const base::Value& in_value) {
DCHECK(CalledOnValidThread());
CrosSettingsProvider* provider;
@@ -43,27 +59,6 @@ void CrosSettings::Set(const std::string& path, const base::Value& in_value) {
provider->Set(path, in_value);
}
-const base::Value* CrosSettings::GetPref(const std::string& path) const {
- DCHECK(CalledOnValidThread());
- CrosSettingsProvider* provider = GetProvider(path);
- if (provider)
- return provider->Get(path);
- NOTREACHED() << path << " preference was not found in the signed settings.";
- return NULL;
-}
-
-CrosSettingsProvider::TrustedStatus CrosSettings::PrepareTrustedValues(
- const base::Closure& callback) const {
- DCHECK(CalledOnValidThread());
- for (size_t i = 0; i < providers_.size(); ++i) {
- CrosSettingsProvider::TrustedStatus status =
- providers_[i]->PrepareTrustedValues(callback);
- if (status != CrosSettingsProvider::TRUSTED)
- return status;
- }
- return CrosSettingsProvider::TRUSTED;
-}
-
void CrosSettings::SetBoolean(const std::string& path, bool in_value) {
DCHECK(CalledOnValidThread());
base::FundamentalValue value(in_value);
@@ -109,51 +104,6 @@ void CrosSettings::RemoveFromList(const std::string& path,
Set(path, *new_value);
}
-bool CrosSettings::GetBoolean(const std::string& path,
- bool* bool_value) const {
- DCHECK(CalledOnValidThread());
- const base::Value* value = GetPref(path);
- if (value)
- return value->GetAsBoolean(bool_value);
- return false;
-}
-
-bool CrosSettings::GetInteger(const std::string& path,
- int* out_value) const {
- DCHECK(CalledOnValidThread());
- const base::Value* value = GetPref(path);
- if (value)
- return value->GetAsInteger(out_value);
- return false;
-}
-
-bool CrosSettings::GetDouble(const std::string& path,
- double* out_value) const {
- DCHECK(CalledOnValidThread());
- const base::Value* value = GetPref(path);
- if (value)
- return value->GetAsDouble(out_value);
- return false;
-}
-
-bool CrosSettings::GetString(const std::string& path,
- std::string* out_value) const {
- DCHECK(CalledOnValidThread());
- const base::Value* value = GetPref(path);
- if (value)
- return value->GetAsString(out_value);
- return false;
-}
-
-bool CrosSettings::GetList(const std::string& path,
- const base::ListValue** out_value) const {
- DCHECK(CalledOnValidThread());
- const base::Value* value = GetPref(path);
- if (value)
- return value->GetAsList(out_value);
- return false;
-}
-
bool CrosSettings::FindEmailInList(const std::string& path,
const std::string& email) const {
DCHECK(CalledOnValidThread());
@@ -270,6 +220,77 @@ CrosSettingsProvider* CrosSettings::GetProvider(
return NULL;
}
+void CrosSettings::ReloadProviders() {
+ for (size_t i = 0; i < providers_.size(); ++i)
+ providers_[i]->Reload();
+}
+
+const base::Value* CrosSettings::GetPref(const std::string& path) const {
+ DCHECK(CalledOnValidThread());
+ CrosSettingsProvider* provider = GetProvider(path);
+ if (provider)
+ return provider->Get(path);
+ NOTREACHED() << path << " preference was not found in the signed settings.";
+ return NULL;
+}
+
+CrosSettingsProvider::TrustedStatus CrosSettings::PrepareTrustedValues(
+ const base::Closure& callback) const {
+ DCHECK(CalledOnValidThread());
+ for (size_t i = 0; i < providers_.size(); ++i) {
+ CrosSettingsProvider::TrustedStatus status =
+ providers_[i]->PrepareTrustedValues(callback);
+ if (status != CrosSettingsProvider::TRUSTED)
+ return status;
+ }
+ return CrosSettingsProvider::TRUSTED;
+}
+
+bool CrosSettings::GetBoolean(const std::string& path,
+ bool* bool_value) const {
+ DCHECK(CalledOnValidThread());
+ const base::Value* value = GetPref(path);
+ if (value)
+ return value->GetAsBoolean(bool_value);
+ return false;
+}
+
+bool CrosSettings::GetInteger(const std::string& path,
+ int* out_value) const {
+ DCHECK(CalledOnValidThread());
+ const base::Value* value = GetPref(path);
+ if (value)
+ return value->GetAsInteger(out_value);
+ return false;
+}
+
+bool CrosSettings::GetDouble(const std::string& path,
+ double* out_value) const {
+ DCHECK(CalledOnValidThread());
+ const base::Value* value = GetPref(path);
+ if (value)
+ return value->GetAsDouble(out_value);
+ return false;
+}
+
+bool CrosSettings::GetString(const std::string& path,
+ std::string* out_value) const {
+ DCHECK(CalledOnValidThread());
+ const base::Value* value = GetPref(path);
+ if (value)
+ return value->GetAsString(out_value);
+ return false;
+}
+
+bool CrosSettings::GetList(const std::string& path,
+ const base::ListValue** out_value) const {
+ DCHECK(CalledOnValidThread());
+ const base::Value* value = GetPref(path);
+ if (value)
+ return value->GetAsList(out_value);
+ return false;
+}
+
CrosSettings::CrosSettings() {
CrosSettingsProvider::NotifyObserversCallback notify_cb(
base::Bind(&CrosSettings::FireObservers,
@@ -280,7 +301,7 @@ CrosSettings::CrosSettings() {
AddSettingsProvider(new StubCrosSettingsProvider(notify_cb));
} else {
AddSettingsProvider(
- new DeviceSettingsProvider(notify_cb, DeviceSettingsService::Get()));
+ new DeviceSettingsProvider(notify_cb, SignedSettingsHelper::Get()));
}
// System settings are not mocked currently.
AddSettingsProvider(new SystemSettingsProvider(notify_cb));
@@ -291,20 +312,4 @@ CrosSettings::~CrosSettings() {
STLDeleteValues(&settings_observers_);
}
-void CrosSettings::FireObservers(const std::string& path) {
- DCHECK(CalledOnValidThread());
- SettingsObserverMap::iterator observer_iterator =
- settings_observers_.find(path);
- if (observer_iterator == settings_observers_.end())
- return;
-
- NotificationObserverList::Iterator it(*(observer_iterator->second));
- content::NotificationObserver* observer;
- while ((observer = it.GetNext()) != NULL) {
- observer->Observe(chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED,
- content::Source<CrosSettings>(this),
- content::Details<const std::string>(&path));
- }
-}
-
} // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/cros_settings.h b/chrome/browser/chromeos/settings/cros_settings.h
index 4148ee6..128184c 100644
--- a/chrome/browser/chromeos/settings/cros_settings.h
+++ b/chrome/browser/chromeos/settings/cros_settings.h
@@ -91,16 +91,12 @@ class CrosSettings : public base::NonThreadSafe {
// Returns the provider that handles settings with the |path| or prefix.
CrosSettingsProvider* GetProvider(const std::string& path) const;
+ // Forces all providers to reload their caches from the respective backing
+ // stores if they have any.
+ void ReloadProviders();
+
private:
friend struct base::DefaultLazyInstanceTraits<CrosSettings>;
- friend class CrosSettingsTest;
-
- // Public for testing.
- CrosSettings();
- ~CrosSettings();
-
- // Fires system setting change notification.
- void FireObservers(const std::string& path);
// List of ChromeOS system settings providers.
std::vector<CrosSettingsProvider*> providers_;
@@ -113,6 +109,12 @@ class CrosSettings : public base::NonThreadSafe {
SettingsObserverMap;
SettingsObserverMap settings_observers_;
+ CrosSettings();
+ ~CrosSettings();
+
+ // Fires system setting change notification.
+ void FireObservers(const std::string& path);
+
DISALLOW_COPY_AND_ASSIGN(CrosSettings);
};
diff --git a/chrome/browser/chromeos/settings/cros_settings_provider.h b/chrome/browser/chromeos/settings/cros_settings_provider.h
index 6196555..2477f34 100644
--- a/chrome/browser/chromeos/settings/cros_settings_provider.h
+++ b/chrome/browser/chromeos/settings/cros_settings_provider.h
@@ -58,6 +58,9 @@ class CrosSettingsProvider {
// Gets the namespace prefix provided by this provider.
virtual bool HandlesSetting(const std::string& path) const = 0;
+ // Reloads the caches if the provider has any.
+ virtual void Reload() = 0;
+
void SetNotifyObserversCallback(const NotifyObserversCallback& notify_cb);
protected:
diff --git a/chrome/browser/chromeos/settings/cros_settings_unittest.cc b/chrome/browser/chromeos/settings/cros_settings_unittest.cc
index e3fc928..f5fb133 100644
--- a/chrome/browser/chromeos/settings/cros_settings_unittest.cc
+++ b/chrome/browser/chromeos/settings/cros_settings_unittest.cc
@@ -2,19 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "chrome/browser/chromeos/settings/signed_settings.h"
+
#include <map>
#include <string>
#include "base/bind.h"
-#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop.h"
#include "base/stl_util.h"
#include "base/values.h"
+#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/login/mock_user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
-#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
-#include "chrome/browser/policy/cloud_policy_constants.h"
+#include "chrome/browser/chromeos/settings/signed_settings_cache.h"
#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "chrome/test/base/testing_browser_process.h"
@@ -22,8 +24,10 @@
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
-namespace em = enterprise_management;
+using ::testing::AnyNumber;
+using ::testing::Return;
+namespace em = enterprise_management;
namespace chromeos {
class CrosSettingsTest : public testing::Test {
@@ -31,15 +35,28 @@ class CrosSettingsTest : public testing::Test {
CrosSettingsTest()
: message_loop_(MessageLoop::TYPE_UI),
ui_thread_(content::BrowserThread::UI, &message_loop_),
- local_state_(static_cast<TestingBrowserProcess*>(g_browser_process)),
- weak_factory_(this) {}
+ file_thread_(content::BrowserThread::FILE, &message_loop_),
+ pointer_factory_(this),
+ local_state_(static_cast<TestingBrowserProcess*>(g_browser_process)) {
+ }
- virtual ~CrosSettingsTest() {}
+ virtual ~CrosSettingsTest() {
+ }
+
+ virtual void SetUp() {
+ EXPECT_CALL(*mock_user_manager_.user_manager(), IsCurrentUserOwner())
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(true));
+ // Reset the cache between tests.
+ ApplyEmptyPolicy();
+ }
- virtual void TearDown() OVERRIDE {
+ virtual void TearDown() {
+ message_loop_.RunAllPending();
ASSERT_TRUE(expected_props_.empty());
+ // Reset the cache between tests.
+ ApplyEmptyPolicy();
STLDeleteValues(&expected_props_);
- expected_props_.clear();
}
void FetchPref(const std::string& pref) {
@@ -48,12 +65,12 @@ class CrosSettingsTest : public testing::Test {
return;
if (CrosSettingsProvider::TRUSTED ==
- settings_.PrepareTrustedValues(
- base::Bind(&CrosSettingsTest::FetchPref,
- weak_factory_.GetWeakPtr(), pref))) {
+ CrosSettings::Get()->PrepareTrustedValues(
+ base::Bind(&CrosSettingsTest::FetchPref,
+ pointer_factory_.GetWeakPtr(), pref))) {
scoped_ptr<base::Value> expected_value(
expected_props_.find(pref)->second);
- const base::Value* pref_value = settings_.GetPref(pref);
+ const base::Value* pref_value = CrosSettings::Get()->GetPref(pref);
if (expected_value.get()) {
ASSERT_TRUE(pref_value);
ASSERT_TRUE(expected_value->Equals(pref_value));
@@ -66,7 +83,7 @@ class CrosSettingsTest : public testing::Test {
void SetPref(const std::string& pref_name, const base::Value* value) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- settings_.Set(pref_name, *value);
+ CrosSettings::Get()->Set(pref_name, *value);
}
void AddExpectation(const std::string& pref_name, base::Value* value) {
@@ -79,7 +96,7 @@ class CrosSettingsTest : public testing::Test {
// Prepare some policy blob.
em::PolicyFetchResponse response;
em::ChromeDeviceSettingsProto pol;
- policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType);
+ policy->set_policy_type(chromeos::kDevicePolicyType);
policy->set_username("me@owner");
policy->set_policy_value(pol.SerializeAsString());
// Wipe the signed settings store.
@@ -87,16 +104,25 @@ class CrosSettingsTest : public testing::Test {
response.set_policy_data_signature("false");
}
+ void ApplyEmptyPolicy() {
+ em::PolicyData fake_pol;
+ PrepareEmptyPolicy(&fake_pol);
+ signed_settings_cache::Store(fake_pol, local_state_.Get());
+ CrosSettings::Get()->ReloadProviders();
+ }
+
+ std::map<std::string, base::Value*> expected_props_;
+
MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
+ content::TestBrowserThread file_thread_;
- ScopedTestingLocalState local_state_;
- ScopedDeviceSettingsTestHelper device_settings_test_helper_;
- CrosSettings settings_;
+ base::WeakPtrFactory<CrosSettingsTest> pointer_factory_;
- base::WeakPtrFactory<CrosSettingsTest> weak_factory_;
+ ScopedTestingLocalState local_state_;
- std::map<std::string, base::Value*> expected_props_;
+ ScopedMockUserManagerEnabler mock_user_manager_;
+ ScopedStubCrosEnabler stub_cros_enabler_;
};
TEST_F(CrosSettingsTest, SetPref) {
@@ -105,6 +131,7 @@ TEST_F(CrosSettingsTest, SetPref) {
base::Value::CreateBooleanValue(false));
SetPref(kAccountsPrefAllowGuest, expected_props_[kAccountsPrefAllowGuest]);
FetchPref(kAccountsPrefAllowGuest);
+ message_loop_.RunAllPending();
ASSERT_TRUE(expected_props_.empty());
}
@@ -136,7 +163,7 @@ TEST_F(CrosSettingsTest, SetWhitelistWithListOps) {
base::Value::CreateBooleanValue(false));
AddExpectation(kAccountsPrefUsers, whitelist);
// Add some user to the whitelist.
- settings_.AppendToList(kAccountsPrefUsers, &hacky_user);
+ CrosSettings::Get()->AppendToList(kAccountsPrefUsers, &hacky_user);
FetchPref(kAccountsPrefAllowNewUser);
FetchPref(kAccountsPrefUsers);
}
@@ -154,10 +181,11 @@ TEST_F(CrosSettingsTest, SetWhitelistWithListOps2) {
SetPref(kAccountsPrefUsers, &whitelist);
FetchPref(kAccountsPrefAllowNewUser);
FetchPref(kAccountsPrefUsers);
+ message_loop_.RunAllPending();
ASSERT_TRUE(expected_props_.empty());
// Now try to remove one element from that list.
AddExpectation(kAccountsPrefUsers, expected_list);
- settings_.RemoveFromList(kAccountsPrefUsers, &lamy_user);
+ CrosSettings::Get()->RemoveFromList(kAccountsPrefUsers, &lamy_user);
FetchPref(kAccountsPrefAllowNewUser);
FetchPref(kAccountsPrefUsers);
}
@@ -199,6 +227,13 @@ TEST_F(CrosSettingsTest, SetAllowNewUsers) {
FetchPref(kAccountsPrefAllowNewUser);
}
+TEST_F(CrosSettingsTest, SetOwner) {
+ base::StringValue hacky_owner("h@xxor");
+ AddExpectation(kDeviceOwner, base::Value::CreateStringValue("h@xxor"));
+ SetPref(kDeviceOwner, &hacky_owner);
+ FetchPref(kDeviceOwner);
+}
+
TEST_F(CrosSettingsTest, SetEphemeralUsersEnabled) {
base::FundamentalValue ephemeral_users_enabled(true);
AddExpectation(kAccountsPrefEphemeralUsersEnabled,
@@ -214,7 +249,7 @@ TEST_F(CrosSettingsTest, FindEmailInList) {
list.Append(base::Value::CreateStringValue("with.dots@gmail.com"));
list.Append(base::Value::CreateStringValue("Upper@example.com"));
- CrosSettings* cs = &settings_;
+ CrosSettings* cs = CrosSettings::Get();
cs->Set(kAccountsPrefUsers, list);
EXPECT_TRUE(cs->FindEmailInList(kAccountsPrefUsers, "user@example.com"));
diff --git a/chrome/browser/chromeos/settings/device_settings_cache.cc b/chrome/browser/chromeos/settings/device_settings_cache.cc
deleted file mode 100644
index 178cbfb..0000000
--- a/chrome/browser/chromeos/settings/device_settings_cache.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2012 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/chromeos/settings/device_settings_cache.h"
-
-#include <string>
-
-#include "base/base64.h"
-#include "base/bind.h"
-#include "chrome/browser/chromeos/settings/cros_settings.h"
-#include "chrome/browser/policy/proto/device_management_backend.pb.h"
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/common/pref_names.h"
-
-namespace em = enterprise_management;
-
-namespace chromeos {
-
-namespace device_settings_cache {
-
-void RegisterPrefs(PrefService* local_state) {
- local_state->RegisterStringPref(prefs::kDeviceSettingsCache,
- "invalid",
- PrefService::UNSYNCABLE_PREF);
-}
-
-bool Store(const em::PolicyData& policy, PrefService* local_state) {
- if (local_state) {
- std::string policy_string = policy.SerializeAsString();
- std::string encoded;
- if (!base::Base64Encode(policy_string, &encoded)) {
- LOG(ERROR) << "Can't encode policy in base64.";
- return false;
- }
- local_state->SetString(prefs::kDeviceSettingsCache, encoded);
- return true;
- }
- return false;
-}
-
-bool Retrieve(em::PolicyData *policy, PrefService* local_state) {
- if (local_state) {
- std::string encoded =
- local_state->GetString(prefs::kDeviceSettingsCache);
- std::string policy_string;
- if (!base::Base64Decode(encoded, &policy_string)) {
- // This is normal and happens on first boot.
- VLOG(1) << "Can't decode policy from base64.";
- return false;
- }
- return policy->ParseFromString(policy_string);
- }
- return false;
-}
-
-} // namespace device_settings_cache
-
-} // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc
index 1a6b56b..ed03b55 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -15,15 +15,19 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/network_library.h"
+#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
-#include "chrome/browser/chromeos/settings/device_settings_cache.h"
+#include "chrome/browser/chromeos/settings/signed_settings_cache.h"
+#include "chrome/browser/chromeos/settings/signed_settings_helper.h"
#include "chrome/browser/policy/app_pack_updater.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/cloud_policy_constants.h"
-#include "chrome/browser/policy/proto/device_management_backend.pb.h"
+#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
#include "chrome/browser/ui/options/options_util.h"
+#include "chrome/common/chrome_notification_types.h"
#include "chrome/installer/util/google_update_settings.h"
+#include "content/public/browser/notification_service.h"
using google::protobuf::RepeatedPtrField;
@@ -60,6 +64,9 @@ const char* kKnownSettings[] = {
kSystemTimezonePolicy,
};
+// Upper bound for number of retries to fetch a signed setting.
+static const int kNumRetriesLimit = 9;
+
// Legacy policy file location. Used to detect migration from pre v12 ChromeOS.
const char kLegacyPolicyFile[] = "/var/lib/whitelist/preferences";
@@ -81,30 +88,43 @@ bool HasOldMetricsFile() {
DeviceSettingsProvider::DeviceSettingsProvider(
const NotifyObserversCallback& notify_cb,
- DeviceSettingsService* device_settings_service)
+ SignedSettingsHelper* signed_settings_helper)
: CrosSettingsProvider(notify_cb),
- device_settings_service_(device_settings_service),
- trusted_status_(TEMPORARILY_UNTRUSTED),
- ownership_status_(device_settings_service_->GetOwnershipStatus()),
- ALLOW_THIS_IN_INITIALIZER_LIST(store_callback_factory_(this)) {
- device_settings_service_->AddObserver(this);
-
- if (!UpdateFromService()) {
- // Make sure we have at least the cache data immediately.
- RetrieveCachedData();
- }
+ signed_settings_helper_(signed_settings_helper),
+ ownership_status_(OwnershipService::GetSharedInstance()->GetStatus(true)),
+ migration_helper_(new SignedSettingsMigrationHelper()),
+ retries_left_(kNumRetriesLimit),
+ trusted_status_(TEMPORARILY_UNTRUSTED) {
+ // Register for notification when ownership is taken so that we can update
+ // the |ownership_status_| and reload if needed.
+ registrar_.Add(this, chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED,
+ content::NotificationService::AllSources());
+ // Make sure we have at least the cache data immediately.
+ RetrieveCachedData();
+ // Start prefetching preferences.
+ Reload();
}
DeviceSettingsProvider::~DeviceSettingsProvider() {
- device_settings_service_->RemoveObserver(this);
+}
+
+void DeviceSettingsProvider::Reload() {
+ // While fetching we can't trust the cache anymore.
+ trusted_status_ = TEMPORARILY_UNTRUSTED;
+ if (ownership_status_ == OwnershipService::OWNERSHIP_NONE) {
+ RetrieveCachedData();
+ } else {
+ // Retrieve the real data.
+ signed_settings_helper_->StartRetrievePolicyOp(
+ base::Bind(&DeviceSettingsProvider::OnRetrievePolicyCompleted,
+ base::Unretained(this)));
+ }
}
void DeviceSettingsProvider::DoSet(const std::string& path,
const base::Value& in_value) {
- // Make sure that either the current user is the device owner or the
- // device doesn't have an owner yet.
- if (!(device_settings_service_->HasPrivateOwnerKey() ||
- ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)) {
+ if (!UserManager::Get()->IsCurrentUserOwner() &&
+ ownership_status_ != OwnershipService::OWNERSHIP_NONE) {
LOG(WARNING) << "Changing settings from non-owner, setting=" << path;
// Revert UI change.
@@ -114,60 +134,43 @@ void DeviceSettingsProvider::DoSet(const std::string& path,
if (IsControlledSetting(path)) {
pending_changes_.push_back(PendingQueueElement(path, in_value.DeepCopy()));
- if (!store_callback_factory_.HasWeakPtrs())
+ if (pending_changes_.size() == 1)
SetInPolicy();
} else {
NOTREACHED() << "Try to set unhandled cros setting " << path;
}
}
-void DeviceSettingsProvider::OwnershipStatusChanged() {
- DeviceSettingsService::OwnershipStatus new_ownership_status =
- device_settings_service_->GetOwnershipStatus();
-
- // If the device just became owned, write the settings accumulated in the
- // cache to device settings proper. It is important that writing only happens
- // in this case, as during normal operation, the contents of the cache should
- // never overwrite actual device settings.
- if (new_ownership_status == DeviceSettingsService::OWNERSHIP_TAKEN &&
- ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE &&
- device_settings_service_->HasPrivateOwnerKey()) {
-
- // There shouldn't be any pending writes, since the cache writes are all
- // immediate.
- DCHECK(!store_callback_factory_.HasWeakPtrs());
-
- // Apply the locally-accumulated device settings on top of the initial
- // settings from the service and write back the result.
- if (device_settings_service_->device_settings()) {
- em::ChromeDeviceSettingsProto new_settings(
- *device_settings_service_->device_settings());
- new_settings.MergeFrom(device_settings_);
- device_settings_.Swap(&new_settings);
- }
- StoreDeviceSettings();
+void DeviceSettingsProvider::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ if (type == chrome::NOTIFICATION_OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED) {
+ // Reload the policy blob once the owner key has been loaded or updated.
+ ownership_status_ = OwnershipService::OWNERSHIP_TAKEN;
+ Reload();
}
-
- // The owner key might have become available, allowing migration to happen.
- AttemptMigration();
-
- ownership_status_ = new_ownership_status;
}
-void DeviceSettingsProvider::DeviceSettingsUpdated() {
- if (!store_callback_factory_.HasWeakPtrs())
- UpdateAndProceedStoring();
+const em::PolicyData DeviceSettingsProvider::policy() const {
+ return policy_;
}
void DeviceSettingsProvider::RetrieveCachedData() {
- em::PolicyData policy_data;
- if (!device_settings_cache::Retrieve(&policy_data,
- g_browser_process->local_state()) ||
- !device_settings_.ParseFromString(policy_data.policy_value())) {
- VLOG(1) << "Can't retrieve temp store, possibly not created yet.";
+ // If there is no owner yet, this function will pull the policy cache from the
+ // temp storage and use that instead.
+ em::PolicyData policy;
+ if (!signed_settings_cache::Retrieve(&policy,
+ g_browser_process->local_state())) {
+ VLOG(1) << "Can't retrieve temp store possibly not created yet.";
+ // Prepare empty data for the case we don't have temp cache yet.
+ policy.set_policy_type(kDevicePolicyType);
+ em::ChromeDeviceSettingsProto pol;
+ policy.set_policy_value(pol.SerializeAsString());
}
- UpdateValuesCache(policy_data, device_settings_);
+ policy_ = policy;
+ UpdateValuesCache();
}
void DeviceSettingsProvider::SetInPolicy() {
@@ -176,44 +179,62 @@ void DeviceSettingsProvider::SetInPolicy() {
return;
}
- if (RequestTrustedEntity() != TRUSTED) {
- // Re-sync device settings before proceeding.
- device_settings_service_->Load();
+ const std::string& prop = pending_changes_[0].first;
+ base::Value* value = pending_changes_[0].second;
+ if (prop == kDeviceOwner) {
+ // Just store it in the memory cache without trusted checks or persisting.
+ std::string owner;
+ if (value->GetAsString(&owner)) {
+ policy_.set_username(owner);
+ // In this case the |value_cache_| takes the ownership of |value|.
+ values_cache_.SetValue(prop, value);
+ NotifyObservers(prop);
+ // We can't trust this value anymore until we reload the real username.
+ trusted_status_ = TEMPORARILY_UNTRUSTED;
+ pending_changes_.erase(pending_changes_.begin());
+ if (!pending_changes_.empty())
+ SetInPolicy();
+ } else {
+ NOTREACHED();
+ }
return;
}
- std::string prop(pending_changes_.front().first);
- scoped_ptr<base::Value> value(pending_changes_.front().second);
- pending_changes_.pop_front();
+ if (RequestTrustedEntity() != TRUSTED) {
+ // Otherwise we should first reload and apply on top of that.
+ signed_settings_helper_->StartRetrievePolicyOp(
+ base::Bind(&DeviceSettingsProvider::FinishSetInPolicy,
+ base::Unretained(this)));
+ return;
+ }
trusted_status_ = TEMPORARILY_UNTRUSTED;
+ em::PolicyData data = policy();
+ em::ChromeDeviceSettingsProto pol;
+ pol.ParseFromString(data.policy_value());
if (prop == kAccountsPrefAllowNewUser) {
- em::AllowNewUsersProto* allow =
- device_settings_.mutable_allow_new_users();
+ em::AllowNewUsersProto* allow = pol.mutable_allow_new_users();
bool allow_value;
if (value->GetAsBoolean(&allow_value))
allow->set_allow_new_users(allow_value);
else
NOTREACHED();
} else if (prop == kAccountsPrefAllowGuest) {
- em::GuestModeEnabledProto* guest =
- device_settings_.mutable_guest_mode_enabled();
+ em::GuestModeEnabledProto* guest = pol.mutable_guest_mode_enabled();
bool guest_value;
if (value->GetAsBoolean(&guest_value))
guest->set_guest_mode_enabled(guest_value);
else
NOTREACHED();
} else if (prop == kAccountsPrefShowUserNamesOnSignIn) {
- em::ShowUserNamesOnSigninProto* show =
- device_settings_.mutable_show_user_names();
+ em::ShowUserNamesOnSigninProto* show = pol.mutable_show_user_names();
bool show_value;
if (value->GetAsBoolean(&show_value))
show->set_show_user_names(show_value);
else
NOTREACHED();
} else if (prop == kSignedDataRoamingEnabled) {
- em::DataRoamingEnabledProto* roam =
- device_settings_.mutable_data_roaming_enabled();
+ em::DataRoamingEnabledProto* roam = pol.mutable_data_roaming_enabled();
bool roaming_value = false;
if (value->GetAsBoolean(&roaming_value))
roam->set_data_roaming_enabled(roaming_value);
@@ -225,23 +246,20 @@ void DeviceSettingsProvider::SetInPolicy() {
std::string proxy_value;
if (value->GetAsString(&proxy_value)) {
bool success =
- device_settings_.mutable_device_proxy_settings()->ParseFromString(
- proxy_value);
+ pol.mutable_device_proxy_settings()->ParseFromString(proxy_value);
DCHECK(success);
} else {
NOTREACHED();
}
} else if (prop == kReleaseChannel) {
- em::ReleaseChannelProto* release_channel =
- device_settings_.mutable_release_channel();
+ em::ReleaseChannelProto* release_channel = pol.mutable_release_channel();
std::string channel_value;
if (value->GetAsString(&channel_value))
release_channel->set_release_channel(channel_value);
else
NOTREACHED();
} else if (prop == kStatsReportingPref) {
- em::MetricsEnabledProto* metrics =
- device_settings_.mutable_metrics_enabled();
+ em::MetricsEnabledProto* metrics = pol.mutable_metrics_enabled();
bool metrics_value = false;
if (value->GetAsBoolean(&metrics_value))
metrics->set_metrics_enabled(metrics_value);
@@ -249,8 +267,7 @@ void DeviceSettingsProvider::SetInPolicy() {
NOTREACHED();
ApplyMetricsSetting(false, metrics_value);
} else if (prop == kAccountsPrefUsers) {
- em::UserWhitelistProto* whitelist_proto =
- device_settings_.mutable_user_whitelist();
+ em::UserWhitelistProto* whitelist_proto = pol.mutable_user_whitelist();
whitelist_proto->clear_user_whitelist();
base::ListValue& users = static_cast<base::ListValue&>(*value);
for (base::ListValue::const_iterator i = users.begin();
@@ -261,19 +278,17 @@ void DeviceSettingsProvider::SetInPolicy() {
}
} else if (prop == kAccountsPrefEphemeralUsersEnabled) {
em::EphemeralUsersEnabledProto* ephemeral_users_enabled =
- device_settings_.mutable_ephemeral_users_enabled();
+ pol.mutable_ephemeral_users_enabled();
bool ephemeral_users_enabled_value = false;
- if (value->GetAsBoolean(&ephemeral_users_enabled_value)) {
+ if (value->GetAsBoolean(&ephemeral_users_enabled_value))
ephemeral_users_enabled->set_ephemeral_users_enabled(
ephemeral_users_enabled_value);
- } else {
+ else
NOTREACHED();
- }
} else {
// The remaining settings don't support Set(), since they are not
// intended to be customizable by the user:
// kAppPack
- // kDeviceOwner
// kIdleLogoutTimeout
// kIdleLogoutWarningDuration
// kReleaseChannelDelegated
@@ -286,29 +301,48 @@ void DeviceSettingsProvider::SetInPolicy() {
// kStartUpUrls
// kSystemTimezonePolicy
- LOG(FATAL) << "Device setting " << prop << " is read-only.";
+ NOTREACHED();
}
-
- em::PolicyData data;
- data.set_username(device_settings_service_->GetUsername());
- CHECK(device_settings_.SerializeToString(data.mutable_policy_value()));
-
+ data.set_policy_value(pol.SerializeAsString());
// Set the cache to the updated value.
- UpdateValuesCache(data, device_settings_);
+ policy_ = data;
+ UpdateValuesCache();
- if (!device_settings_cache::Store(data, g_browser_process->local_state()))
+ if (!signed_settings_cache::Store(data, g_browser_process->local_state()))
LOG(ERROR) << "Couldn't store to the temp storage.";
- if (ownership_status_ == DeviceSettingsService::OWNERSHIP_TAKEN) {
- StoreDeviceSettings();
+ if (ownership_status_ == OwnershipService::OWNERSHIP_TAKEN) {
+ em::PolicyFetchResponse policy_envelope;
+ policy_envelope.set_policy_data(policy_.SerializeAsString());
+ signed_settings_helper_->StartStorePolicyOp(
+ policy_envelope,
+ base::Bind(&DeviceSettingsProvider::OnStorePolicyCompleted,
+ base::Unretained(this)));
} else {
// OnStorePolicyCompleted won't get called in this case so proceed with any
// pending operations immediately.
+ delete pending_changes_[0].second;
+ pending_changes_.erase(pending_changes_.begin());
if (!pending_changes_.empty())
SetInPolicy();
}
}
+void DeviceSettingsProvider::FinishSetInPolicy(
+ SignedSettings::ReturnCode code,
+ const em::PolicyFetchResponse& policy) {
+ if (code != SignedSettings::SUCCESS) {
+ LOG(ERROR) << "Can't serialize to policy error code: " << code;
+ Reload();
+ return;
+ }
+ // Update the internal caches and set the trusted flag to true so that we
+ // can pass the trustedness check in the second call to SetInPolicy.
+ OnRetrievePolicyCompleted(code, policy);
+
+ SetInPolicy();
+}
+
void DeviceSettingsProvider::DecodeLoginPolicies(
const em::ChromeDeviceSettingsProto& policy,
PrefValueMap* new_values_cache) const {
@@ -504,19 +538,21 @@ void DeviceSettingsProvider::DecodeGenericPolicies(
}
}
-void DeviceSettingsProvider::UpdateValuesCache(
- const em::PolicyData& policy_data,
- const em::ChromeDeviceSettingsProto& settings) {
+void DeviceSettingsProvider::UpdateValuesCache() {
+ const em::PolicyData data = policy();
PrefValueMap new_values_cache;
- if (policy_data.has_username() && !policy_data.has_request_token())
- new_values_cache.SetString(kDeviceOwner, policy_data.username());
+ if (data.has_username() && !data.has_request_token())
+ new_values_cache.SetString(kDeviceOwner, data.username());
- DecodeLoginPolicies(settings, &new_values_cache);
- DecodeKioskPolicies(settings, &new_values_cache);
- DecodeNetworkPolicies(settings, &new_values_cache);
- DecodeReportingPolicies(settings, &new_values_cache);
- DecodeGenericPolicies(settings, &new_values_cache);
+ em::ChromeDeviceSettingsProto pol;
+ pol.ParseFromString(data.policy_value());
+
+ DecodeLoginPolicies(pol, &new_values_cache);
+ DecodeKioskPolicies(pol, &new_values_cache);
+ DecodeNetworkPolicies(pol, &new_values_cache);
+ DecodeReportingPolicies(pol, &new_values_cache);
+ DecodeGenericPolicies(pol, &new_values_cache);
// Collect all notifications but send them only after we have swapped the
// cache so that if somebody actually reads the cache will be already valid.
@@ -543,18 +579,18 @@ void DeviceSettingsProvider::UpdateValuesCache(
}
void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
- bool new_value) {
+ bool new_value) const {
// TODO(pastarmovj): Remove this once migration is not needed anymore.
// If the value is not set we should try to migrate legacy consent file.
if (use_file) {
new_value = HasOldMetricsFile();
// Make sure the values will get eventually written to the policy file.
- migration_values_.SetValue(kStatsReportingPref,
- base::Value::CreateBooleanValue(new_value));
- AttemptMigration();
+ migration_helper_->AddMigrationValue(
+ kStatsReportingPref, base::Value::CreateBooleanValue(new_value));
+ migration_helper_->MigrateValues();
LOG(INFO) << "No metrics policy set will revert to checking "
- << "consent file which is "
- << (new_value ? "on." : "off.");
+ << "consent file which is "
+ << (new_value ? "on." : "off.");
}
VLOG(1) << "Metrics policy is being set to : " << new_value
<< "(use file : " << use_file << ")";
@@ -563,7 +599,7 @@ void DeviceSettingsProvider::ApplyMetricsSetting(bool use_file,
OptionsUtil::ResolveMetricsReportingEnabled(new_value);
}
-void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) {
+void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) const {
NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
const NetworkDevice* cellular = cros->FindCellularDevice();
if (cellular) {
@@ -578,26 +614,25 @@ void DeviceSettingsProvider::ApplyRoamingSetting(bool new_value) {
}
}
-void DeviceSettingsProvider::ApplySideEffects(
- const em::ChromeDeviceSettingsProto& settings) {
+void DeviceSettingsProvider::ApplySideEffects() const {
+ const em::PolicyData data = policy();
+ em::ChromeDeviceSettingsProto pol;
+ pol.ParseFromString(data.policy_value());
// First migrate metrics settings as needed.
- if (settings.has_metrics_enabled())
- ApplyMetricsSetting(false, settings.metrics_enabled().metrics_enabled());
+ if (pol.has_metrics_enabled())
+ ApplyMetricsSetting(false, pol.metrics_enabled().metrics_enabled());
else
ApplyMetricsSetting(true, false);
-
// Next set the roaming setting as needed.
- ApplyRoamingSetting(
- settings.has_data_roaming_enabled() ?
- settings.data_roaming_enabled().data_roaming_enabled() :
- false);
+ ApplyRoamingSetting(pol.has_data_roaming_enabled() ?
+ pol.data_roaming_enabled().data_roaming_enabled() : false);
}
bool DeviceSettingsProvider::MitigateMissingPolicy() {
// First check if the device has been owned already and if not exit
// immediately.
if (g_browser_process->browser_policy_connector()->GetDeviceMode() !=
- policy::DEVICE_MODE_CONSUMER) {
+ policy::DEVICE_MODE_CONSUMER) {
return false;
}
@@ -610,15 +645,17 @@ bool DeviceSettingsProvider::MitigateMissingPolicy() {
LOG(ERROR) << "Corruption of the policy data has been detected."
<< "Switching to \"safe-mode\" policies until the owner logs in "
<< "to regenerate the policy data.";
-
- device_settings_.Clear();
- device_settings_.mutable_allow_new_users()->set_allow_new_users(true);
- device_settings_.mutable_guest_mode_enabled()->set_guest_mode_enabled(true);
- em::PolicyData empty_policy_data;
- UpdateValuesCache(empty_policy_data, device_settings_);
+ values_cache_.SetBoolean(kAccountsPrefAllowNewUser, true);
+ values_cache_.SetBoolean(kAccountsPrefAllowGuest, true);
values_cache_.SetBoolean(kPolicyMissingMitigationMode, true);
trusted_status_ = TRUSTED;
-
+ // Make sure we will recreate the policy once the owner logs in.
+ // Any value not in this list will be left to the default which is fine as
+ // we repopulate the whitelist with the owner and all other existing users
+ // every time the owner enables whitelist filtering on the UI.
+ migration_helper_->AddMigrationValue(
+ kAccountsPrefAllowNewUser, base::Value::CreateBooleanValue(true));
+ migration_helper_->MigrateValues();
return true;
}
@@ -648,93 +685,83 @@ bool DeviceSettingsProvider::HandlesSetting(const std::string& path) const {
DeviceSettingsProvider::TrustedStatus
DeviceSettingsProvider::RequestTrustedEntity() {
- if (ownership_status_ == DeviceSettingsService::OWNERSHIP_NONE)
+ if (ownership_status_ == OwnershipService::OWNERSHIP_NONE)
return TRUSTED;
return trusted_status_;
}
-void DeviceSettingsProvider::UpdateAndProceedStoring() {
- // Re-sync the cache from the service.
- UpdateFromService();
+void DeviceSettingsProvider::OnStorePolicyCompleted(
+ SignedSettings::ReturnCode code) {
+ // In any case reload the policy cache to now.
+ if (code != SignedSettings::SUCCESS) {
+ Reload();
+ } else {
+ trusted_status_ = TRUSTED;
+ // TODO(pastarmovj): Make those side effects responsibility of the
+ // respective subsystems.
+ ApplySideEffects();
+ // Notify the observers we are done.
+ std::vector<base::Closure> callbacks;
+ callbacks.swap(callbacks_);
+ for (size_t i = 0; i < callbacks.size(); ++i)
+ callbacks[i].Run();
+ }
- // Trigger the next change if necessary.
- if (trusted_status_ == TRUSTED &&
- !store_callback_factory_.HasWeakPtrs() &&
- !pending_changes_.empty()) {
+ // Clear the finished task and proceed with any other stores that could be
+ // pending by now.
+ delete pending_changes_[0].second;
+ pending_changes_.erase(pending_changes_.begin());
+ if (!pending_changes_.empty())
SetInPolicy();
- }
}
-bool DeviceSettingsProvider::UpdateFromService() {
- bool settings_loaded = false;
- switch (device_settings_service_->status()) {
- case DeviceSettingsService::STORE_SUCCESS: {
- const em::PolicyData* policy_data =
- device_settings_service_->policy_data();
- const em::ChromeDeviceSettingsProto* device_settings =
- device_settings_service_->device_settings();
- if (policy_data && device_settings) {
- UpdateValuesCache(*policy_data, *device_settings);
- device_settings_ = *device_settings;
- trusted_status_ = TRUSTED;
-
- // TODO(pastarmovj): Make those side effects responsibility of the
- // respective subsystems.
- ApplySideEffects(*device_settings);
-
- settings_loaded = true;
- } else {
- // Initial policy load is still pending.
- trusted_status_ = TEMPORARILY_UNTRUSTED;
- }
+void DeviceSettingsProvider::OnRetrievePolicyCompleted(
+ SignedSettings::ReturnCode code,
+ const em::PolicyFetchResponse& policy_data) {
+ VLOG(1) << "OnRetrievePolicyCompleted. Error code: " << code
+ << ", trusted status : " << trusted_status_
+ << ", ownership status : " << ownership_status_;
+ switch (code) {
+ case SignedSettings::SUCCESS: {
+ DCHECK(policy_data.has_policy_data());
+ policy_.ParseFromString(policy_data.policy_data());
+ signed_settings_cache::Store(policy(),
+ g_browser_process->local_state());
+ UpdateValuesCache();
+ trusted_status_ = TRUSTED;
+ // TODO(pastarmovj): Make those side effects responsibility of the
+ // respective subsystems.
+ ApplySideEffects();
break;
}
- case DeviceSettingsService::STORE_NO_POLICY:
+ case SignedSettings::NOT_FOUND:
if (MitigateMissingPolicy())
break;
- // fall through.
- case DeviceSettingsService::STORE_KEY_UNAVAILABLE:
- VLOG(1) << "No policies present yet, will use the temp storage.";
+ case SignedSettings::KEY_UNAVAILABLE: {
+ if (ownership_status_ != OwnershipService::OWNERSHIP_TAKEN)
+ NOTREACHED() << "No policies present yet, will use the temp storage.";
trusted_status_ = PERMANENTLY_UNTRUSTED;
break;
- case DeviceSettingsService::STORE_POLICY_ERROR:
- case DeviceSettingsService::STORE_VALIDATION_ERROR:
- case DeviceSettingsService::STORE_INVALID_POLICY:
- case DeviceSettingsService::STORE_OPERATION_FAILED:
- LOG(ERROR) << "Failed to retrieve cros policies. Reason: "
- << device_settings_service_->status();
+ }
+ case SignedSettings::BAD_SIGNATURE:
+ case SignedSettings::OPERATION_FAILED: {
+ LOG(ERROR) << "Failed to retrieve cros policies. Reason:" << code;
+ if (retries_left_ > 0) {
+ trusted_status_ = TEMPORARILY_UNTRUSTED;
+ retries_left_ -= 1;
+ Reload();
+ return;
+ }
+ LOG(ERROR) << "No retries left";
trusted_status_ = PERMANENTLY_UNTRUSTED;
break;
+ }
}
-
// Notify the observers we are done.
std::vector<base::Closure> callbacks;
callbacks.swap(callbacks_);
for (size_t i = 0; i < callbacks.size(); ++i)
callbacks[i].Run();
-
- return settings_loaded;
-}
-
-void DeviceSettingsProvider::StoreDeviceSettings() {
- // Mute all previous callbacks to guarantee the |pending_changes_| queue is
- // processed serially.
- store_callback_factory_.InvalidateWeakPtrs();
-
- device_settings_service_->SignAndStore(
- scoped_ptr<em::ChromeDeviceSettingsProto>(
- new em::ChromeDeviceSettingsProto(device_settings_)),
- base::Bind(&DeviceSettingsProvider::UpdateAndProceedStoring,
- store_callback_factory_.GetWeakPtr()));
-}
-
-void DeviceSettingsProvider::AttemptMigration() {
- if (device_settings_service_->HasPrivateOwnerKey()) {
- PrefValueMap::const_iterator i;
- for (i = migration_values_.begin(); i != migration_values_.end(); ++i)
- DoSet(i->first, *i->second);
- migration_values_.Clear();
- }
}
} // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.h b/chrome/browser/chromeos/settings/device_settings_provider.h
index cf625df..03735b5 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider.h
+++ b/chrome/browser/chromeos/settings/device_settings_provider.h
@@ -5,20 +5,18 @@
#ifndef CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_PROVIDER_H_
#define CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_PROVIDER_H_
-#include <deque>
#include <string>
#include <utility>
#include <vector>
#include "base/basictypes.h"
#include "base/callback_forward.h"
-#include "base/gtest_prod_util.h"
-#include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/settings/cros_settings_provider.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
-#include "chrome/browser/prefs/pref_value_map.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
+#include "chrome/browser/chromeos/settings/signed_settings_migration_helper.h"
+#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "chrome/browser/prefs/pref_value_map.h"
+#include "content/public/browser/notification_registrar.h"
namespace base {
class Value;
@@ -30,12 +28,12 @@ class ChromeDeviceSettingsProto;
namespace chromeos {
-// CrosSettingsProvider implementation that works with device settings.
+// CrosSettingsProvider implementation that works with SignedSettings.
class DeviceSettingsProvider : public CrosSettingsProvider,
- public DeviceSettingsService::Observer {
+ public content::NotificationObserver {
public:
DeviceSettingsProvider(const NotifyObserversCallback& notify_cb,
- DeviceSettingsService* device_settings_service);
+ SignedSettingsHelper* signed_settings_helper);
virtual ~DeviceSettingsProvider();
// CrosSettingsProvider implementation.
@@ -43,26 +41,35 @@ class DeviceSettingsProvider : public CrosSettingsProvider,
virtual TrustedStatus PrepareTrustedValues(
const base::Closure& callback) OVERRIDE;
virtual bool HandlesSetting(const std::string& path) const OVERRIDE;
+ virtual void Reload() OVERRIDE;
private:
// CrosSettingsProvider implementation:
virtual void DoSet(const std::string& path,
const base::Value& value) OVERRIDE;
- // DeviceSettingsService::Observer implementation:
- virtual void OwnershipStatusChanged() OVERRIDE;
- virtual void DeviceSettingsUpdated() OVERRIDE;
+ // content::NotificationObserver implementation:
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
+ const enterprise_management::PolicyData policy() const;
// Populates in-memory cache from the local_state cache that is used to store
- // device settings before the device is owned and to speed up policy
+ // signed settings before the device is owned and to speed up policy
// availability before the policy blob is fetched on boot.
void RetrieveCachedData();
- // Stores a value from the |pending_changes_| queue in the device settings.
+ // Stores a value from the |pending_changes_| queue in the signed settings.
// If the device is not owned yet the data ends up only in the local_state
// cache and is serialized once ownership is acquired.
void SetInPolicy();
+ // Finalizes stores to the policy file if the cache is dirty.
+ void FinishSetInPolicy(
+ SignedSettings::ReturnCode code,
+ const enterprise_management::PolicyFetchResponse& policy);
+
// Decode the various groups of policies.
void DecodeLoginPolicies(
const enterprise_management::ChromeDeviceSettingsProto& policy,
@@ -80,21 +87,18 @@ class DeviceSettingsProvider : public CrosSettingsProvider,
const enterprise_management::ChromeDeviceSettingsProto& policy,
PrefValueMap* new_values_cache) const;
- // Parses the policy data and fills in |values_cache_|.
- void UpdateValuesCache(
- const enterprise_management::PolicyData& policy_data,
- const enterprise_management::ChromeDeviceSettingsProto& settings);
+ // Parses the policy cache and fills the cache of base::Value objects.
+ void UpdateValuesCache();
// Applies the metrics policy and if not set migrates the legacy file.
- void ApplyMetricsSetting(bool use_file, bool new_value);
+ void ApplyMetricsSetting(bool use_file, bool new_value) const;
// Applies the data roaming policy.
- void ApplyRoamingSetting(bool new_value);
+ void ApplyRoamingSetting(bool new_value) const;
// Applies any changes of the policies that are not handled by the respective
// subsystems.
- void ApplySideEffects(
- const enterprise_management::ChromeDeviceSettingsProto& settings);
+ void ApplySideEffects() const;
// In case of missing policy blob we should verify if this is upgrade of
// machine owned from pre version 12 OS and the user never touched the device
@@ -102,55 +106,58 @@ class DeviceSettingsProvider : public CrosSettingsProvider,
// comes and changes that.
bool MitigateMissingPolicy();
+ // Called right before boolean property is changed.
+ void OnBooleanPropertyChange(const std::string& path, bool new_value);
+
// Checks if the current cache value can be trusted for being representative
// for the disk cache.
TrustedStatus RequestTrustedEntity();
- // Invokes UpdateFromService() to synchronize with |device_settings_service_|,
- // then triggers the next store operation if applicable.
- void UpdateAndProceedStoring();
-
- // Re-reads state from |device_settings_service_|, adjusts
- // |trusted_status_| and calls UpdateValuesCache() if applicable. Returns true
- // if new settings have been loaded.
- bool UpdateFromService();
-
- // Sends |device_settings_| to |device_settings_service_| for signing and
- // storage in session_manager.
- void StoreDeviceSettings();
-
- // Checks the current ownership status to see whether the device owner is
- // logged in and writes the data accumulated in |migration_values_| to proper
- // device settings.
- void AttemptMigration();
+ // Called right after signed value was checked.
+ void OnPropertyRetrieve(const std::string& path,
+ const base::Value* value,
+ bool use_default_value);
+
+ // Callback of StorePolicyOp for ordinary policy stores.
+ void OnStorePolicyCompleted(SignedSettings::ReturnCode code);
+
+ // Callback of RetrievePolicyOp for ordinary policy [re]loads.
+ void OnRetrievePolicyCompleted(
+ SignedSettings::ReturnCode code,
+ const enterprise_management::PolicyFetchResponse& policy);
+
+ // These setters are for test use only.
+ void set_ownership_status(OwnershipService::Status status) {
+ ownership_status_ = status;
+ }
+ void set_trusted_status(TrustedStatus status) {
+ trusted_status_ = status;
+ }
+ void set_retries_left(int retries) {
+ retries_left_ = retries;
+ }
// Pending callbacks that need to be invoked after settings verification.
std::vector<base::Closure> callbacks_;
- DeviceSettingsService* device_settings_service_;
- mutable PrefValueMap migration_values_;
+ SignedSettingsHelper* signed_settings_helper_;
+ OwnershipService::Status ownership_status_;
+ mutable scoped_ptr<SignedSettingsMigrationHelper> migration_helper_;
+
+ content::NotificationRegistrar registrar_;
+
+ // In order to guard against occasional failure to fetch a property
+ // we allow for some number of retries.
+ int retries_left_;
+ enterprise_management::PolicyData policy_;
TrustedStatus trusted_status_;
- DeviceSettingsService::OwnershipStatus ownership_status_;
-
- // The device settings as currently reported through the CrosSettingsProvider
- // interface. This may be different from the actual current device settings
- // (which can be obtained from |device_settings_service_|) in case the device
- // does not have an owner yet or there are pending changes that have not yet
- // been written to session_manager.
- enterprise_management::ChromeDeviceSettingsProto device_settings_;
-
- // A cache of values, indexed by the settings keys served through the
- // CrosSettingsProvider interface. This is always kept in sync with the raw
- // data found in |device_settings_|.
+
PrefValueMap values_cache_;
// This is a queue for set requests, because those need to be sequential.
typedef std::pair<std::string, base::Value*> PendingQueueElement;
- std::deque<PendingQueueElement> pending_changes_;
-
- // Weak pointer factory for creating store operation callbacks.
- base::WeakPtrFactory<DeviceSettingsProvider> store_callback_factory_;
+ std::vector<PendingQueueElement> pending_changes_;
friend class DeviceSettingsProviderTest;
FRIEND_TEST_ALL_PREFIXES(DeviceSettingsProviderTest,
diff --git a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
index 8943eee3e..e05c24c 100644
--- a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
+++ b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
@@ -7,14 +7,13 @@
#include <string>
#include "base/bind.h"
-#include "base/callback.h"
#include "base/message_loop.h"
#include "base/values.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
+#include "chrome/browser/chromeos/login/mock_user_manager.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
-#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
-#include "chrome/browser/chromeos/settings/mock_owner_key_util.h"
-#include "chrome/browser/policy/policy_builder.h"
+#include "chrome/browser/chromeos/settings/mock_signed_settings_helper.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "chrome/test/base/testing_browser_process.h"
@@ -24,82 +23,96 @@
#include "testing/gtest/include/gtest/gtest.h"
namespace em = enterprise_management;
-
namespace chromeos {
using ::testing::AnyNumber;
using ::testing::Mock;
+using ::testing::Return;
+using ::testing::SaveArg;
using ::testing::_;
class DeviceSettingsProviderTest: public testing::Test {
- public:
+public:
MOCK_METHOD1(SettingChanged, void(const std::string&));
MOCK_METHOD0(GetTrustedCallback, void(void));
- protected:
+protected:
DeviceSettingsProviderTest()
: message_loop_(MessageLoop::TYPE_UI),
ui_thread_(content::BrowserThread::UI, &message_loop_),
file_thread_(content::BrowserThread::FILE, &message_loop_),
- local_state_(static_cast<TestingBrowserProcess*>(g_browser_process)),
- owner_key_util_(new MockOwnerKeyUtil()) {}
+ local_state_(static_cast<TestingBrowserProcess*>(g_browser_process)) {
+ }
+
+ virtual ~DeviceSettingsProviderTest() {
+ }
virtual void SetUp() OVERRIDE {
- policy_.payload().mutable_metrics_enabled()->set_metrics_enabled(false);
- policy_.Build();
+ PrepareEmptyPolicy();
- device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_))
+ .WillRepeatedly(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ policy_blob_));
+ EXPECT_CALL(signed_settings_helper_, StartStorePolicyOp(_,_))
+ .WillRepeatedly(DoAll(
+ SaveArg<0>(&policy_blob_),
+ MockSignedSettingsHelperStorePolicy(SignedSettings::SUCCESS)));
- device_settings_service_.Initialize(&device_settings_test_helper_,
- owner_key_util_);
+ EXPECT_CALL(*mock_user_manager_.user_manager(), IsCurrentUserOwner())
+ .WillRepeatedly(Return(true));
EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
provider_.reset(
new DeviceSettingsProvider(
base::Bind(&DeviceSettingsProviderTest::SettingChanged,
base::Unretained(this)),
- &device_settings_service_));
+ &signed_settings_helper_));
+ provider_->set_ownership_status(OwnershipService::OWNERSHIP_TAKEN);
+
+ // To prevent flooding the logs.
+ provider_->set_retries_left(1);
+ provider_->Reload();
Mock::VerifyAndClearExpectations(this);
}
- virtual void TearDown() OVERRIDE {
- device_settings_service_.Shutdown();
+ void PrepareEmptyPolicy() {
+ em::PolicyData policy;
+ em::ChromeDeviceSettingsProto pol;
+ // Set metrics to disabled to prevent us from running into code that is not
+ // mocked.
+ pol.mutable_metrics_enabled()->set_metrics_enabled(false);
+ policy.set_policy_type(chromeos::kDevicePolicyType);
+ policy.set_username("me@owner");
+ policy.set_policy_value(pol.SerializeAsString());
+ // Wipe the signed settings store.
+ policy_blob_.set_policy_data(policy.SerializeAsString());
+ policy_blob_.set_policy_data_signature("false");
}
+ em::PolicyFetchResponse policy_blob_;
+
+ scoped_ptr<DeviceSettingsProvider> provider_;
+
MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
content::TestBrowserThread file_thread_;
- ScopedStubCrosEnabler stub_cros_enabler_;
-
ScopedTestingLocalState local_state_;
- DeviceSettingsTestHelper device_settings_test_helper_;
- scoped_refptr<MockOwnerKeyUtil> owner_key_util_;
-
- DeviceSettingsService device_settings_service_;
-
- policy::DevicePolicyBuilder policy_;
-
- scoped_ptr<DeviceSettingsProvider> provider_;
+ MockSignedSettingsHelper signed_settings_helper_;
- private:
- DISALLOW_COPY_AND_ASSIGN(DeviceSettingsProviderTest);
+ ScopedStubCrosEnabler stub_cros_enabler_;
+ ScopedMockUserManagerEnabler mock_user_manager_;
};
TEST_F(DeviceSettingsProviderTest, InitializationTest) {
- owner_key_util_->SetPublicKeyFromPrivateKey(policy_.signing_key());
-
- // Have the service load a settings blob.
- EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
- device_settings_service_.Load();
- device_settings_test_helper_.Flush();
- Mock::VerifyAndClearExpectations(this);
-
// Verify that the policy blob has been correctly parsed and trusted.
// The trusted flag should be set before the call to PrepareTrustedValues.
EXPECT_EQ(CrosSettingsProvider::TRUSTED,
- provider_->PrepareTrustedValues(base::Closure()));
+ provider_->PrepareTrustedValues(
+ base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback,
+ base::Unretained(this))));
const base::Value* value = provider_->Get(kStatsReportingPref);
ASSERT_TRUE(value);
bool bool_value;
@@ -108,13 +121,16 @@ TEST_F(DeviceSettingsProviderTest, InitializationTest) {
}
TEST_F(DeviceSettingsProviderTest, InitializationTestUnowned) {
- // Have the service check the key.
- device_settings_service_.Load();
- device_settings_test_helper_.Flush();
+ // No calls to the SignedSettingsHelper should occur in this case!
+ Mock::VerifyAndClear(&signed_settings_helper_);
+ provider_->set_ownership_status(OwnershipService::OWNERSHIP_NONE);
+ provider_->Reload();
// The trusted flag should be set before the call to PrepareTrustedValues.
EXPECT_EQ(CrosSettingsProvider::TRUSTED,
- provider_->PrepareTrustedValues(base::Closure()));
+ provider_->PrepareTrustedValues(
+ base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback,
+ base::Unretained(this))));
const base::Value* value = provider_->Get(kReleaseChannel);
ASSERT_TRUE(value);
std::string string_value;
@@ -122,38 +138,26 @@ TEST_F(DeviceSettingsProviderTest, InitializationTestUnowned) {
EXPECT_TRUE(string_value.empty());
// Sets should succeed though and be readable from the cache.
- EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
EXPECT_CALL(*this, SettingChanged(kReleaseChannel)).Times(1);
base::StringValue new_value("stable-channel");
provider_->Set(kReleaseChannel, new_value);
- Mock::VerifyAndClearExpectations(this);
-
- // This shouldn't trigger a write.
- device_settings_test_helper_.set_policy_blob(std::string());
- device_settings_test_helper_.Flush();
- EXPECT_EQ(std::string(), device_settings_test_helper_.policy_blob());
-
- // Verify the change has been applied.
+ // Do one more reload here to make sure we don't flip randomly between stores.
+ provider_->Reload();
+ // Verify the change has not been applied.
const base::Value* saved_value = provider_->Get(kReleaseChannel);
ASSERT_TRUE(saved_value);
EXPECT_TRUE(saved_value->GetAsString(&string_value));
ASSERT_EQ("stable-channel", string_value);
+ Mock::VerifyAndClearExpectations(this);
}
TEST_F(DeviceSettingsProviderTest, SetPrefFailed) {
+ EXPECT_CALL(*this, SettingChanged(kStatsReportingPref)).Times(1);
// If we are not the owner no sets should work.
- owner_key_util_->SetPublicKeyFromPrivateKey(policy_.signing_key());
-
+ EXPECT_CALL(*mock_user_manager_.user_manager(), IsCurrentUserOwner())
+ .WillOnce(Return(false));
base::FundamentalValue value(true);
- EXPECT_CALL(*this, SettingChanged(kStatsReportingPref)).Times(1);
provider_->Set(kStatsReportingPref, value);
- Mock::VerifyAndClearExpectations(this);
-
- // This shouldn't trigger a write.
- device_settings_test_helper_.set_policy_blob(std::string());
- device_settings_test_helper_.Flush();
- EXPECT_EQ(std::string(), device_settings_test_helper_.policy_blob());
-
// Verify the change has not been applied.
const base::Value* saved_value = provider_->Get(kStatsReportingPref);
ASSERT_TRUE(saved_value);
@@ -163,26 +167,10 @@ TEST_F(DeviceSettingsProviderTest, SetPrefFailed) {
}
TEST_F(DeviceSettingsProviderTest, SetPrefSucceed) {
- owner_key_util_->SetPrivateKey(policy_.signing_key());
- device_settings_service_.SetUsername(policy_.policy_data().username());
- device_settings_test_helper_.Flush();
-
- base::FundamentalValue value(true);
- EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
EXPECT_CALL(*this, SettingChanged(kStatsReportingPref)).Times(1);
+ base::FundamentalValue value(true);
provider_->Set(kStatsReportingPref, value);
- Mock::VerifyAndClearExpectations(this);
-
- // Process the store.
- device_settings_test_helper_.set_policy_blob(std::string());
- device_settings_test_helper_.Flush();
-
- // Verify that the device policy has been adjusted.
- ASSERT_TRUE(device_settings_service_.device_settings());
- EXPECT_TRUE(device_settings_service_.device_settings()->
- metrics_enabled().metrics_enabled());
-
- // Verify the change has been applied.
+ // Verify the change has not been applied.
const base::Value* saved_value = provider_->Get(kStatsReportingPref);
ASSERT_TRUE(saved_value);
bool bool_value;
@@ -190,64 +178,84 @@ TEST_F(DeviceSettingsProviderTest, SetPrefSucceed) {
EXPECT_TRUE(bool_value);
}
-TEST_F(DeviceSettingsProviderTest, PolicyRetrievalFailedBadSignature) {
- owner_key_util_->SetPublicKeyFromPrivateKey(policy_.signing_key());
- policy_.policy().set_policy_data_signature("bad signature");
- device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
-
- device_settings_service_.Load();
- device_settings_test_helper_.Flush();
-
- // Verify that the cached settings blob is not "trusted".
- EXPECT_EQ(DeviceSettingsService::STORE_VALIDATION_ERROR,
- device_settings_service_.status());
+TEST_F(DeviceSettingsProviderTest, PolicyRetrievalFailedBadSingature) {
+ // No calls to the SignedSettingsHelper should occur in this case!
+ Mock::VerifyAndClear(&signed_settings_helper_);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_))
+ .WillRepeatedly(
+ MockSignedSettingsHelperRetrievePolicy(
+ SignedSettings::BAD_SIGNATURE,
+ policy_blob_));
+ provider_->Reload();
+ // Verify that the cache policy blob is not "trusted".
EXPECT_EQ(CrosSettingsProvider::PERMANENTLY_UNTRUSTED,
- provider_->PrepareTrustedValues(base::Closure()));
+ provider_->PrepareTrustedValues(
+ base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback,
+ base::Unretained(this))));
}
-TEST_F(DeviceSettingsProviderTest, PolicyRetrievalNoPolicy) {
- owner_key_util_->SetPublicKeyFromPrivateKey(policy_.signing_key());
- device_settings_test_helper_.set_policy_blob(std::string());
-
- device_settings_service_.Load();
- device_settings_test_helper_.Flush();
-
- // Verify that the cached settings blob is not "trusted".
- EXPECT_EQ(DeviceSettingsService::STORE_NO_POLICY,
- device_settings_service_.status());
+TEST_F(DeviceSettingsProviderTest, PolicyRetrievalOperationFailedPermanently) {
+ // No calls to the SignedSettingsHelper should occur in this case!
+ Mock::VerifyAndClear(&signed_settings_helper_);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_))
+ .WillRepeatedly(
+ MockSignedSettingsHelperRetrievePolicy(
+ SignedSettings::OPERATION_FAILED,
+ policy_blob_));
+ provider_->Reload();
+ // Verify that the cache policy blob is not "trusted".
EXPECT_EQ(CrosSettingsProvider::PERMANENTLY_UNTRUSTED,
- provider_->PrepareTrustedValues(base::Closure()));
+ provider_->PrepareTrustedValues(
+ base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback,
+ base::Unretained(this))));
}
-TEST_F(DeviceSettingsProviderTest, PolicyFailedPermanentlyNotification) {
- owner_key_util_->SetPublicKeyFromPrivateKey(policy_.signing_key());
- device_settings_test_helper_.set_policy_blob(std::string());
+TEST_F(DeviceSettingsProviderTest, PolicyRetrievalOperationFailedOnce) {
+ // No calls to the SignedSettingsHelper should occur in this case!
+ Mock::VerifyAndClear(&signed_settings_helper_);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_))
+ .WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(
+ SignedSettings::OPERATION_FAILED,
+ policy_blob_))
+ .WillRepeatedly(
+ MockSignedSettingsHelperRetrievePolicy(
+ SignedSettings::SUCCESS,
+ policy_blob_));
+ // Should be trusted after an automatic reload.
+ provider_->Reload();
+ // Verify that the cache policy blob is not "trusted".
+ EXPECT_EQ(CrosSettingsProvider::TRUSTED,
+ provider_->PrepareTrustedValues(
+ base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback,
+ base::Unretained(this))));
+}
+TEST_F(DeviceSettingsProviderTest, PolicyFailedPermanentlyNotification) {
+ Mock::VerifyAndClear(&signed_settings_helper_);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_))
+ .WillRepeatedly(
+ MockSignedSettingsHelperRetrievePolicy(
+ SignedSettings::OPERATION_FAILED,
+ policy_blob_));
+
+ provider_->set_trusted_status(CrosSettingsProvider::TEMPORARILY_UNTRUSTED);
EXPECT_CALL(*this, GetTrustedCallback());
EXPECT_EQ(CrosSettingsProvider::TEMPORARILY_UNTRUSTED,
provider_->PrepareTrustedValues(
base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback,
base::Unretained(this))));
-
- device_settings_service_.Load();
- device_settings_test_helper_.Flush();
- Mock::VerifyAndClearExpectations(this);
-
- EXPECT_EQ(CrosSettingsProvider::PERMANENTLY_UNTRUSTED,
- provider_->PrepareTrustedValues(base::Closure()));
+ provider_->Reload();
}
TEST_F(DeviceSettingsProviderTest, PolicyLoadNotification) {
+ provider_->set_trusted_status(CrosSettingsProvider::TEMPORARILY_UNTRUSTED);
EXPECT_CALL(*this, GetTrustedCallback());
-
EXPECT_EQ(CrosSettingsProvider::TEMPORARILY_UNTRUSTED,
provider_->PrepareTrustedValues(
base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback,
base::Unretained(this))));
-
- device_settings_service_.Load();
- device_settings_test_helper_.Flush();
- Mock::VerifyAndClearExpectations(this);
+ provider_->Reload();
}
} // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/owner_manager.cc b/chrome/browser/chromeos/settings/owner_manager.cc
index 60e69a3..385af76 100644
--- a/chrome/browser/chromeos/settings/owner_manager.cc
+++ b/chrome/browser/chromeos/settings/owner_manager.cc
@@ -12,7 +12,7 @@
#include "base/file_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/boot_times_loader.h"
-#include "chrome/browser/chromeos/settings/device_settings_cache.h"
+#include "chrome/browser/chromeos/settings/signed_settings_cache.h"
#include "chrome/common/chrome_notification_types.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chromeos/settings/session_manager_observer.cc b/chrome/browser/chromeos/settings/session_manager_observer.cc
index fba6894..6bb828c 100644
--- a/chrome/browser/chromeos/settings/session_manager_observer.cc
+++ b/chrome/browser/chromeos/settings/session_manager_observer.cc
@@ -5,8 +5,8 @@
#include "chrome/browser/chromeos/settings/session_manager_observer.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/settings/device_settings_cache.h"
#include "chrome/browser/chromeos/settings/signed_settings.h"
+#include "chrome/browser/chromeos/settings/signed_settings_cache.h"
#include "chrome/common/chrome_notification_types.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "content/public/browser/browser_thread.h"
@@ -60,7 +60,7 @@ void SessionManagerObserver::OwnerKeySet(bool success) {
// Now owner is assigned and key is generated and we should persist
// those settings into signed storage.
if (success && g_browser_process && g_browser_process->local_state())
- device_settings_cache::Finalize(g_browser_process->local_state());
+ signed_settings_cache::Finalize(g_browser_process->local_state());
// Whether we exported the public key or not, send a notification
// indicating that we're done with this attempt.
diff --git a/chrome/browser/chromeos/settings/signed_settings_cache.cc b/chrome/browser/chromeos/settings/signed_settings_cache.cc
new file mode 100644
index 0000000..811f428
--- /dev/null
+++ b/chrome/browser/chromeos/settings/signed_settings_cache.cc
@@ -0,0 +1,133 @@
+// Copyright (c) 2012 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/chromeos/settings/signed_settings_cache.h"
+
+#include <string>
+
+#include "base/base64.h"
+#include "base/bind.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
+#include "chrome/browser/chromeos/settings/signed_settings_helper.h"
+#include "chrome/browser/policy/proto/device_management_backend.pb.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/common/pref_names.h"
+
+using content::BrowserThread;
+
+namespace em = enterprise_management;
+
+namespace chromeos {
+
+namespace {
+
+void OnStorePolicyCompleted(SignedSettings::ReturnCode code) {
+ if (code != SignedSettings::SUCCESS)
+ LOG(ERROR) << "Couldn't save temp store to the policy blob. code: " << code;
+ else
+ CrosSettings::Get()->ReloadProviders();
+}
+
+void FinishFinalize(PrefService* local_state,
+ SignedSettings::ReturnCode code,
+ const em::PolicyFetchResponse& policy) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (code != SignedSettings::SUCCESS) {
+ LOG(ERROR) << "Can't finalize temp store error code:" << code;
+ return;
+ }
+
+ if (local_state) {
+ std::string encoded =
+ local_state->GetString(prefs::kSignedSettingsCache);
+ std::string policy_string;
+ if (!base::Base64Decode(encoded, &policy_string)) {
+ LOG(ERROR) << "Can't decode policy from base64 on finalizing.";
+ return;
+ }
+
+ em::PolicyData merging_policy_data;
+ if (!merging_policy_data.ParseFromString(policy_string)) {
+ LOG(ERROR) << "Can't decode policy from string on finalizing.";
+ return;
+ }
+
+ em::PolicyFetchResponse policy_envelope = policy;
+ DCHECK(policy_envelope.has_policy_data());
+ em::PolicyData base_policy_data;
+ base_policy_data.ParseFromString(policy_envelope.policy_data());
+ // Merge only the policy value as we should never ever rewrite the other
+ // fields of the PolicyData protobuf.
+ base_policy_data.set_policy_value(merging_policy_data.policy_value());
+ policy_envelope.set_policy_data(base_policy_data.SerializeAsString());
+ DCHECK(base_policy_data.has_username());
+ policy_envelope.clear_policy_data_signature();
+ SignedSettingsHelper::Get()->StartStorePolicyOp(
+ policy_envelope, base::Bind(&OnStorePolicyCompleted));
+ }
+}
+
+// Reload the initial policy blob, and if successful apply the settings from
+// temp storage, and write them back the blob in FinishFinalize.
+void ReloadSignedSettingsAndFinalize(
+ PrefService* local_state,
+ OwnershipService::Status status,
+ bool current_user_is_owner) {
+ if (current_user_is_owner) {
+ SignedSettingsHelper::Get()->StartRetrievePolicyOp(
+ base::Bind(FinishFinalize, local_state));
+ }
+}
+
+} // namespace
+
+namespace signed_settings_cache {
+
+void RegisterPrefs(PrefService* local_state) {
+ local_state->RegisterStringPref(prefs::kSignedSettingsCache,
+ "invalid",
+ PrefService::UNSYNCABLE_PREF);
+}
+
+bool Store(const em::PolicyData& policy, PrefService* local_state) {
+ if (local_state) {
+ std::string policy_string = policy.SerializeAsString();
+ std::string encoded;
+ if (!base::Base64Encode(policy_string, &encoded)) {
+ LOG(ERROR) << "Can't encode policy in base64.";
+ return false;
+ }
+ local_state->SetString(prefs::kSignedSettingsCache, encoded);
+ return true;
+ }
+ return false;
+}
+
+bool Retrieve(em::PolicyData *policy, PrefService* local_state) {
+ if (local_state) {
+ std::string encoded =
+ local_state->GetString(prefs::kSignedSettingsCache);
+ std::string policy_string;
+ if (!base::Base64Decode(encoded, &policy_string)) {
+ // This is normal and happens on first boot.
+ VLOG(1) << "Can't decode policy from base64.";
+ return false;
+ }
+ return policy->ParseFromString(policy_string);
+ }
+ return false;
+}
+
+void Finalize(PrefService* local_state) {
+ // First we have to make sure the owner is really logged in because the key
+ // notification is generated on every cloud policy key rotation too.
+ OwnershipService::GetSharedInstance()->GetStatusAsync(
+ base::Bind(&ReloadSignedSettingsAndFinalize, local_state));
+}
+
+} // namespace signed_settings_cache
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/device_settings_cache.h b/chrome/browser/chromeos/settings/signed_settings_cache.h
index 8f6f7cf..ab9da59 100644
--- a/chrome/browser/chromeos/settings/device_settings_cache.h
+++ b/chrome/browser/chromeos/settings/signed_settings_cache.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_CACHE_H_
-#define CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_CACHE_H_
+#ifndef CHROME_BROWSER_CHROMEOS_SETTINGS_SIGNED_SETTINGS_CACHE_H_
+#define CHROME_BROWSER_CHROMEOS_SETTINGS_SIGNED_SETTINGS_CACHE_H_
namespace enterprise_management {
class PolicyData;
@@ -13,11 +13,11 @@ class PrefService;
namespace chromeos {
-// There is need (metrics at OOBE stage) to store settings (that normally would
-// go into DeviceSettings storage) before owner has been assigned (hence no key
-// is available). This set of functions serves as a transient storage in that
-// case.
-namespace device_settings_cache {
+// There is need (metrics at OOBE stage) to store settings
+// (that normally would go into SignedSettings storage)
+// before owner has been assigned (hence no key is available).
+// This set of functions serves as a transient storage in that case.
+namespace signed_settings_cache {
// Registers required pref section.
void RegisterPrefs(PrefService* local_state);
@@ -29,11 +29,11 @@ bool Store(const enterprise_management::PolicyData &policy,
bool Retrieve(enterprise_management::PolicyData *policy,
PrefService* local_state);
-// Call this after owner has been assigned to persist settings into
-// DeviceSettings storage.
+// Call this after owner has been assigned to persist settings
+// into SignedSettings storage.
void Finalize(PrefService* local_state);
-} // namespace device_settings_cache
+} // namespace signed_settings_cache
} // namespace chromeos
-#endif // CHROME_BROWSER_CHROMEOS_SETTINGS_DEVICE_SETTINGS_CACHE_H_
+#endif // CHROME_BROWSER_CHROMEOS_SETTINGS_SIGNED_SETTINGS_CACHE_H_
diff --git a/chrome/browser/chromeos/settings/device_settings_cache_unittest.cc b/chrome/browser/chromeos/settings/signed_settings_cache_unittest.cc
index d47021b5..de8bbc5 100644
--- a/chrome/browser/chromeos/settings/device_settings_cache_unittest.cc
+++ b/chrome/browser/chromeos/settings/signed_settings_cache_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/chromeos/settings/device_settings_cache.h"
+#include "chrome/browser/chromeos/settings/signed_settings_cache.h"
#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"
@@ -14,7 +14,7 @@ namespace em = enterprise_management;
namespace chromeos {
-class DeviceSettingsCacheTest : public testing::Test {
+class SignedSettingsCacheTest : public testing::Test {
protected:
virtual void SetUp() {
// prepare some data.
@@ -23,18 +23,18 @@ class DeviceSettingsCacheTest : public testing::Test {
pol.mutable_allow_new_users()->set_allow_new_users(false);
policy_.set_policy_value(pol.SerializeAsString());
- device_settings_cache::RegisterPrefs(&local_state_);
+ signed_settings_cache::RegisterPrefs(&local_state_);
}
TestingPrefService local_state_;
em::PolicyData policy_;
};
-TEST_F(DeviceSettingsCacheTest, Basic) {
- EXPECT_TRUE(device_settings_cache::Store(policy_, &local_state_));
+TEST_F(SignedSettingsCacheTest, Basic) {
+ EXPECT_TRUE(signed_settings_cache::Store(policy_, &local_state_));
em::PolicyData policy_out;
- EXPECT_TRUE(device_settings_cache::Retrieve(&policy_out, &local_state_));
+ EXPECT_TRUE(signed_settings_cache::Retrieve(&policy_out, &local_state_));
EXPECT_TRUE(policy_out.has_policy_type());
EXPECT_TRUE(policy_out.has_policy_value());
@@ -45,13 +45,13 @@ TEST_F(DeviceSettingsCacheTest, Basic) {
EXPECT_FALSE(pol.allow_new_users().allow_new_users());
}
-TEST_F(DeviceSettingsCacheTest, CorruptData) {
- EXPECT_TRUE(device_settings_cache::Store(policy_, &local_state_));
+TEST_F(SignedSettingsCacheTest, CorruptData) {
+ EXPECT_TRUE(signed_settings_cache::Store(policy_, &local_state_));
- local_state_.SetString(prefs::kDeviceSettingsCache, "blaaa");
+ local_state_.SetString(prefs::kSignedSettingsCache, "blaaa");
em::PolicyData policy_out;
- EXPECT_FALSE(device_settings_cache::Retrieve(&policy_out, &local_state_));
+ EXPECT_FALSE(signed_settings_cache::Retrieve(&policy_out, &local_state_));
}
} // namespace chromeos
diff --git a/chrome/browser/chromeos/settings/signed_settings_migration_helper.cc b/chrome/browser/chromeos/settings/signed_settings_migration_helper.cc
new file mode 100644
index 0000000..566f2b3
--- /dev/null
+++ b/chrome/browser/chromeos/settings/signed_settings_migration_helper.cc
@@ -0,0 +1,66 @@
+// Copyright (c) 2012 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/chromeos/settings/signed_settings_migration_helper.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "content/public/browser/notification_service.h"
+
+namespace chromeos {
+
+SignedSettingsMigrationHelper::SignedSettingsMigrationHelper()
+ : ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) {
+ registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_CHECKED,
+ content::NotificationService::AllSources());
+}
+
+SignedSettingsMigrationHelper::~SignedSettingsMigrationHelper() {
+ registrar_.RemoveAll();
+ migration_values_.Clear();
+}
+
+void SignedSettingsMigrationHelper::AddMigrationValue(const std::string& path,
+ base::Value* value) {
+ migration_values_.SetValue(path, value);
+}
+
+void SignedSettingsMigrationHelper::MigrateValues(void) {
+ ptr_factory_.InvalidateWeakPtrs();
+ OwnershipService::GetSharedInstance()->GetStatusAsync(
+ base::Bind(&SignedSettingsMigrationHelper::DoMigrateValues,
+ ptr_factory_.GetWeakPtr()));
+}
+
+// NotificationObserver overrides:
+void SignedSettingsMigrationHelper::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ if (type == chrome::NOTIFICATION_OWNERSHIP_CHECKED)
+ MigrateValues();
+}
+
+void SignedSettingsMigrationHelper::DoMigrateValues(
+ OwnershipService::Status status,
+ bool current_user_is_owner) {
+ // We can call StartStorePropertyOp in two cases - either if the owner is
+ // currently logged in and the policy can be updated immediately or if there
+ // is no owner yet in which case the value will be temporarily stored in the
+ // SignedSettingsCache until the device is owned. If none of these
+ // cases is met then we will wait for user change notification and retry.
+ if (current_user_is_owner || status != OwnershipService::OWNERSHIP_TAKEN) {
+ std::map<std::string, base::Value*>::const_iterator i;
+ for (i = migration_values_.begin(); i != migration_values_.end(); ++i) {
+ // Queue all values for storing.
+ CrosSettings::Get()->Set(i->first, *i->second);
+ }
+ migration_values_.Clear();
+ }
+}
+
+} // namespace chromeos
+
diff --git a/chrome/browser/chromeos/settings/signed_settings_migration_helper.h b/chrome/browser/chromeos/settings/signed_settings_migration_helper.h
new file mode 100644
index 0000000..13d5bfb
--- /dev/null
+++ b/chrome/browser/chromeos/settings/signed_settings_migration_helper.h
@@ -0,0 +1,59 @@
+// Copyright (c) 2012 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_SETTINGS_SIGNED_SETTINGS_MIGRATION_HELPER_H_
+#define CHROME_BROWSER_CHROMEOS_SETTINGS_SIGNED_SETTINGS_MIGRATION_HELPER_H_
+
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
+#include "chrome/browser/chromeos/settings/signed_settings_helper.h"
+#include "chrome/browser/prefs/pref_value_map.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
+
+namespace base {
+class Value;
+}
+
+namespace chromeos {
+
+// This class provides the means to migrate settings to the signed settings
+// store. It does one of three things - store the settings in the policy blob
+// immediately if the current user is the owner. Uses the
+// SignedSettingsCache if there is no owner yet, or waits for an
+// OWNERSHIP_CHECKED notification to delay the storing until the owner has
+// logged in.
+class SignedSettingsMigrationHelper : public content::NotificationObserver {
+ public:
+ SignedSettingsMigrationHelper();
+ virtual ~SignedSettingsMigrationHelper();
+
+ // Adds a value to be migrated. The class takes ownership of the |value|.
+ void AddMigrationValue(const std::string& path, base::Value* value);
+
+ // Initiates values migration. If the device is already owned this will
+ // happen immediately if not it will wait for ownership login and finish the
+ // migration then.
+ void MigrateValues(void);
+
+ // NotificationObserver overrides:
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
+
+ private:
+ // Does the actual migration when ownership has been confirmed.
+ void DoMigrateValues(OwnershipService::Status status,
+ bool current_user_is_owner);
+
+ content::NotificationRegistrar registrar_;
+ base::WeakPtrFactory<SignedSettingsMigrationHelper> ptr_factory_;
+ PrefValueMap migration_values_;
+
+ DISALLOW_COPY_AND_ASSIGN(SignedSettingsMigrationHelper);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_SETTINGS_SIGNED_SETTINGS_MIGRATION_HELPER_H_
diff --git a/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc b/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc
index 83c9d75..facadc3 100644
--- a/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/stub_cros_settings_provider.cc
@@ -73,6 +73,9 @@ bool StubCrosSettingsProvider::HandlesSetting(const std::string& path) const {
return std::find(kHandledSettings, end, path) != end;
}
+void StubCrosSettingsProvider::Reload() {
+}
+
void StubCrosSettingsProvider::DoSet(const std::string& path,
const base::Value& value) {
values_.SetValue(path, value.DeepCopy());
diff --git a/chrome/browser/chromeos/settings/stub_cros_settings_provider.h b/chrome/browser/chromeos/settings/stub_cros_settings_provider.h
index 9d88bf7..13a10cc 100644
--- a/chrome/browser/chromeos/settings/stub_cros_settings_provider.h
+++ b/chrome/browser/chromeos/settings/stub_cros_settings_provider.h
@@ -26,6 +26,7 @@ class StubCrosSettingsProvider : public CrosSettingsProvider {
virtual TrustedStatus PrepareTrustedValues(
const base::Closure& callback) OVERRIDE;
virtual bool HandlesSetting(const std::string& path) const OVERRIDE;
+ virtual void Reload() OVERRIDE;
private:
// CrosSettingsProvider implementation:
diff --git a/chrome/browser/chromeos/settings/system_settings_provider.cc b/chrome/browser/chromeos/settings/system_settings_provider.cc
index 75a8656..5148c74 100644
--- a/chrome/browser/chromeos/settings/system_settings_provider.cc
+++ b/chrome/browser/chromeos/settings/system_settings_provider.cc
@@ -60,6 +60,11 @@ bool SystemSettingsProvider::HandlesSetting(const std::string& path) const {
return path == kSystemTimezone;
}
+void SystemSettingsProvider::Reload() {
+ // TODO(pastarmovj): We can actually cache the timezone here to make returning
+ // it faster.
+}
+
void SystemSettingsProvider::TimezoneChanged(const icu::TimeZone& timezone) {
// Fires system setting change notification.
timezone_value_.reset(base::Value::CreateStringValue(
diff --git a/chrome/browser/chromeos/settings/system_settings_provider.h b/chrome/browser/chromeos/settings/system_settings_provider.h
index 578a1c5..49ef2aa 100644
--- a/chrome/browser/chromeos/settings/system_settings_provider.h
+++ b/chrome/browser/chromeos/settings/system_settings_provider.h
@@ -30,6 +30,7 @@ class SystemSettingsProvider : public CrosSettingsProvider,
virtual TrustedStatus PrepareTrustedValues(
const base::Closure& callback) OVERRIDE;
virtual bool HandlesSetting(const std::string& path) const OVERRIDE;
+ virtual void Reload() OVERRIDE;
// TimezoneSettings::Observer implementation.
virtual void TimezoneChanged(const icu::TimeZone& timezone) OVERRIDE;
diff --git a/chrome/browser/policy/device_policy_cache.cc b/chrome/browser/policy/device_policy_cache.cc
index 8f6fac2..d81567b 100644
--- a/chrome/browser/policy/device_policy_cache.cc
+++ b/chrome/browser/policy/device_policy_cache.cc
@@ -15,6 +15,9 @@
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/values.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/chromeos/settings/ownership_service.h"
+#include "chrome/browser/chromeos/settings/signed_settings_helper.h"
#include "chrome/browser/policy/app_pack_updater.h"
#include "chrome/browser/policy/cloud_policy_data_store.h"
#include "chrome/browser/policy/enterprise_install_attributes.h"
@@ -36,6 +39,69 @@ namespace em = enterprise_management;
namespace {
+// Stores policy, updates the owner key if required and reports the status
+// through a callback.
+class StorePolicyOperation : public chromeos::OwnerManager::KeyUpdateDelegate {
+ public:
+ typedef base::Callback<void(chromeos::SignedSettings::ReturnCode)> Callback;
+
+ StorePolicyOperation(chromeos::SignedSettingsHelper* signed_settings_helper,
+ const em::PolicyFetchResponse& policy,
+ const Callback& callback)
+ : signed_settings_helper_(signed_settings_helper),
+ policy_(policy),
+ callback_(callback),
+ weak_ptr_factory_(this) {
+ signed_settings_helper_->StartStorePolicyOp(
+ policy,
+ base::Bind(&StorePolicyOperation::OnStorePolicyCompleted,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+ virtual ~StorePolicyOperation() {
+ }
+
+ void OnStorePolicyCompleted(chromeos::SignedSettings::ReturnCode code) {
+ if (code != chromeos::SignedSettings::SUCCESS) {
+ callback_.Run(code);
+ delete this;
+ return;
+ }
+
+ if (policy_.has_new_public_key()) {
+ // The session manager has successfully done a key rotation. Replace the
+ // owner key also in chrome.
+ const std::string& new_key = policy_.new_public_key();
+ const std::vector<uint8> new_key_data(new_key.c_str(),
+ new_key.c_str() + new_key.size());
+ chromeos::OwnershipService::GetSharedInstance()->StartUpdateOwnerKey(
+ new_key_data, this);
+ return;
+ } else {
+ chromeos::CrosSettings::Get()->ReloadProviders();
+ callback_.Run(chromeos::SignedSettings::SUCCESS);
+ delete this;
+ return;
+ }
+ }
+
+ // OwnerManager::KeyUpdateDelegate implementation:
+ virtual void OnKeyUpdated() OVERRIDE {
+ chromeos::CrosSettings::Get()->ReloadProviders();
+ callback_.Run(chromeos::SignedSettings::SUCCESS);
+ delete this;
+ }
+
+ private:
+
+ chromeos::SignedSettingsHelper* signed_settings_helper_;
+ em::PolicyFetchResponse policy_;
+ Callback callback_;
+
+ base::WeakPtrFactory<StorePolicyOperation> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(StorePolicyOperation);
+};
+
// Decodes a protobuf integer to an IntegerValue. The caller assumes ownership
// of the return Value*. Returns NULL in case the input value is out of bounds.
Value* DecodeIntegerValue(google::protobuf::int64 value) {
@@ -73,30 +139,29 @@ DevicePolicyCache::DevicePolicyCache(
EnterpriseInstallAttributes* install_attributes)
: data_store_(data_store),
install_attributes_(install_attributes),
- device_settings_service_(chromeos::DeviceSettingsService::Get()),
+ signed_settings_helper_(chromeos::SignedSettingsHelper::Get()),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
policy_fetch_pending_(false) {
- device_settings_service_->AddObserver(this);
}
DevicePolicyCache::DevicePolicyCache(
CloudPolicyDataStore* data_store,
EnterpriseInstallAttributes* install_attributes,
- chromeos::DeviceSettingsService* device_settings_service)
+ chromeos::SignedSettingsHelper* signed_settings_helper)
: data_store_(data_store),
install_attributes_(install_attributes),
- device_settings_service_(device_settings_service),
+ signed_settings_helper_(signed_settings_helper),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
policy_fetch_pending_(false) {
- device_settings_service_->AddObserver(this);
}
DevicePolicyCache::~DevicePolicyCache() {
- device_settings_service_->RemoveObserver(this);
}
void DevicePolicyCache::Load() {
- DeviceSettingsUpdated();
+ signed_settings_helper_->StartRetrievePolicyOp(
+ base::Bind(&DevicePolicyCache::OnRetrievePolicyCompleted,
+ weak_ptr_factory_.GetWeakPtr()));
}
bool DevicePolicyCache::SetPolicy(const em::PolicyFetchResponse& policy) {
@@ -140,11 +205,11 @@ bool DevicePolicyCache::SetPolicy(const em::PolicyFetchResponse& policy) {
set_last_policy_refresh_time(base::Time::NowFromSystemTime());
// Start a store operation.
- policy_fetch_pending_ = true;
- device_settings_service_->Store(
- policy.SerializeAsString(),
+ StorePolicyOperation::Callback callback =
base::Bind(&DevicePolicyCache::PolicyStoreOpCompleted,
- weak_ptr_factory_.GetWeakPtr()));
+ weak_ptr_factory_.GetWeakPtr());
+ new StorePolicyOperation(signed_settings_helper_, policy, callback);
+ policy_fetch_pending_ = true;
return true;
}
@@ -160,27 +225,17 @@ void DevicePolicyCache::SetFetchingDone() {
CloudPolicyCacheBase::SetFetchingDone();
}
-void DevicePolicyCache::OwnershipStatusChanged() {}
-
-void DevicePolicyCache::DeviceSettingsUpdated() {
+void DevicePolicyCache::OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::ReturnCode code,
+ const em::PolicyFetchResponse& policy) {
DCHECK(CalledOnValidThread());
- chromeos::DeviceSettingsService::Status status =
- device_settings_service_->status();
- const em::PolicyData* policy_data = device_settings_service_->policy_data();
- if (status == chromeos::DeviceSettingsService::STORE_SUCCESS &&
- !policy_data) {
- // Initial policy load is still pending.
- return;
- }
-
if (!IsReady()) {
std::string device_token;
- InstallInitialPolicy(status, policy_data, &device_token);
+ InstallInitialPolicy(code, policy, &device_token);
SetTokenAndFlagReady(device_token);
} else { // In other words, IsReady() == true
- if (status != chromeos::DeviceSettingsService::STORE_SUCCESS ||
- !policy_data) {
- if (status == chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR) {
+ if (code != chromeos::SignedSettings::SUCCESS) {
+ if (code == chromeos::SignedSettings::BAD_SIGNATURE) {
UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyFetchBadSignature,
kMetricPolicySize);
InformNotifier(CloudPolicySubsystem::LOCAL_ERROR,
@@ -192,16 +247,14 @@ void DevicePolicyCache::DeviceSettingsUpdated() {
CloudPolicySubsystem::POLICY_LOCAL_ERROR);
}
} else {
- em::PolicyFetchResponse policy_response;
- CHECK(policy_data->SerializeToString(
- policy_response.mutable_policy_data()));
- bool ok = SetPolicyInternal(policy_response, NULL, false);
+ bool ok = SetPolicyInternal(policy, NULL, false);
if (ok) {
UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyFetchOK,
kMetricPolicySize);
}
}
}
+ CheckFetchingDone();
}
bool DevicePolicyCache::DecodePolicyData(const em::PolicyData& policy_data,
@@ -215,14 +268,13 @@ bool DevicePolicyCache::DecodePolicyData(const em::PolicyData& policy_data,
return true;
}
-void DevicePolicyCache::PolicyStoreOpCompleted() {
+void DevicePolicyCache::PolicyStoreOpCompleted(
+ chromeos::SignedSettings::ReturnCode code) {
DCHECK(CalledOnValidThread());
- chromeos::DeviceSettingsService::Status status =
- device_settings_service_->status();
- if (status != chromeos::DeviceSettingsService::STORE_SUCCESS) {
+ if (code != chromeos::SignedSettings::SUCCESS) {
UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyStoreFailed,
kMetricPolicySize);
- if (status == chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR) {
+ if (code == chromeos::SignedSettings::BAD_SIGNATURE) {
UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyFetchBadSignature,
kMetricPolicySize);
InformNotifier(CloudPolicySubsystem::LOCAL_ERROR,
@@ -238,21 +290,24 @@ void DevicePolicyCache::PolicyStoreOpCompleted() {
}
UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyStoreSucceeded,
kMetricPolicySize);
-
- CheckFetchingDone();
+ signed_settings_helper_->StartRetrievePolicyOp(
+ base::Bind(&DevicePolicyCache::OnRetrievePolicyCompleted,
+ weak_ptr_factory_.GetWeakPtr()));
}
void DevicePolicyCache::InstallInitialPolicy(
- chromeos::DeviceSettingsService::Status status,
- const em::PolicyData* policy_data,
+ chromeos::SignedSettings::ReturnCode code,
+ const em::PolicyFetchResponse& policy,
std::string* device_token) {
- if (status == chromeos::DeviceSettingsService::STORE_NO_POLICY ||
- status == chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE) {
+ if (code == chromeos::SignedSettings::NOT_FOUND ||
+ code == chromeos::SignedSettings::KEY_UNAVAILABLE ||
+ !policy.has_policy_data()) {
InformNotifier(CloudPolicySubsystem::UNENROLLED,
CloudPolicySubsystem::NO_DETAILS);
return;
}
- if (!policy_data) {
+ em::PolicyData policy_data;
+ if (!policy_data.ParseFromString(policy.policy_data())) {
LOG(WARNING) << "Failed to parse PolicyData protobuf.";
UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyLoadFailed,
kMetricPolicySize);
@@ -260,8 +315,8 @@ void DevicePolicyCache::InstallInitialPolicy(
CloudPolicySubsystem::POLICY_LOCAL_ERROR);
return;
}
- if (!policy_data->has_request_token() ||
- policy_data->request_token().empty()) {
+ if (!policy_data.has_request_token() ||
+ policy_data.request_token().empty()) {
SetUnmanagedInternal(base::Time::NowFromSystemTime());
InformNotifier(CloudPolicySubsystem::UNMANAGED,
CloudPolicySubsystem::NO_DETAILS);
@@ -270,7 +325,7 @@ void DevicePolicyCache::InstallInitialPolicy(
// SetPolicyInternal() here.
return;
}
- if (!policy_data->has_username() || !policy_data->has_device_id()) {
+ if (!policy_data.has_username() || !policy_data.has_device_id()) {
UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyLoadFailed,
kMetricPolicySize);
InformNotifier(CloudPolicySubsystem::LOCAL_ERROR,
@@ -279,17 +334,26 @@ void DevicePolicyCache::InstallInitialPolicy(
}
UMA_HISTOGRAM_ENUMERATION(kMetricPolicy, kMetricPolicyLoadSucceeded,
kMetricPolicySize);
- data_store_->set_user_name(policy_data->username());
- data_store_->set_device_id(policy_data->device_id());
- *device_token = policy_data->request_token();
+ data_store_->set_user_name(policy_data.username());
+ data_store_->set_device_id(policy_data.device_id());
+ *device_token = policy_data.request_token();
base::Time timestamp;
- em::PolicyFetchResponse policy_response;
- CHECK(policy_data->SerializeToString(policy_response.mutable_policy_data()));
- if (SetPolicyInternal(policy_response, &timestamp, true))
+ if (SetPolicyInternal(policy, &timestamp, true))
set_last_policy_refresh_time(timestamp);
}
void DevicePolicyCache::SetTokenAndFlagReady(const std::string& device_token) {
+ // Make sure that we only start device policy fetches once device settings are
+ // available in order to ensure the first device policy fetch uploads the
+ // configured reporting bits.
+ if (chromeos::CrosSettingsProvider::TEMPORARILY_UNTRUSTED ==
+ chromeos::CrosSettings::Get()->PrepareTrustedValues(
+ base::Bind(&DevicePolicyCache::SetTokenAndFlagReady,
+ weak_ptr_factory_.GetWeakPtr(),
+ device_token))) {
+ return;
+ }
+
// We need to call SetDeviceToken unconditionally to indicate the cache has
// finished loading.
data_store_->SetDeviceToken(device_token, true);
diff --git a/chrome/browser/policy/device_policy_cache.h b/chrome/browser/policy/device_policy_cache.h
index 0f52fd8..573a514 100644
--- a/chrome/browser/policy/device_policy_cache.h
+++ b/chrome/browser/policy/device_policy_cache.h
@@ -6,9 +6,19 @@
#define CHROME_BROWSER_POLICY_DEVICE_POLICY_CACHE_H_
#include "base/memory/weak_ptr.h"
-#include "chrome/browser/chromeos/settings/device_settings_service.h"
+#include "chrome/browser/chromeos/settings/signed_settings.h"
#include "chrome/browser/policy/cloud_policy_cache_base.h"
+namespace chromeos {
+class SignedSettingsHelper;
+} // namespace chromeos
+
+namespace enterprise_management {
+class ChromeDeviceSettingsProto;
+class PolicyData;
+class PolicyFetchResponse;
+} // namespace enterprise_management
+
namespace policy {
class CloudPolicyDataStore;
@@ -16,9 +26,8 @@ class EnterpriseInstallAttributes;
class PolicyMap;
// CloudPolicyCacheBase implementation that persists policy information
-// to ChromeOS' session manager (via DeviceSettingsService).
-class DevicePolicyCache : public CloudPolicyCacheBase,
- public chromeos::DeviceSettingsService::Observer {
+// to ChromeOS' session manager (via SignedSettingsHelper).
+class DevicePolicyCache : public CloudPolicyCacheBase {
public:
DevicePolicyCache(CloudPolicyDataStore* data_store,
EnterpriseInstallAttributes* install_attributes);
@@ -31,28 +40,27 @@ class DevicePolicyCache : public CloudPolicyCacheBase,
virtual void SetUnmanaged() OVERRIDE;
virtual void SetFetchingDone() OVERRIDE;
- // DeviceSettingsService::Observer implementation:
- virtual void OwnershipStatusChanged() OVERRIDE;
- virtual void DeviceSettingsUpdated() OVERRIDE;
+ void OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::ReturnCode code,
+ const enterprise_management::PolicyFetchResponse& policy);
private:
friend class DevicePolicyCacheTest;
friend class DevicePolicyCacheTestHelper;
- // Alternate c'tor allowing tests to mock out the DeviceSettingsService
+ // Alternate c'tor allowing tests to mock out the SignedSettingsHelper
// singleton.
DevicePolicyCache(
CloudPolicyDataStore* data_store,
EnterpriseInstallAttributes* install_attributes,
- chromeos::DeviceSettingsService* device_settings_service);
+ chromeos::SignedSettingsHelper* signed_settings_helper);
// CloudPolicyCacheBase implementation:
virtual bool DecodePolicyData(
const enterprise_management::PolicyData& policy_data,
PolicyMap* policies) OVERRIDE;
- // Handles completion of policy store operations.
- void PolicyStoreOpCompleted();
+ void PolicyStoreOpCompleted(chromeos::SignedSettings::ReturnCode code);
// Checks with immutable attributes whether this is an enterprise device and
// read the registration user if this is the case.
@@ -61,8 +69,8 @@ class DevicePolicyCache : public CloudPolicyCacheBase,
// Tries to install the initial device policy retrieved from signed settings.
// Fills in |device_token| if it could be extracted from the loaded protobuf.
void InstallInitialPolicy(
- chromeos::DeviceSettingsService::Status status,
- const enterprise_management::PolicyData* policy_data,
+ chromeos::SignedSettings::ReturnCode code,
+ const enterprise_management::PolicyFetchResponse& policy,
std::string* device_token);
// Ensures that CrosSettings has established trust on the reporting prefs and
@@ -104,7 +112,7 @@ class DevicePolicyCache : public CloudPolicyCacheBase,
CloudPolicyDataStore* data_store_;
EnterpriseInstallAttributes* install_attributes_;
- chromeos::DeviceSettingsService* device_settings_service_;
+ chromeos::SignedSettingsHelper* signed_settings_helper_;
base::WeakPtrFactory<DevicePolicyCache> weak_ptr_factory_;
diff --git a/chrome/browser/policy/device_policy_cache_unittest.cc b/chrome/browser/policy/device_policy_cache_unittest.cc
index 169398a..4762ab4 100644
--- a/chrome/browser/policy/device_policy_cache_unittest.cc
+++ b/chrome/browser/policy/device_policy_cache_unittest.cc
@@ -4,92 +4,106 @@
#include "chrome/browser/policy/device_policy_cache.h"
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/file_path.h"
-#include "base/memory/ref_counted.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/chromeos/cros/cryptohome_library.h"
-#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
-#include "chrome/browser/chromeos/settings/mock_owner_key_util.h"
+#include "chrome/browser/chromeos/settings/mock_signed_settings_helper.h"
#include "chrome/browser/policy/cloud_policy_data_store.h"
#include "chrome/browser/policy/enterprise_install_attributes.h"
-#include "chrome/browser/policy/policy_builder.h"
#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
-#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "content/public/test/test_browser_thread.h"
#include "policy/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-using ::testing::Mock;
-
namespace em = enterprise_management;
namespace policy {
namespace {
+// Test registration user name.
+const char kTestUser[] = "test@example.com";
+
+using ::chromeos::SignedSettings;
+using ::testing::InSequence;
+using ::testing::Mock;
+using ::testing::SaveArg;
+using ::testing::_;
+
class MockCloudPolicyCacheObserver : public CloudPolicyCacheBase::Observer {
public:
- virtual ~MockCloudPolicyCacheObserver() {}
-
MOCK_METHOD1(OnCacheGoingAway, void(CloudPolicyCacheBase*));
MOCK_METHOD1(OnCacheUpdate, void(CloudPolicyCacheBase*));
};
+void CreatePolicy(em::PolicyFetchResponse* policy,
+ const std::string& user,
+ em::ChromeDeviceSettingsProto& settings) {
+ // This method omits a few fields which currently aren't needed by tests:
+ // timestamp, machine_name, public key info.
+ em::PolicyData signed_response;
+ signed_response.set_username(user);
+ signed_response.set_request_token("dmtoken");
+ signed_response.set_device_id("deviceid");
+ EXPECT_TRUE(
+ settings.SerializeToString(signed_response.mutable_policy_value()));
+ std::string serialized_signed_response;
+ EXPECT_TRUE(signed_response.SerializeToString(&serialized_signed_response));
+ policy->set_policy_data(serialized_signed_response);
+}
+
+void CreateRefreshRatePolicy(em::PolicyFetchResponse* policy,
+ const std::string& user,
+ int refresh_rate) {
+ em::ChromeDeviceSettingsProto settings;
+ settings.mutable_device_policy_refresh_rate()->
+ set_device_policy_refresh_rate(refresh_rate);
+ CreatePolicy(policy, user, settings);
+}
+
+void CreateProxyPolicy(em::PolicyFetchResponse* policy,
+ const std::string& user,
+ const std::string& proxy_mode,
+ const std::string& proxy_server,
+ const std::string& proxy_pac_url,
+ const std::string& proxy_bypass_list) {
+ em::ChromeDeviceSettingsProto settings;
+ em::DeviceProxySettingsProto* proxy_settings =
+ settings.mutable_device_proxy_settings();
+ proxy_settings->set_proxy_mode(proxy_mode);
+ proxy_settings->set_proxy_server(proxy_server);
+ proxy_settings->set_proxy_pac_url(proxy_pac_url);
+ proxy_settings->set_proxy_bypass_list(proxy_bypass_list);
+ CreatePolicy(policy, user, settings);
+}
+
} // namespace
class DevicePolicyCacheTest : public testing::Test {
protected:
DevicePolicyCacheTest()
: cryptohome_(chromeos::CryptohomeLibrary::GetImpl(true)),
- owner_key_util_(new chromeos::MockOwnerKeyUtil()),
install_attributes_(cryptohome_.get()),
message_loop_(MessageLoop::TYPE_UI),
ui_thread_(content::BrowserThread::UI, &message_loop_),
file_thread_(content::BrowserThread::FILE, &message_loop_) {}
- virtual void SetUp() OVERRIDE {
- policy_.payload().mutable_device_policy_refresh_rate()->
- set_device_policy_refresh_rate(120);
- policy_.Build();
- device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
-
- owner_key_util_->SetPublicKeyFromPrivateKey(policy_.signing_key());
-
- device_settings_service_.Initialize(&device_settings_test_helper_,
- owner_key_util_);
-
- data_store_.reset(CloudPolicyDataStore::CreateForDevicePolicies());
+ virtual void SetUp() {
+ data_store_.reset(CloudPolicyDataStore::CreateForUserPolicies());
cache_.reset(new DevicePolicyCache(data_store_.get(),
&install_attributes_,
- &device_settings_service_));
+ &signed_settings_helper_));
cache_->AddObserver(&observer_);
}
- virtual void TearDown() OVERRIDE {
- device_settings_test_helper_.Flush();
- device_settings_service_.Shutdown();
-
+ virtual void TearDown() {
cache_->RemoveObserver(&observer_);
cache_.reset();
}
- void Startup() {
- EXPECT_CALL(observer_, OnCacheUpdate(cache_.get()));
- device_settings_service_.Load();
- device_settings_test_helper_.Flush();
- cache_->Load();
- Mock::VerifyAndClearExpectations(&observer_);
- }
-
- void MakeEnterpriseDevice() {
+ void MakeEnterpriseDevice(const char* registration_user) {
ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS,
install_attributes_.LockDevice(
- policy_.policy_data().username(),
+ registration_user,
DEVICE_MODE_ENTERPRISE,
std::string()));
}
@@ -99,16 +113,11 @@ class DevicePolicyCacheTest : public testing::Test {
}
MockCloudPolicyCacheObserver observer_;
-
scoped_ptr<chromeos::CryptohomeLibrary> cryptohome_;
- scoped_refptr<chromeos::MockOwnerKeyUtil> owner_key_util_;
- chromeos::DeviceSettingsTestHelper device_settings_test_helper_;
- chromeos::DeviceSettingsService device_settings_service_;
EnterpriseInstallAttributes install_attributes_;
-
scoped_ptr<CloudPolicyDataStore> data_store_;
+ chromeos::MockSignedSettingsHelper signed_settings_helper_;
scoped_ptr<DevicePolicyCache> cache_;
- DevicePolicyBuilder policy_;
MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
@@ -118,134 +127,192 @@ class DevicePolicyCacheTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(DevicePolicyCacheTest);
};
-TEST_F(DevicePolicyCacheTest, ColdStartup) {
- EXPECT_CALL(observer_, OnCacheUpdate(cache_.get())).Times(0);
- cache_->Load();
- Mock::VerifyAndClearExpectations(&observer_);
-
+TEST_F(DevicePolicyCacheTest, Startup) {
+ em::PolicyFetchResponse policy;
+ CreateRefreshRatePolicy(&policy, kTestUser, 120);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ policy));
EXPECT_CALL(observer_, OnCacheUpdate(cache_.get()));
- device_settings_service_.Load();
- device_settings_test_helper_.Flush();
- Mock::VerifyAndClearExpectations(&observer_);
-
- base::FundamentalValue expected(120);
- EXPECT_TRUE(Value::Equals(&expected,
- GetPolicy(key::kDevicePolicyRefreshRate)));
-}
-
-TEST_F(DevicePolicyCacheTest, WarmStartup) {
- Startup();
-
+ cache_->Load();
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
base::FundamentalValue expected(120);
EXPECT_TRUE(Value::Equals(&expected,
GetPolicy(key::kDevicePolicyRefreshRate)));
}
TEST_F(DevicePolicyCacheTest, SetPolicy) {
- MakeEnterpriseDevice();
- Startup();
+ InSequence s;
+
+ MakeEnterpriseDevice(kTestUser);
+ // Startup.
+ em::PolicyFetchResponse policy;
+ CreateRefreshRatePolicy(&policy, kTestUser, 120);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ policy));
+ EXPECT_CALL(observer_, OnCacheUpdate(cache_.get()));
+ cache_->Load();
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
+ Mock::VerifyAndClearExpectations(&observer_);
base::FundamentalValue expected(120);
EXPECT_TRUE(Value::Equals(&expected,
GetPolicy(key::kDevicePolicyRefreshRate)));
// Set new policy information.
- policy_.payload().mutable_device_policy_refresh_rate()->
- set_device_policy_refresh_rate(300);
- policy_.Build();
+ chromeos::SignedSettingsHelper::StorePolicyCallback store_callback;
+ em::PolicyFetchResponse new_policy;
+ CreateRefreshRatePolicy(&new_policy, kTestUser, 300);
+ EXPECT_CALL(signed_settings_helper_, StartStorePolicyOp(_, _)).WillOnce(
+ SaveArg<1>(&store_callback));
EXPECT_CALL(observer_, OnCacheUpdate(cache_.get())).Times(0);
- EXPECT_TRUE(cache_->SetPolicy(policy_.policy()));
+ EXPECT_TRUE(cache_->SetPolicy(new_policy));
cache_->SetFetchingDone();
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
Mock::VerifyAndClearExpectations(&observer_);
+ ASSERT_FALSE(store_callback.is_null());
+ chromeos::SignedSettingsHelper::RetrievePolicyCallback retrieve_callback;
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ SaveArg<0>(&retrieve_callback));
EXPECT_CALL(observer_, OnCacheUpdate(cache_.get())).Times(0);
- device_settings_test_helper_.FlushStore();
+ store_callback.Run(chromeos::SignedSettings::SUCCESS);
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
Mock::VerifyAndClearExpectations(&observer_);
+ ASSERT_FALSE(retrieve_callback.is_null());
// Cache update notification should only fire in the retrieve callback.
EXPECT_CALL(observer_, OnCacheUpdate(cache_.get()));
- device_settings_test_helper_.Flush();
- Mock::VerifyAndClearExpectations(&observer_);
-
+ retrieve_callback.Run(chromeos::SignedSettings::SUCCESS, new_policy);
base::FundamentalValue updated_expected(300);
EXPECT_TRUE(Value::Equals(&updated_expected,
GetPolicy(key::kDevicePolicyRefreshRate)));
+ Mock::VerifyAndClearExpectations(&observer_);
cache_->RemoveObserver(&observer_);
}
TEST_F(DevicePolicyCacheTest, SetPolicyOtherUserSameDomain) {
- MakeEnterpriseDevice();
- Startup();
+ InSequence s;
- // Set new policy information. This should succeed as the domain is the same.
- policy_.policy_data().set_username("another_user@example.com");
- policy_.Build();
+ MakeEnterpriseDevice(kTestUser);
+ // Startup.
+ em::PolicyFetchResponse policy;
+ CreateRefreshRatePolicy(&policy, kTestUser, 120);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ policy));
EXPECT_CALL(observer_, OnCacheUpdate(cache_.get()));
- EXPECT_TRUE(cache_->SetPolicy(policy_.policy()));
- device_settings_test_helper_.Flush();
+ cache_->Load();
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
+
+ // Set new policy information. This should succeed as the domain is the same.
+ chromeos::SignedSettingsHelper::StorePolicyCallback store_callback;
+ em::PolicyFetchResponse new_policy;
+ CreateRefreshRatePolicy(&new_policy, "another_user@example.com", 300);
+ EXPECT_CALL(signed_settings_helper_, StartStorePolicyOp(_, _)).WillOnce(
+ SaveArg<1>(&store_callback));
+ EXPECT_CALL(observer_, OnCacheUpdate(cache_.get())).Times(1);
+ EXPECT_TRUE(cache_->SetPolicy(new_policy));
+ cache_->SetFetchingDone();
+ store_callback.Run(chromeos::SignedSettings::OPERATION_FAILED);
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
Mock::VerifyAndClearExpectations(&observer_);
- EXPECT_EQ(policy_.GetBlob(), device_settings_test_helper_.policy_blob());
}
TEST_F(DevicePolicyCacheTest, SetPolicyOtherUserOtherDomain) {
- MakeEnterpriseDevice();
- Startup();
+ InSequence s;
+
+ MakeEnterpriseDevice(kTestUser);
+
+ // Startup.
+ em::PolicyFetchResponse policy;
+ CreateRefreshRatePolicy(&policy, kTestUser, 120);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ policy));
+ EXPECT_CALL(observer_, OnCacheUpdate(cache_.get()));
+ cache_->Load();
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
// Set new policy information. This should fail because the user is from
// different domain.
- policy_.policy_data().set_username("foreign_user@hackers.com");
- policy_.Build();
- EXPECT_NE(policy_.GetBlob(), device_settings_test_helper_.policy_blob());
+ em::PolicyFetchResponse new_policy;
+ CreateRefreshRatePolicy(&new_policy, "foreign_user@hackers.com", 300);
+ EXPECT_CALL(signed_settings_helper_, StartStorePolicyOp(_, _)).Times(0);
+ EXPECT_FALSE(cache_->SetPolicy(new_policy));
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
- EXPECT_FALSE(cache_->SetPolicy(policy_.policy()));
- device_settings_test_helper_.Flush();
- EXPECT_NE(policy_.GetBlob(), device_settings_test_helper_.policy_blob());
+ base::FundamentalValue expected(120);
+ EXPECT_TRUE(Value::Equals(&expected,
+ GetPolicy(key::kDevicePolicyRefreshRate)));
}
TEST_F(DevicePolicyCacheTest, SetPolicyNonEnterpriseDevice) {
- Startup();
+ InSequence s;
+
+ // Startup.
+ em::PolicyFetchResponse policy;
+ CreateRefreshRatePolicy(&policy, kTestUser, 120);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ policy));
+ EXPECT_CALL(observer_, OnCacheUpdate(cache_.get()));
+ cache_->Load();
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
// Set new policy information. This should fail due to invalid user.
- device_settings_test_helper_.set_policy_blob(std::string());
+ em::PolicyFetchResponse new_policy;
+ CreateRefreshRatePolicy(&new_policy, kTestUser, 120);
+ EXPECT_CALL(signed_settings_helper_, StartStorePolicyOp(_, _)).Times(0);
+ EXPECT_FALSE(cache_->SetPolicy(new_policy));
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
- EXPECT_FALSE(cache_->SetPolicy(policy_.policy()));
- device_settings_test_helper_.Flush();
- EXPECT_TRUE(device_settings_test_helper_.policy_blob().empty());
+ base::FundamentalValue expected(120);
+ EXPECT_TRUE(Value::Equals(&expected,
+ GetPolicy(key::kDevicePolicyRefreshRate)));
}
TEST_F(DevicePolicyCacheTest, SetProxyPolicy) {
- MakeEnterpriseDevice();
-
- em::DeviceProxySettingsProto proxy_settings;
- proxy_settings.set_proxy_mode("direct");
- proxy_settings.set_proxy_server("http://proxy:8080");
- proxy_settings.set_proxy_pac_url("http://proxy:8080/pac.js");
- proxy_settings.set_proxy_bypass_list("127.0.0.1,example.com");
- policy_.payload().mutable_device_proxy_settings()->CopyFrom(proxy_settings);
- policy_.Build();
- device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
- Startup();
-
+ MakeEnterpriseDevice(kTestUser);
+
+ // Startup.
+ em::PolicyFetchResponse policy;
+ CreateProxyPolicy(&policy, kTestUser, "direct", "http://proxy:8080",
+ "http://proxy:8080/pac.js", "127.0.0.1,example.com");
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ policy));
+ EXPECT_CALL(observer_, OnCacheUpdate(cache_.get()));
+ cache_->Load();
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
DictionaryValue expected;
- expected.SetString(key::kProxyMode, proxy_settings.proxy_mode());
- expected.SetString(key::kProxyServer, proxy_settings.proxy_server());
- expected.SetString(key::kProxyPacUrl, proxy_settings.proxy_pac_url());
- expected.SetString(key::kProxyBypassList, proxy_settings.proxy_bypass_list());
- EXPECT_TRUE(Value::Equals(&expected, GetPolicy(key::kProxySettings)));
+ expected.SetString(key::kProxyMode, "direct");
+ expected.SetString(key::kProxyServer, "http://proxy:8080");
+ expected.SetString(key::kProxyPacUrl, "http://proxy:8080/pac.js");
+ expected.SetString(key::kProxyBypassList, "127.0.0.1,example.com");
+ EXPECT_TRUE(Value::Equals(&expected,
+ GetPolicy(key::kProxySettings)));
}
TEST_F(DevicePolicyCacheTest, SetDeviceNetworkConfigurationPolicy) {
- MakeEnterpriseDevice();
+ MakeEnterpriseDevice(kTestUser);
+ // Startup.
std::string fake_config("{ 'NetworkConfigurations': [] }");
- policy_.payload().mutable_open_network_configuration()->
- set_open_network_configuration(fake_config);
- policy_.Build();
- device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
- Startup();
-
+ em::PolicyFetchResponse policy;
+ em::ChromeDeviceSettingsProto settings;
+ settings.mutable_open_network_configuration()->set_open_network_configuration(
+ fake_config);
+ CreatePolicy(&policy, kTestUser, settings);
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ policy));
+ EXPECT_CALL(observer_, OnCacheUpdate(cache_.get()));
+ cache_->Load();
+ Mock::VerifyAndClearExpectations(&signed_settings_helper_);
StringValue expected_config(fake_config);
EXPECT_TRUE(
Value::Equals(&expected_config,
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 72daab2..1e2a824 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -95,7 +95,7 @@
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/preferences.h"
#include "chrome/browser/chromeos/proxy_config_service_impl.h"
-#include "chrome/browser/chromeos/settings/device_settings_cache.h"
+#include "chrome/browser/chromeos/settings/signed_settings_cache.h"
#include "chrome/browser/chromeos/status/data_promo_notification.h"
#include "chrome/browser/policy/auto_enrollment_client.h"
#include "chrome/browser/policy/device_status_collector.h"
@@ -179,7 +179,7 @@ void RegisterLocalState(PrefService* local_state) {
chromeos::ProxyConfigServiceImpl::RegisterPrefs(local_state);
chromeos::UserManager::RegisterPrefs(local_state);
chromeos::ServicesCustomizationDocument::RegisterPrefs(local_state);
- chromeos::device_settings_cache::RegisterPrefs(local_state);
+ chromeos::signed_settings_cache::RegisterPrefs(local_state);
chromeos::WallpaperManager::RegisterPrefs(local_state);
chromeos::WizardController::RegisterPrefs(local_state);
policy::AutoEnrollmentClient::RegisterPrefs(local_state);