Commit e951d159 authored by akuegel@chromium.org's avatar akuegel@chromium.org

Enable the new elevation for managed users which is tied to a specific...

Enable the new elevation for managed users which is tied to a specific WebContents. This replaces the old elevation which was tied to a profile.

BUG=222364
TEST=unit_tests,browser_tests


Review URL: https://chromiumcodereview.appspot.com/13119011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192549 0039d316-1c4b-4281-b951-d872f2087c98
parent 1437f0c5
......@@ -9,6 +9,7 @@
#include "base/message_loop.h"
#include "chrome/browser/extensions/image_loader.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/api/icons/icons_handler.h"
#include "chrome/common/extensions/extension.h"
......@@ -150,13 +151,17 @@ void ExtensionUninstallDialog::Observe(
bool ExtensionUninstallDialog::ShowAuthorizationDialog() {
ManagedUserService* service =
ManagedUserServiceFactory::GetForProfile(profile_);
if (service->ProfileIsManaged() && !service->CanSkipPassphraseDialog()) {
service->RequestAuthorizationUsingActiveWebContents(
browser_,
content::WebContents* web_contents =
browser_->tab_strip_model()->GetActiveWebContents();
if (service->ProfileIsManaged() &&
!service->CanSkipPassphraseDialog(web_contents)) {
service->RequestAuthorization(
web_contents,
base::Bind(&ExtensionUninstallDialog::OnAuthorizationResult,
base::Unretained(this)));
return true;
}
service->AddElevationForExtension(extension_->id());
return false;
}
......
......@@ -104,9 +104,7 @@ void ManagedUserService::URLFilterContext::SetManualURLs(
io_url_filter_, base::Owned(url_map.release())));
}
ManagedUserService::ManagedUserService(Profile* profile)
: profile_(profile),
is_elevated_(false) {
ManagedUserService::ManagedUserService(Profile* profile) : profile_(profile) {
}
ManagedUserService::~ManagedUserService() {
......@@ -116,15 +114,11 @@ bool ManagedUserService::ProfileIsManaged() const {
return profile_->GetPrefs()->GetBoolean(prefs::kProfileIsManaged);
}
bool ManagedUserService::IsElevated() const {
return is_elevated_;
}
bool ManagedUserService::IsElevatedForWebContents(
const content::WebContents* web_contents) const {
const ManagedModeNavigationObserver* observer =
ManagedModeNavigationObserver::FromWebContents(web_contents);
return observer->is_elevated();
return observer ? observer->is_elevated() : false;
}
bool ManagedUserService::IsPassphraseEmpty() const {
......@@ -132,16 +126,9 @@ bool ManagedUserService::IsPassphraseEmpty() const {
return pref_service->GetString(prefs::kManagedModeLocalPassphrase).empty();
}
bool ManagedUserService::CanSkipPassphraseDialog() {
// If the profile is already elevated or there is no passphrase set, no
// authentication is needed.
return IsElevated() || IsPassphraseEmpty();
}
bool ManagedUserService::CanSkipPassphraseDialog(
const content::WebContents* web_contents) const {
return IsElevated() ||
IsElevatedForWebContents(web_contents) ||
return IsElevatedForWebContents(web_contents) ||
IsPassphraseEmpty();
}
......@@ -157,14 +144,6 @@ void ManagedUserService::RequestAuthorization(
new ManagedUserPassphraseDialog(web_contents, callback);
}
void ManagedUserService::RequestAuthorizationUsingActiveWebContents(
Browser* browser,
const PassphraseCheckedCallback& callback) {
RequestAuthorization(
browser->tab_strip_model()->GetActiveWebContents(),
callback);
}
// static
void ManagedUserService::RegisterUserPrefs(PrefRegistrySyncable* registry) {
registry->RegisterDictionaryPref(prefs::kManagedModeManualHosts,
......@@ -290,6 +269,15 @@ void ManagedUserService::Observe(int type,
}
break;
}
case chrome::NOTIFICATION_EXTENSION_INSTALLED:
case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
// When an extension was installed or uninstalled, remove the temporary
// elevation.
const extensions::Extension* extension =
content::Details<extensions::Extension>(details).ptr();
RemoveElevationForExtension(extension->id());
break;
}
default:
NOTREACHED();
}
......@@ -301,9 +289,6 @@ bool ManagedUserService::ExtensionManagementPolicyImpl(
if (!ProfileIsManaged())
return true;
if (is_elevated_)
return true;
if (elevated_for_extensions_.count(extension_id))
return true;
......@@ -424,12 +409,6 @@ void ManagedUserService::GetManualExceptionsForHost(const std::string& host,
}
}
// TODO(akuegel): Rename to SetElevatedForTesting when all callers are changed
// to set elevation on the ManagedModeNavigationObserver.
void ManagedUserService::SetElevated(bool is_elevated) {
is_elevated_ = is_elevated;
}
void ManagedUserService::AddElevationForExtension(
const std::string& extension_id) {
elevated_for_extensions_.insert(extension_id);
......@@ -455,6 +434,10 @@ void ManagedUserService::Init() {
content::Source<Profile>(profile_));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
content::Source<Profile>(profile_));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
content::Source<Profile>(profile_));
registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
content::Source<Profile>(profile_));
pref_change_registrar_.Init(profile_->GetPrefs());
pref_change_registrar_.Add(
prefs::kDefaultManagedModeFilteringBehavior,
......
......@@ -44,9 +44,6 @@ class ManagedUserService : public ProfileKeyedService,
bool ProfileIsManaged() const;
// Deprecated. Use IsElevatedForWebContents() instead.
bool IsElevated() const;
// Returns the elevation state for specific WebContents.
bool IsElevatedForWebContents(const content::WebContents* web_contents) const;
......@@ -90,10 +87,6 @@ class ManagedUserService : public ProfileKeyedService,
void GetManualExceptionsForHost(const std::string& host,
std::vector<GURL>* urls);
// Deprecated. Use the CanSkipPassphraseDialog() method which requires a
// WebContents parameter instead.
bool CanSkipPassphraseDialog();
// Checks if the passphrase dialog can be skipped (the profile is already in
// elevated state for the given WebContents or the passphrase is empty).
bool CanSkipPassphraseDialog(const content::WebContents* web_contents) const;
......@@ -102,16 +95,6 @@ class ManagedUserService : public ProfileKeyedService,
void RequestAuthorization(content::WebContents* web_contents,
const PassphraseCheckedCallback& callback);
// Handles the request to authorize as the custodian of the managed user.
// Also determines the active web contents to be passed to the passphrase
// dialog.
void RequestAuthorizationUsingActiveWebContents(
Browser* browser,
const PassphraseCheckedCallback& callback);
// Set the elevation state for the profile.
void SetElevated(bool is_elevated);
// Add an elevation for a specific extension which allows the managed user to
// install/uninstall this specific extension.
void AddElevationForExtension(const std::string& extension_id);
......@@ -196,11 +179,6 @@ class ManagedUserService : public ProfileKeyedService,
// Owns us via the ProfileKeyedService mechanism.
Profile* profile_;
// If ManagedUserService is in an elevated state, a custodian user has
// authorized making changes (to install additional content packs, for
// example).
bool is_elevated_;
content::NotificationRegistrar registrar_;
PrefChangeRegistrar pref_change_registrar_;
......
......@@ -188,7 +188,6 @@ TEST_F(ManagedUserServiceExtensionTest, InstallContentPacks) {
profile_->GetPrefs()->SetBoolean(prefs::kProfileIsManaged, true);
ManagedUserService managed_user_service(profile_.get());
managed_user_service.Init();
managed_user_service.SetElevated(true);
ManagedModeURLFilter* url_filter =
managed_user_service.GetURLFilterForUIThread();
ManagedModeURLFilterObserver observer(url_filter);
......@@ -273,8 +272,10 @@ TEST_F(ManagedUserServiceExtensionTest, InstallContentPacks) {
#endif
// Disable the first content pack.
managed_user_service.AddElevationForExtension(extension->id());
service_->DisableExtension(extension->id(),
extensions::Extension::DISABLE_USER_ACTION);
managed_user_service.RemoveElevationForExtension(extension->id());
observer.Wait();
site_lists = GetActiveSiteLists(&managed_user_service);
......
// Copyright (c) 2013 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/managed_mode/scoped_extension_elevation.h"
#include "chrome/browser/managed_mode/managed_user_service.h"
ScopedExtensionElevation::ScopedExtensionElevation(ManagedUserService* service)
: service_(service) {
}
void ScopedExtensionElevation::AddExtension(const std::string& extension_id) {
service_->AddElevationForExtension(extension_id);
elevated_extensions_.push_back(extension_id);
}
ScopedExtensionElevation::~ScopedExtensionElevation() {
for (size_t i = 0; i < elevated_extensions_.size(); ++i)
service_->RemoveElevationForExtension(elevated_extensions_[i]);
}
// Copyright (c) 2013 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_MANAGED_MODE_SCOPED_EXTENSION_ELEVATION_H_
#define CHROME_BROWSER_MANAGED_MODE_SCOPED_EXTENSION_ELEVATION_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
class ManagedUserService;
// Used to allow managed users to install extensions if they are currently in
// elevated state.
class ScopedExtensionElevation {
public:
explicit ScopedExtensionElevation(ManagedUserService* service);
~ScopedExtensionElevation();
// Add elevation for the extension with the id |extension_id|.
void AddExtension(const std::string& extension_id);
private:
ManagedUserService* service_;
// A list of extensions which stay elevated until the destructor of this
// class is called.
std::vector<std::string> elevated_extensions_;
DISALLOW_COPY_AND_ASSIGN(ScopedExtensionElevation);
};
#endif // CHROME_BROWSER_MANAGED_MODE_SCOPED_EXTENSION_ELEVATION_H_
......@@ -32,6 +32,7 @@
#include "chrome/browser/extensions/unpacked_installer.h"
#include "chrome/browser/extensions/updater/extension_updater.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/managed_mode/managed_mode_navigation_observer.h"
#include "chrome/browser/managed_mode/managed_user_service.h"
#include "chrome/browser/managed_mode/managed_user_service_factory.h"
#include "chrome/browser/profiles/profile.h"
......@@ -131,7 +132,7 @@ DictionaryValue* ExtensionSettingsHandler::CreateExtensionDetailValue(
extension->GetBasicInfo(enabled, extension_data);
extension_data->SetBoolean("userModifiable",
management_policy_->UserMayModifySettings(extension, NULL));
CheckUserMayModifySettings(extension));
GURL icon =
ExtensionIconSource::GetIconURL(extension,
......@@ -554,8 +555,10 @@ void ExtensionSettingsHandler::ReloadUnpackedExtensions() {
void ExtensionSettingsHandler::PassphraseDialogCallback(bool success) {
if (!success)
return;
Profile* profile = Profile::FromWebUI(web_ui());
ManagedUserServiceFactory::GetForProfile(profile)->SetElevated(true);
ManagedModeNavigationObserver* observer =
ManagedModeNavigationObserver::FromWebContents(
web_ui()->GetWebContents());
observer->set_elevated(true);
HandleRequestExtensionsData(NULL);
}
......@@ -570,11 +573,40 @@ void ExtensionSettingsHandler::ManagedUserSetElevated(const ListValue* args) {
base::Bind(&ExtensionSettingsHandler::PassphraseDialogCallback,
base::Unretained(this)));
} else {
service->SetElevated(false);
ManagedModeNavigationObserver* observer =
ManagedModeNavigationObserver::FromWebContents(
web_ui()->GetWebContents());
observer->set_elevated(false);
HandleRequestExtensionsData(NULL);
}
}
scoped_ptr<ScopedExtensionElevation>
ExtensionSettingsHandler::GetScopedElevation(
const std::string& extension_id) {
// web_ui() can be NULL in a unit_test.
if (web_ui() == NULL)
return scoped_ptr<ScopedExtensionElevation>(NULL);
ManagedUserService* service = ManagedUserServiceFactory::GetForProfile(
Profile::FromWebUI(web_ui()));
scoped_ptr<ScopedExtensionElevation> elevation(
new ScopedExtensionElevation(service));
if (service->ProfileIsManaged() &&
service->IsElevatedForWebContents(web_ui()->GetWebContents())) {
elevation->AddExtension(extension_id);
}
return elevation.Pass();
}
bool ExtensionSettingsHandler::CheckUserMayModifySettings(
const Extension* extension) {
// Get managed user elevation for a specific extension id. The elevation will
// be removed automatically when |elevation| goes out of scope.
scoped_ptr<ScopedExtensionElevation> elevation =
GetScopedElevation(extension->id());
return management_policy_->UserMayModifySettings(extension, NULL);
}
void ExtensionSettingsHandler::HandleRequestExtensionsData(
const ListValue* args) {
DictionaryValue results;
......@@ -624,7 +656,8 @@ void ExtensionSettingsHandler::HandleRequestExtensionsData(
ManagedUserServiceFactory::GetForProfile(profile);
bool is_managed = service->ProfileIsManaged();
bool is_elevated = service->IsElevated();
bool is_elevated =
service->IsElevatedForWebContents(web_ui()->GetWebContents());
bool developer_mode =
(!is_managed || is_elevated) &&
profile->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode);
......@@ -734,8 +767,7 @@ void ExtensionSettingsHandler::HandleEnableMessage(const ListValue* args) {
const Extension* extension =
extension_service_->GetInstalledExtension(extension_id);
if (!extension ||
!management_policy_->UserMayModifySettings(extension, NULL)) {
if (!extension || !CheckUserMayModifySettings(extension)) {
LOG(ERROR) << "Attempt to enable an extension that is non-usermanagable was"
<< "made. Extension id: " << extension->id();
return;
......@@ -765,6 +797,10 @@ void ExtensionSettingsHandler::HandleEnableMessage(const ListValue* args) {
prefs->SetBrowserActionVisibility(extension, true);
}
} else {
// Get managed user elevation for a specific extension id. The elevation
// will be removed automatically when |elevation| goes out of scope.
scoped_ptr<ScopedExtensionElevation> elevation =
GetScopedElevation(extension_id);
extension_service_->DisableExtension(
extension_id, Extension::DISABLE_USER_ACTION);
}
......@@ -809,7 +845,7 @@ void ExtensionSettingsHandler::HandleAllowFileAccessMessage(
if (!extension)
return;
if (!management_policy_->UserMayModifySettings(extension, NULL)) {
if (!CheckUserMayModifySettings(extension)) {
LOG(ERROR) << "Attempt to change allow file access of an extension that is "
<< "non-usermanagable was made. Extension id : "
<< extension->id();
......@@ -828,7 +864,7 @@ void ExtensionSettingsHandler::HandleUninstallMessage(const ListValue* args) {
if (!extension)
return;
if (!management_policy_->UserMayModifySettings(extension, NULL)) {
if (!CheckUserMayModifySettings(extension)) {
LOG(ERROR) << "Attempt to uninstall an extension that is non-usermanagable "
<< "was made. Extension id : " << extension->id();
return;
......
......@@ -17,6 +17,7 @@
#include "chrome/browser/extensions/extension_uninstall_dialog.h"
#include "chrome/browser/extensions/extension_warning_service.h"
#include "chrome/browser/extensions/requirements_checker.h"
#include "chrome/browser/managed_mode/scoped_extension_elevation.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
......@@ -137,6 +138,15 @@ class ExtensionSettingsHandler
// it gives this information back to the UI.
void PassphraseDialogCallback(bool success);
// Generates a temporary elevation for a managed user which is bound to the
// life-time of the return value.
scoped_ptr<ScopedExtensionElevation> GetScopedElevation(
const std::string& extension_id);
// Verifies that the management policy allows the user to enable,
// disable or uninstall an extension.
bool CheckUserMayModifySettings(const extensions::Extension* extension);
// Callback for "requestExtensionsData" message.
void HandleRequestExtensionsData(const base::ListValue* args);
......
......@@ -28,6 +28,7 @@
#include "chrome/browser/history/history_types.h"
#include "chrome/browser/history/web_history_service.h"
#include "chrome/browser/history/web_history_service_factory.h"
#include "chrome/browser/managed_mode/managed_mode_navigation_observer.h"
#include "chrome/browser/managed_mode/managed_mode_url_filter.h"
#include "chrome/browser/managed_mode/managed_user_service.h"
#include "chrome/browser/managed_mode/managed_user_service_factory.h"
......@@ -605,7 +606,7 @@ void BrowsingHistoryHandler::HandleProcessManagedUrls(const ListValue* args) {
// Check if the managed user is authenticated.
ManagedUserService* service = ManagedUserServiceFactory::GetForProfile(
Profile::FromWebUI(web_ui()));
if (!service->IsElevated())
if (!service->IsElevatedForWebContents(web_ui()->GetWebContents()))
return;
// Since editing a host can have side effects on other hosts, update all of
......@@ -751,16 +752,20 @@ void BrowsingHistoryHandler::HandleSetElevated(const ListValue* elevated_arg) {
base::Bind(&BrowsingHistoryHandler::PassphraseDialogCallback,
base::Unretained(this)));
} else {
service->SetElevated(elevated);
ManagedModeNavigationObserver* observer =
ManagedModeNavigationObserver::FromWebContents(
web_ui()->GetWebContents());
observer->set_elevated(false);
ManagedUserSetElevated();
}
}
void BrowsingHistoryHandler::PassphraseDialogCallback(bool success) {
if (success) {
ManagedUserService* service = ManagedUserServiceFactory::GetForProfile(
Profile::FromWebUI(web_ui()));
service->SetElevated(true);
ManagedModeNavigationObserver* observer =
ManagedModeNavigationObserver::FromWebContents(
web_ui()->GetWebContents());
observer->set_elevated(true);
ManagedUserSetElevated();
}
}
......@@ -768,7 +773,8 @@ void BrowsingHistoryHandler::PassphraseDialogCallback(bool success) {
void BrowsingHistoryHandler::ManagedUserSetElevated() {
ManagedUserService* service = ManagedUserServiceFactory::GetForProfile(
Profile::FromWebUI(web_ui()));
base::FundamentalValue is_elevated(service->IsElevated());
base::FundamentalValue is_elevated(service->IsElevatedForWebContents(
web_ui()->GetWebContents()));
web_ui()->CallJavascriptFunction("managedUserElevated", is_elevated);
}
......
......@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/prefs/pref_service.h"
#include "base/values.h"
#include "chrome/browser/managed_mode/managed_mode_navigation_observer.h"
#include "chrome/browser/managed_mode/managed_user_passphrase.h"
#include "chrome/browser/managed_mode/managed_user_service.h"
#include "chrome/browser/managed_mode/managed_user_service_factory.h"
......@@ -67,9 +68,8 @@ void ManagedUserPassphraseHandler::GetLocalizedValues(
}
void ManagedUserPassphraseHandler::PassphraseDialogCallback(bool success) {
ManagedUserService* managed_user_service =
ManagedUserServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()));
managed_user_service->SetElevated(true);
ManagedModeNavigationObserver::FromWebContents(
web_ui()->GetWebContents())->set_elevated(success);
base::FundamentalValue unlock_success(success);
web_ui()->CallJavascriptFunction("ManagedUserSettings.isAuthenticated",
unlock_success);
......@@ -85,7 +85,8 @@ void ManagedUserPassphraseHandler::SetElevated(
ManagedUserService* managed_user_service =
ManagedUserServiceFactory::GetForProfile(profile);
if (!elevated) {
managed_user_service->SetElevated(false);
ManagedModeNavigationObserver::FromWebContents(
web_ui()->GetWebContents())->set_elevated(false);
return;
}
managed_user_service->RequestAuthorization(
......@@ -116,10 +117,8 @@ void ManagedUserPassphraseHandler::ResetPassphrase(
void ManagedUserPassphraseHandler::SetLocalPassphrase(
const base::ListValue* args) {
// Only change the passphrase if the custodian is authenticated.
Profile* profile = Profile::FromWebUI(web_ui());
ManagedUserService* managed_user_service =
ManagedUserServiceFactory::GetForProfile(profile);
if (!managed_user_service->IsElevated())
if (!ManagedModeNavigationObserver::FromWebContents(
web_ui()->GetWebContents())->is_elevated())
return;
std::string passphrase;
......
......@@ -12,6 +12,7 @@
#include "base/time.h"
#include "base/values.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/managed_mode/managed_mode_navigation_observer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
......@@ -41,20 +42,33 @@ void ManagedUserSettingsHandler::InitializeHandler() {
}
void ManagedUserSettingsHandler::InitializePage() {
if (CommandLine::ForCurrentProcess()->HasSwitch(
if (!CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableManagedUsers)) {
return;
}
PrefService* pref_service = Profile::FromWebUI(web_ui())->GetPrefs();
base::FundamentalValue is_passphrase_set(!pref_service->GetString(
prefs::kManagedModeLocalPassphrase).empty());
web_ui()->CallJavascriptFunction(
"ManagedUserSettings.passphraseChanged",
is_passphrase_set);
if ((first_run::IsChromeFirstRun() &&
!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoFirstRun)) ||
CommandLine::ForCurrentProcess()->HasSwitch(
switches::kResetLocalPassphrase)) {
ManagedModeNavigationObserver::FromWebContents(
web_ui()->GetWebContents())->set_elevated(true);
}
}
void ManagedUserSettingsHandler::HandlePageOpened(const base::ListValue* args) {
start_time_ = base::TimeTicks::Now();
content::RecordAction(UserMetricsAction("ManagedMode_OpenSettings"));
if (ManagedModeNavigationObserver::FromWebContents(
web_ui()->GetWebContents())->is_elevated()) {
web_ui()->CallJavascriptFunction("ManagedUserSettings.isAuthenticated",
base::FundamentalValue(true));
}
}
void ManagedUserSettingsHandler::GetLocalizedValues(
......
......@@ -16,4 +16,5 @@ ManagedUserSettingsTest::~ManagedUserSettingsTest() {
void ManagedUserSettingsTest::SetUpCommandLine(CommandLine* command_line) {
command_line->AppendSwitch(switches::kManaged);
command_line->AppendSwitch(switches::kEnableManagedUsers);
command_line->AppendSwitch(switches::kNoFirstRun);
}
......@@ -898,6 +898,8 @@
'browser/managed_mode/managed_user_service.h',
'browser/managed_mode/managed_user_service_factory.cc',
'browser/managed_mode/managed_user_service_factory.h',
'browser/managed_mode/scoped_extension_elevation.cc',
'browser/managed_mode/scoped_extension_elevation.h',
'browser/media/audio_stream_indicator.cc',
'browser/media/audio_stream_indicator.h',
'browser/media/media_capture_devices_dispatcher.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment