summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrsorokin@chromium.org <rsorokin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-13 16:04:04 +0000
committerrsorokin@chromium.org <rsorokin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-13 16:05:23 +0000
commit815dfac97145b951ffd8c179d56f025371c8edd2 (patch)
tree527bcfdecfa76582c974b803631043f877ab0b63
parentbcd365e5495e53cc5e512fbc1fe87119af30e8e6 (diff)
downloadchromium_src-815dfac97145b951ffd8c179d56f025371c8edd2.zip
chromium_src-815dfac97145b951ffd8c179d56f025371c8edd2.tar.gz
chromium_src-815dfac97145b951ffd8c179d56f025371c8edd2.tar.bz2
Providing more information on why certain users can't be added to multi-profile
session BUG=388279 Review URL: https://codereview.chromium.org/374853002 Cr-Commit-Position: refs/heads/master@{#289304} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289304 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ash/ash_strings.grd3
-rw-r--r--ash/session/session_state_delegate.h3
-rw-r--r--ash/shell/shell_delegate_impl.cc3
-rw-r--r--ash/system/user/user_view.cc17
-rw-r--r--ash/test/test_session_state_delegate.cc5
-rw-r--r--ash/test/test_session_state_delegate.h1
-rw-r--r--chrome/app/chromeos_strings.grdp2
-rw-r--r--chrome/browser/chromeos/login/users/chrome_user_manager.cc4
-rw-r--r--chrome/browser/chromeos/login/users/multi_profile_user_controller.cc71
-rw-r--r--chrome/browser/chromeos/login/users/multi_profile_user_controller.h5
-rw-r--r--chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc131
-rw-r--r--chrome/browser/chromeos/profiles/profile_helper.h1
-rw-r--r--chrome/browser/ui/ash/session_state_delegate_chromeos.cc7
-rw-r--r--chrome/browser/ui/ash/session_state_delegate_chromeos.h1
-rw-r--r--chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc124
-rw-r--r--chrome/browser/ui/ash/session_state_delegate_views.cc4
-rw-r--r--chrome/browser/ui/ash/session_state_delegate_views.h1
17 files changed, 299 insertions, 84 deletions
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index 11c3646..074cdb1 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -250,6 +250,9 @@ Press Ctrl+Alt+Z to disable.
<message name="IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER" desc="The error message when the user has reached the limit of multi profile users.">
You can only have up to three accounts in multiple sign-in.
</message>
+ <message name="IDS_ASH_STATUS_TRAY_MESSAGE_NOT_ALLOWED_PRIMARY_USER" desc="The error message when the primary user forbids multiple signin because of not-allowed policy or because of usage policy-pushed certificates.">
+ The administrator for this account has disallowed multiple sign-in.
+ </message>
<message name="IDS_ASH_STATUS_TRAY_BLUETOOTH" desc="The label used as the header in the bluetooth popup.">
Bluetooth
diff --git a/ash/session/session_state_delegate.h b/ash/session/session_state_delegate.h
index c1d4720..c1c0713 100644
--- a/ash/session/session_state_delegate.h
+++ b/ash/session/session_state_delegate.h
@@ -134,6 +134,9 @@ class ASH_EXPORT SessionStateDelegate {
// ordering as GetLoggedInUsers.
virtual void CycleActiveUser(CycleUser cycle_user) = 0;
+ // Returns true if primary user policy does not forbid multiple signin.
+ virtual bool IsMultiProfileAllowedByPrimaryUserPolicy() const = 0;
+
// Adds or removes sessions state observer.
virtual void AddSessionStateObserver(SessionStateObserver* observer) = 0;
virtual void RemoveSessionStateObserver(SessionStateObserver* observer) = 0;
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc
index 6261e1e..02c6a27 100644
--- a/ash/shell/shell_delegate_impl.cc
+++ b/ash/shell/shell_delegate_impl.cc
@@ -128,6 +128,9 @@ class SessionStateDelegateImpl : public SessionStateDelegate {
}
virtual void SwitchActiveUser(const std::string& user_id) OVERRIDE {}
virtual void CycleActiveUser(CycleUser cycle_user) OVERRIDE {}
+ virtual bool IsMultiProfileAllowedByPrimaryUserPolicy() const OVERRIDE {
+ return true;
+ }
virtual void AddSessionStateObserver(
ash::SessionStateObserver* observer) OVERRIDE {}
virtual void RemoveSessionStateObserver(
diff --git a/ash/system/user/user_view.cc b/ash/system/user/user_view.cc
index f3646a7..689764f 100644
--- a/ash/system/user/user_view.cc
+++ b/ash/system/user/user_view.cc
@@ -493,8 +493,13 @@ void UserView::ToggleAddUserMenuOption() {
const SessionStateDelegate* delegate =
Shell::GetInstance()->session_state_delegate();
- add_user_disabled_ = delegate->NumberOfLoggedInUsers() >=
- delegate->GetMaximumNumberOfLoggedInUsers();
+
+ bool multi_profile_allowed =
+ delegate->IsMultiProfileAllowedByPrimaryUserPolicy();
+ add_user_disabled_ = (delegate->NumberOfLoggedInUsers() >=
+ delegate->GetMaximumNumberOfLoggedInUsers()) ||
+ !multi_profile_allowed;
+
ButtonFromView* button = new ButtonFromView(
add_user_view,
add_user_disabled_ ? NULL : this,
@@ -508,9 +513,15 @@ void UserView::ToggleAddUserMenuOption() {
if (add_user_disabled_) {
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
+ int message_id;
+ if (!multi_profile_allowed)
+ message_id = IDS_ASH_STATUS_TRAY_MESSAGE_NOT_ALLOWED_PRIMARY_USER;
+ else
+ message_id = IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER;
+
popup_message_.reset(new PopupMessage(
bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER),
- bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER),
+ bundle.GetLocalizedString(message_id),
PopupMessage::ICON_WARNING,
add_user_view->anchor(),
views::BubbleBorder::TOP_LEFT,
diff --git a/ash/test/test_session_state_delegate.cc b/ash/test/test_session_state_delegate.cc
index 4c76143..eac5576 100644
--- a/ash/test/test_session_state_delegate.cc
+++ b/ash/test/test_session_state_delegate.cc
@@ -227,6 +227,11 @@ void TestSessionStateDelegate::CycleActiveUser(CycleUser cycle_user) {
SwitchActiveUser("someone@tray");
}
+bool TestSessionStateDelegate::IsMultiProfileAllowedByPrimaryUserPolicy()
+ const {
+ return true;
+}
+
void TestSessionStateDelegate::AddSessionStateObserver(
SessionStateObserver* observer) {
}
diff --git a/ash/test/test_session_state_delegate.h b/ash/test/test_session_state_delegate.h
index 478c340..c508299 100644
--- a/ash/test/test_session_state_delegate.h
+++ b/ash/test/test_session_state_delegate.h
@@ -48,6 +48,7 @@ class TestSessionStateDelegate : public SessionStateDelegate {
virtual bool ShouldShowAvatar(aura::Window* window) const OVERRIDE;
virtual void SwitchActiveUser(const std::string& user_id) OVERRIDE;
virtual void CycleActiveUser(CycleUser cycle_user) OVERRIDE;
+ virtual bool IsMultiProfileAllowedByPrimaryUserPolicy() const OVERRIDE;
virtual void AddSessionStateObserver(
ash::SessionStateObserver* observer) OVERRIDE;
virtual void RemoveSessionStateObserver(
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index fec3c06..5c88570 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -1649,7 +1649,7 @@ Press any key to continue exploring.
<message name="IDS_MULTI_PROFILES_RESTRICTED_POLICY_TITLE" desc="Text that is shown on the title of the bubble shown for user pod which is not allowed in multi-profiles session.">
Can't set up multiple sign-in
</message>
- <message name="IDS_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG" desc="Text that is shown on the bubble shown for user pod which is not allowed in multi-profiles session because of not-allowed policy.">
+ <message name="IDS_MULTI_PROFILES_NOT_ALLOWED_POLICY_MSG" desc="Text that is shown on the bubble shown for user pod which is not allowed in multi-profiles session because of not-allowed policy or because of usage policy-pushed certificates.">
The administrator for this account has disallowed multiple sign-in.
</message>
<message name="IDS_MULTI_PROFILES_PRIMARY_ONLY_POLICY_MSG" desc="Text that is shown on the bubble shown for user pod which is not allowed in multi-profiles session because of primary-only policy.">
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager.cc b/chrome/browser/chromeos/login/users/chrome_user_manager.cc
index aec54c3..d7fdd8b 100644
--- a/chrome/browser/chromeos/login/users/chrome_user_manager.cc
+++ b/chrome/browser/chromeos/login/users/chrome_user_manager.cc
@@ -211,7 +211,9 @@ user_manager::UserList ChromeUserManager::GetUsersAdmittedForMultiProfile()
// Same applies to owner account (see http://crbug.com/385034).
if (check == MultiProfileUserController::ALLOWED ||
check == MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS ||
- check == MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY) {
+ check == MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY ||
+ check ==
+ MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED) {
result.push_back(*it);
}
}
diff --git a/chrome/browser/chromeos/login/users/multi_profile_user_controller.cc b/chrome/browser/chromeos/login/users/multi_profile_user_controller.cc
index 1d315d3..6bb7114 100644
--- a/chrome/browser/chromeos/login/users/multi_profile_user_controller.cc
+++ b/chrome/browser/chromeos/login/users/multi_profile_user_controller.cc
@@ -87,30 +87,19 @@ void MultiProfileUserController::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
}
-bool MultiProfileUserController::IsUserAllowedInSession(
- const std::string& user_email,
- MultiProfileUserController::UserAllowedInSessionReason* reason) const {
+// static
+MultiProfileUserController::UserAllowedInSessionReason
+MultiProfileUserController::GetPrimaryUserPolicy() {
UserManager* user_manager = UserManager::Get();
CHECK(user_manager);
const user_manager::User* primary_user = user_manager->GetPrimaryUser();
- std::string primary_user_email;
- if (primary_user)
- primary_user_email = primary_user->email();
-
- // Always allow if there is no primary user or user being checked is the
- // primary user.
- if (primary_user_email.empty() || primary_user_email == user_email)
- return SetUserAllowedReason(reason, ALLOWED);
-
- // Owner is not allowed to be secondary user.
- if (user_manager->GetOwnerEmail() == user_email)
- return SetUserAllowedReason(reason, NOT_ALLOWED_OWNER_AS_SECONDARY);
+ if (!primary_user)
+ return ALLOWED;
+ Profile* primary_user_profile =
+ ProfileHelper::Get()->GetProfileByUserUnsafe(primary_user);
- // Don't allow profiles potentially tainted by data fetched with policy-pushed
- // certificates to join a multiprofile session.
- if (policy::PolicyCertServiceFactory::UsedPolicyCertificates(user_email))
- return SetUserAllowedReason(reason, NOT_ALLOWED_POLICY_CERT_TAINTED);
+ std::string primary_user_email = primary_user->email();
// Don't allow any secondary profiles if the primary profile is tainted.
if (policy::PolicyCertServiceFactory::UsedPolicyCertificates(
@@ -118,31 +107,57 @@ bool MultiProfileUserController::IsUserAllowedInSession(
// Check directly in local_state before checking if the primary user has
// a PolicyCertService. His profile may have been tainted previously though
// he didn't get a PolicyCertService created for this session.
- return SetUserAllowedReason(reason,
- NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED);
+ return NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED;
}
// If the primary profile already has policy certificates installed but hasn't
// used them yet then it can become tainted at any time during this session;
// disable secondary profiles in this case too.
- Profile* primary_user_profile =
- primary_user ? ProfileHelper::Get()->GetProfileByUserUnsafe(primary_user)
- : NULL;
policy::PolicyCertService* service =
primary_user_profile ? policy::PolicyCertServiceFactory::GetForProfile(
primary_user_profile)
: NULL;
if (service && service->has_policy_certificates())
- return SetUserAllowedReason(reason,
- NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED);
+ return NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED;
// No user is allowed if the primary user policy forbids it.
const std::string primary_user_behavior =
primary_user_profile->GetPrefs()->GetString(
prefs::kMultiProfileUserBehavior);
if (primary_user_behavior == kBehaviorNotAllowed)
- return SetUserAllowedReason(reason,
- NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS);
+ return NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS;
+
+ return ALLOWED;
+}
+
+bool MultiProfileUserController::IsUserAllowedInSession(
+ const std::string& user_email,
+ MultiProfileUserController::UserAllowedInSessionReason* reason) const {
+ UserManager* user_manager = UserManager::Get();
+ CHECK(user_manager);
+
+ const user_manager::User* primary_user = user_manager->GetPrimaryUser();
+ std::string primary_user_email;
+ if (primary_user)
+ primary_user_email = primary_user->email();
+
+ // Always allow if there is no primary user or user being checked is the
+ // primary user.
+ if (primary_user_email.empty() || primary_user_email == user_email)
+ return SetUserAllowedReason(reason, ALLOWED);
+
+ // Owner is not allowed to be secondary user.
+ if (user_manager->GetOwnerEmail() == user_email)
+ return SetUserAllowedReason(reason, NOT_ALLOWED_OWNER_AS_SECONDARY);
+
+ // Don't allow profiles potentially tainted by data fetched with policy-pushed
+ // certificates to join a multiprofile session.
+ if (policy::PolicyCertServiceFactory::UsedPolicyCertificates(user_email))
+ return SetUserAllowedReason(reason, NOT_ALLOWED_POLICY_CERT_TAINTED);
+
+ UserAllowedInSessionReason primary_user_policy = GetPrimaryUserPolicy();
+ if (primary_user_policy != ALLOWED)
+ return SetUserAllowedReason(reason, primary_user_policy);
// The user must have 'unrestricted' policy to be a secondary user.
const std::string behavior = GetCachedValue(user_email);
diff --git a/chrome/browser/chromeos/login/users/multi_profile_user_controller.h b/chrome/browser/chromeos/login/users/multi_profile_user_controller.h
index 628a955..506794f 100644
--- a/chrome/browser/chromeos/login/users/multi_profile_user_controller.h
+++ b/chrome/browser/chromeos/login/users/multi_profile_user_controller.h
@@ -65,6 +65,11 @@ class MultiProfileUserController {
// Returns the cached policy value for |user_email|.
std::string GetCachedValue(const std::string& user_email) const;
+ // Returns primary user policy (only ALLOW,
+ // NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
+ // NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS)
+ static UserAllowedInSessionReason GetPrimaryUserPolicy();
+
// Returns true if user allowed to be in the current session. If |reason| not
// null stores UserAllowedInSessionReason enum that describes actual reason.
bool IsUserAllowedInSession(const std::string& user_email,
diff --git a/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc b/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc
index 5f3258f..b93d73a 100644
--- a/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc
+++ b/chrome/browser/chromeos/login/users/multi_profile_user_controller_unittest.cc
@@ -34,55 +34,65 @@ const char* kUsers[] = {"a@gmail.com", "b@gmail.com" };
struct BehaviorTestCase {
const char* primary;
const char* secondary;
- MultiProfileUserController::UserAllowedInSessionReason expected_allowed;
+ MultiProfileUserController::UserAllowedInSessionReason
+ expected_primary_policy;
+ MultiProfileUserController::UserAllowedInSessionReason
+ expected_secondary_allowed;
};
const BehaviorTestCase kBehaviorTestCases[] = {
- {
- MultiProfileUserController::kBehaviorUnrestricted,
- MultiProfileUserController::kBehaviorUnrestricted,
- MultiProfileUserController::ALLOWED,
- },
- {
- MultiProfileUserController::kBehaviorUnrestricted,
- MultiProfileUserController::kBehaviorPrimaryOnly,
- MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
- },
- {
- MultiProfileUserController::kBehaviorUnrestricted,
- MultiProfileUserController::kBehaviorNotAllowed,
- MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
- },
- {
- MultiProfileUserController::kBehaviorPrimaryOnly,
- MultiProfileUserController::kBehaviorUnrestricted,
- MultiProfileUserController::ALLOWED,
- },
- {
- MultiProfileUserController::kBehaviorPrimaryOnly,
- MultiProfileUserController::kBehaviorPrimaryOnly,
- MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
- },
- {
- MultiProfileUserController::kBehaviorPrimaryOnly,
- MultiProfileUserController::kBehaviorNotAllowed,
- MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
- },
- {
- MultiProfileUserController::kBehaviorNotAllowed,
- MultiProfileUserController::kBehaviorUnrestricted,
- MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
- },
- {
- MultiProfileUserController::kBehaviorNotAllowed,
- MultiProfileUserController::kBehaviorPrimaryOnly,
- MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
- },
- {
- MultiProfileUserController::kBehaviorNotAllowed,
- MultiProfileUserController::kBehaviorNotAllowed,
- MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
- },
+ {
+ MultiProfileUserController::kBehaviorUnrestricted,
+ MultiProfileUserController::kBehaviorUnrestricted,
+ MultiProfileUserController::ALLOWED, MultiProfileUserController::ALLOWED,
+ },
+ {
+ MultiProfileUserController::kBehaviorUnrestricted,
+ MultiProfileUserController::kBehaviorPrimaryOnly,
+ MultiProfileUserController::ALLOWED,
+ MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
+ },
+ {
+ MultiProfileUserController::kBehaviorUnrestricted,
+ MultiProfileUserController::kBehaviorNotAllowed,
+ MultiProfileUserController::ALLOWED,
+ MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
+ },
+ {
+ MultiProfileUserController::kBehaviorPrimaryOnly,
+ MultiProfileUserController::kBehaviorUnrestricted,
+ MultiProfileUserController::ALLOWED, MultiProfileUserController::ALLOWED,
+ },
+ {
+ MultiProfileUserController::kBehaviorPrimaryOnly,
+ MultiProfileUserController::kBehaviorPrimaryOnly,
+ MultiProfileUserController::ALLOWED,
+ MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
+ },
+ {
+ MultiProfileUserController::kBehaviorPrimaryOnly,
+ MultiProfileUserController::kBehaviorNotAllowed,
+ MultiProfileUserController::ALLOWED,
+ MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS,
+ },
+ {
+ MultiProfileUserController::kBehaviorNotAllowed,
+ MultiProfileUserController::kBehaviorUnrestricted,
+ MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
+ MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
+ },
+ {
+ MultiProfileUserController::kBehaviorNotAllowed,
+ MultiProfileUserController::kBehaviorPrimaryOnly,
+ MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
+ MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
+ },
+ {
+ MultiProfileUserController::kBehaviorNotAllowed,
+ MultiProfileUserController::kBehaviorNotAllowed,
+ MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
+ MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS,
+ },
};
// Weak ptr to PolicyCertVerifier - object is freed in test destructor once
@@ -216,6 +226,9 @@ TEST_F(MultiProfileUserControllerTest, AllAllowedBeforeLogin) {
EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[0], &reason))
<< "Case " << i;
EXPECT_EQ(MultiProfileUserController::ALLOWED, reason) << "Case " << i;
+ EXPECT_EQ(MultiProfileUserController::ALLOWED,
+ MultiProfileUserController::GetPrimaryUserPolicy())
+ << "Case " << i;
}
}
@@ -272,9 +285,13 @@ TEST_F(MultiProfileUserControllerTest, IsSecondaryAllowed) {
for (size_t i = 0; i < arraysize(kBehaviorTestCases); ++i) {
SetPrefBehavior(0, kBehaviorTestCases[i].primary);
SetCachedBehavior(1, kBehaviorTestCases[i].secondary);
+ EXPECT_EQ(kBehaviorTestCases[i].expected_primary_policy,
+ MultiProfileUserController::GetPrimaryUserPolicy())
+ << "Case " << i;
MultiProfileUserController::UserAllowedInSessionReason reason;
controller()->IsUserAllowedInSession(kUsers[1], &reason);
- EXPECT_EQ(kBehaviorTestCases[i].expected_allowed, reason) << "Case " << i;
+ EXPECT_EQ(kBehaviorTestCases[i].expected_secondary_allowed, reason)
+ << "Case " << i;
}
}
@@ -291,11 +308,13 @@ TEST_F(MultiProfileUserControllerTest, PrimaryBehaviorChange) {
SetPrefBehavior(0, kBehaviorTestCases[i].primary);
SetPrefBehavior(1, kBehaviorTestCases[i].secondary);
if (user_not_allowed_count() == 0) {
- EXPECT_EQ(kBehaviorTestCases[i].expected_allowed,
- MultiProfileUserController::ALLOWED) << "Case " << i;
+ EXPECT_EQ(kBehaviorTestCases[i].expected_secondary_allowed,
+ MultiProfileUserController::ALLOWED)
+ << "Case " << i;
} else {
- EXPECT_NE(kBehaviorTestCases[i].expected_allowed,
- MultiProfileUserController::ALLOWED) << "Case " << i;
+ EXPECT_NE(kBehaviorTestCases[i].expected_secondary_allowed,
+ MultiProfileUserController::ALLOWED)
+ << "Case " << i;
}
}
}
@@ -324,6 +343,8 @@ TEST_F(MultiProfileUserControllerTest,
EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
+ EXPECT_EQ(MultiProfileUserController::ALLOWED,
+ MultiProfileUserController::GetPrimaryUserPolicy());
}
TEST_F(MultiProfileUserControllerTest,
@@ -363,10 +384,14 @@ TEST_F(MultiProfileUserControllerTest,
EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
reason);
+ EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
+ MultiProfileUserController::GetPrimaryUserPolicy());
policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(kUsers[1]);
EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_POLICY_CERT_TAINTED,
reason);
+ EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
+ MultiProfileUserController::GetPrimaryUserPolicy());
// Flush tasks posted to IO.
base::RunLoop().RunUntilIdle();
@@ -395,6 +420,8 @@ TEST_F(MultiProfileUserControllerTest,
MultiProfileUserController::UserAllowedInSessionReason reason;
EXPECT_TRUE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
EXPECT_EQ(MultiProfileUserController::ALLOWED, reason);
+ EXPECT_EQ(MultiProfileUserController::ALLOWED,
+ MultiProfileUserController::GetPrimaryUserPolicy());
net::CertificateList certificates;
certificates.push_back(new net::X509Certificate(
@@ -404,6 +431,8 @@ TEST_F(MultiProfileUserControllerTest,
EXPECT_FALSE(controller()->IsUserAllowedInSession(kUsers[1], &reason));
EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
reason);
+ EXPECT_EQ(MultiProfileUserController::NOT_ALLOWED_PRIMARY_POLICY_CERT_TAINTED,
+ MultiProfileUserController::GetPrimaryUserPolicy());
// Flush tasks posted to IO.
base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/chromeos/profiles/profile_helper.h b/chrome/browser/chromeos/profiles/profile_helper.h
index 3048f17..04afba4 100644
--- a/chrome/browser/chromeos/profiles/profile_helper.h
+++ b/chrome/browser/chromeos/profiles/profile_helper.h
@@ -134,6 +134,7 @@ class ProfileHelper : public BrowsingDataRemover::Observer,
friend class ParallelAuthenticatorTest;
friend class ProfileHelperTest;
friend class ProfileListChromeOSTest;
+ friend class SessionStateDelegateChromeOSTest;
// BrowsingDataRemover::Observer implementation:
virtual void OnBrowsingDataRemoverDone() OVERRIDE;
diff --git a/chrome/browser/ui/ash/session_state_delegate_chromeos.cc b/chrome/browser/ui/ash/session_state_delegate_chromeos.cc
index 613c87aa..ef9f807 100644
--- a/chrome/browser/ui/ash/session_state_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/session_state_delegate_chromeos.cc
@@ -11,6 +11,7 @@
#include "base/prefs/pref_service.h"
#include "chrome/browser/chromeos/login/lock/screen_locker.h"
#include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
+#include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
#include "chrome/browser/chromeos/login/users/user_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/profiles/profile.h"
@@ -208,6 +209,12 @@ void SessionStateDelegateChromeos::CycleActiveUser(CycleUser cycle_user) {
chromeos::UserManager::Get()->SwitchActiveUser(user_id);
}
+bool SessionStateDelegateChromeos::IsMultiProfileAllowedByPrimaryUserPolicy()
+ const {
+ return chromeos::MultiProfileUserController::GetPrimaryUserPolicy() ==
+ chromeos::MultiProfileUserController::ALLOWED;
+}
+
void SessionStateDelegateChromeos::AddSessionStateObserver(
ash::SessionStateObserver* observer) {
session_state_observer_list_.AddObserver(observer);
diff --git a/chrome/browser/ui/ash/session_state_delegate_chromeos.h b/chrome/browser/ui/ash/session_state_delegate_chromeos.h
index 0ec9622..93f9b7da 100644
--- a/chrome/browser/ui/ash/session_state_delegate_chromeos.h
+++ b/chrome/browser/ui/ash/session_state_delegate_chromeos.h
@@ -48,6 +48,7 @@ class SessionStateDelegateChromeos
virtual bool ShouldShowAvatar(aura::Window* window) const OVERRIDE;
virtual void SwitchActiveUser(const std::string& user_id) OVERRIDE;
virtual void CycleActiveUser(CycleUser cycle_user) OVERRIDE;
+ virtual bool IsMultiProfileAllowedByPrimaryUserPolicy() const OVERRIDE;
virtual void AddSessionStateObserver(
ash::SessionStateObserver* observer) OVERRIDE;
virtual void RemoveSessionStateObserver(
diff --git a/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc b/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc
index d0bd6bf..2bf05dd 100644
--- a/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc
+++ b/chrome/browser/ui/ash/session_state_delegate_chromeos_unittest.cc
@@ -7,10 +7,38 @@
#include <string>
#include <vector>
+#include "base/run_loop.h"
#include "chrome/browser/chromeos/login/users/fake_user_manager.h"
+#include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
+#include "chrome/browser/chromeos/policy/policy_cert_service.h"
+#include "chrome/browser/chromeos/policy/policy_cert_service_factory.h"
+#include "chrome/browser/chromeos/policy/policy_cert_verifier.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile_manager.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "net/cert/x509_certificate.h"
#include "testing/gtest/include/gtest/gtest.h"
+namespace chromeos {
+
+namespace {
+
+const char* kUser = "user@test.com";
+
+// Weak ptr to PolicyCertVerifier - object is freed in test destructor once
+// we've ensured the profile has been shut down.
+policy::PolicyCertVerifier* g_policy_cert_verifier_for_factory = NULL;
+
+KeyedService* CreateTestPolicyCertService(content::BrowserContext* context) {
+ return policy::PolicyCertService::CreateForTesting(
+ kUser,
+ g_policy_cert_verifier_for_factory,
+ chromeos::UserManager::Get()).release();
+}
+
+} // namespace
class SessionStateDelegateChromeOSTest : public testing::Test {
protected:
@@ -36,6 +64,17 @@ class SessionStateDelegateChromeOSTest : public testing::Test {
session_state_delegate_.reset();
user_manager_enabler_.reset();
user_manager_ = NULL;
+ // Clear our cached pointer to the PolicyCertVerifier.
+ g_policy_cert_verifier_for_factory = NULL;
+ profile_manager_.reset();
+
+ // We must ensure that the PolicyCertVerifier outlives the
+ // PolicyCertService so shutdown the profile here. Additionally, we need
+ // to run the message loop between freeing the PolicyCertService and
+ // freeing the PolicyCertVerifier (see
+ // PolicyCertService::OnTrustAnchorsChanged() which is called from
+ // PolicyCertService::Shutdown()).
+ base::RunLoop().RunUntilIdle();
}
// Add and log in a user to the session.
@@ -54,6 +93,26 @@ class SessionStateDelegateChromeOSTest : public testing::Test {
return session_state_delegate_.get();
}
+ void InitForMultiProfile() {
+ profile_manager_.reset(
+ new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
+ ASSERT_TRUE(profile_manager_->SetUp());
+
+ const std::string user_email(kUser);
+ const user_manager::User* user = user_manager()->AddUser(user_email);
+
+ // Note that user profiles are created after user login in reality.
+ user_profile_ = profile_manager_->CreateTestingProfile(user_email);
+ user_profile_->set_profile_name(user_email);
+ chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(
+ user, user_profile_);
+ }
+
+ content::TestBrowserThreadBundle threads_;
+ scoped_ptr<policy::PolicyCertVerifier> cert_verifier_;
+ scoped_ptr<TestingProfileManager> profile_manager_;
+ TestingProfile* user_profile_;
+
private:
scoped_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
scoped_ptr<SessionStateDelegateChromeos> session_state_delegate_;
@@ -104,3 +163,68 @@ TEST_F(SessionStateDelegateChromeOSTest, CyclingThreeUsers) {
session_state_delegate()->CycleActiveUser(backward);
EXPECT_EQ("firstuser@test.com", GetActiveUser());
}
+
+// Make sure MultiProfile disabled by primary user policy.
+TEST_F(SessionStateDelegateChromeOSTest, MultiProfileDisallowedByUserPolicy) {
+ InitForMultiProfile();
+ EXPECT_TRUE(
+ session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
+ const std::string user_email(kUser);
+ user_manager()->LoginUser(user_email);
+ EXPECT_TRUE(
+ session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
+
+ user_profile_->GetPrefs()->SetString(
+ prefs::kMultiProfileUserBehavior,
+ chromeos::MultiProfileUserController::kBehaviorNotAllowed);
+ EXPECT_FALSE(
+ session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
+}
+
+// Make sure MultiProfile disabled by primary user policy certificates.
+TEST_F(SessionStateDelegateChromeOSTest,
+ MultiProfileDisallowedByPolicyCertificates) {
+ InitForMultiProfile();
+ const std::string user_email(kUser);
+ user_manager()->LoginUser(user_email);
+ EXPECT_TRUE(
+ session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
+ policy::PolicyCertServiceFactory::SetUsedPolicyCertificates(user_email);
+ EXPECT_FALSE(
+ session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
+
+ // Flush tasks posted to IO.
+ base::RunLoop().RunUntilIdle();
+}
+
+// Make sure MultiProfile disabled by primary user certificates in memory.
+TEST_F(SessionStateDelegateChromeOSTest,
+ MultiProfileDisallowedByPrimaryUserCertificatesInMemory) {
+ InitForMultiProfile();
+ const std::string user_email(kUser);
+ user_manager()->LoginUser(user_email);
+ EXPECT_TRUE(
+ session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
+ cert_verifier_.reset(new policy::PolicyCertVerifier(base::Closure()));
+ g_policy_cert_verifier_for_factory = cert_verifier_.get();
+ ASSERT_TRUE(
+ policy::PolicyCertServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ user_profile_, CreateTestPolicyCertService));
+ policy::PolicyCertService* service =
+ policy::PolicyCertServiceFactory::GetForProfile(user_profile_);
+ ASSERT_TRUE(service);
+
+ EXPECT_FALSE(service->has_policy_certificates());
+ net::CertificateList certificates;
+ certificates.push_back(new net::X509Certificate(
+ "subject", "issuer", base::Time(), base::Time()));
+ service->OnTrustAnchorsChanged(certificates);
+ EXPECT_TRUE(service->has_policy_certificates());
+ EXPECT_FALSE(
+ session_state_delegate()->IsMultiProfileAllowedByPrimaryUserPolicy());
+
+ // Flush tasks posted to IO.
+ base::RunLoop().RunUntilIdle();
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/ui/ash/session_state_delegate_views.cc b/chrome/browser/ui/ash/session_state_delegate_views.cc
index 9622319..de814bd 100644
--- a/chrome/browser/ui/ash/session_state_delegate_views.cc
+++ b/chrome/browser/ui/ash/session_state_delegate_views.cc
@@ -91,6 +91,10 @@ void SessionStateDelegate::CycleActiveUser(CycleUser cycle_user) {
NOTIMPLEMENTED();
}
+bool SessionStateDelegate::IsMultiProfileAllowedByPrimaryUserPolicy() const {
+ return true;
+}
+
void SessionStateDelegate::AddSessionStateObserver(
ash::SessionStateObserver* observer) {
NOTIMPLEMENTED();
diff --git a/chrome/browser/ui/ash/session_state_delegate_views.h b/chrome/browser/ui/ash/session_state_delegate_views.h
index 14e005e..421d11c 100644
--- a/chrome/browser/ui/ash/session_state_delegate_views.h
+++ b/chrome/browser/ui/ash/session_state_delegate_views.h
@@ -42,6 +42,7 @@ class SessionStateDelegate : public ash::SessionStateDelegate {
virtual bool ShouldShowAvatar(aura::Window* window) const OVERRIDE;
virtual void SwitchActiveUser(const std::string& user_id) OVERRIDE;
virtual void CycleActiveUser(CycleUser cycle_user) OVERRIDE;
+ virtual bool IsMultiProfileAllowedByPrimaryUserPolicy() const OVERRIDE;
virtual void AddSessionStateObserver(
ash::SessionStateObserver* observer) OVERRIDE;
virtual void RemoveSessionStateObserver(