Skip to content

Commit

Permalink
Replace Profile::IsChild with AreExtensionsPermissionsEnabled
Browse files Browse the repository at this point in the history
(cherry picked from commit caca31e)

Bug: b/270551374, 1429580
Change-Id: Idd3e8ab0c5897c99cabd1d543729bf354a71a737
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4341969
Reviewed-by: David Roger <droger@chromium.org>
Commit-Queue: Liza Bipin <mlbipin@google.com>
Reviewed-by: James Lee <ljjlee@google.com>
Cr-Original-Commit-Position: refs/heads/main@{#1124160}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4392161
Auto-Submit: Prudhvikumar Bommana <pbommana@google.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: James Lee <ljjlee@google.com>
Cr-Commit-Position: refs/branch-heads/5672@{#197}
Cr-Branched-From: 5f2a724-refs/heads/main@{#1121455}
  • Loading branch information
Liza Bipin authored and Chromium LUCI CQ committed Apr 3, 2023
1 parent be9db7e commit d37abec
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 60 deletions.
Expand Up @@ -123,12 +123,20 @@
#include "url/gurl.h"
#include "url/origin.h"

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
#include "chrome/browser/supervised_user/supervised_user_service.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#endif

namespace extensions {

namespace developer = api::developer_private;

namespace {

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
const char kCannotUpdateChildAccountProfileSettingsError[] =
"Cannot change settings for a child account profile.";
#endif
const char kNoSuchExtensionError[] = "No such extension.";
const char kRequiresUserGestureError[] =
"This action requires a user gesture.";
Expand All @@ -142,8 +150,6 @@ const char kManifestKeyIsRequiredError[] =
"The 'manifestKey' argument is required for manifest files.";
const char kCouldNotFindWebContentsError[] =
"Could not find a valid web contents.";
const char kCannotUpdateChildAccountProfileSettingsError[] =
"Cannot change settings for a child account profile.";
const char kNoOptionsPageForExtensionError[] =
"Extension does not have an options page.";
const char kCannotRepairHealthyExtension[] =
Expand Down Expand Up @@ -500,7 +506,13 @@ DeveloperPrivateAPI::GetFactoryInstance() {
std::unique_ptr<developer::ProfileInfo> DeveloperPrivateAPI::CreateProfileInfo(
Profile* profile) {
std::unique_ptr<developer::ProfileInfo> info(new developer::ProfileInfo());
info->is_child_account = profile->IsChild();
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
SupervisedUserService* service =
SupervisedUserServiceFactory::GetForProfile(profile);
info->is_child_account = service->AreExtensionsPermissionsEnabled();
#else
info->is_child_account = false;
#endif
PrefService* prefs = profile->GetPrefs();
const PrefService::Preference* pref =
prefs->FindPreference(prefs::kExtensionsUIDeveloperMode);
Expand Down Expand Up @@ -1085,10 +1097,17 @@ DeveloperPrivateUpdateProfileConfigurationFunction::Run() {

const developer::ProfileConfigurationUpdate& update = params->update;
Profile* profile = Profile::FromBrowserContext(browser_context());

PrefService* prefs = profile->GetPrefs();
if (update.in_developer_mode) {
if (profile->IsChild())
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
SupervisedUserService* service =
SupervisedUserServiceFactory::GetForProfile(profile);
if (service->AreExtensionsPermissionsEnabled()) {
return RespondNow(Error(kCannotUpdateChildAccountProfileSettingsError));
}
#endif

prefs->SetBoolean(prefs::kExtensionsUIDeveloperMode,
*update.in_developer_mode);
SetCurrentDeveloperMode(util::GetBrowserContextId(browser_context()),
Expand Down Expand Up @@ -1311,10 +1330,14 @@ ExtensionFunction::ResponseAction DeveloperPrivateLoadUnpackedFunction::Run() {
return RespondNow(Error(kCouldNotFindWebContentsError));

Profile* profile = Profile::FromBrowserContext(browser_context());
if (profile->IsChild()) {
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
SupervisedUserService* service =
SupervisedUserServiceFactory::GetForProfile(profile);
if (service->AreExtensionsPermissionsEnabled()) {
return RespondNow(
Error("Child account users cannot load unpacked extensions."));
}
#endif
PrefService* prefs = profile->GetPrefs();
if (!prefs->GetBoolean(prefs::kExtensionsUIDeveloperMode)) {
return RespondNow(
Expand Down Expand Up @@ -1892,8 +1915,14 @@ DeveloperPrivateChoosePathFunction::~DeveloperPrivateChoosePathFunction() {}

ExtensionFunction::ResponseAction
DeveloperPrivateIsProfileManagedFunction::Run() {
return RespondNow(
WithArguments(Profile::FromBrowserContext(browser_context())->IsChild()));
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
Profile* profile = Profile::FromBrowserContext(browser_context());
SupervisedUserService* service =
SupervisedUserServiceFactory::GetForProfile(profile);
return RespondNow(WithArguments(service->AreExtensionsPermissionsEnabled()));
#else
return RespondNow(WithArguments(false));
#endif
}

DeveloperPrivateIsProfileManagedFunction::
Expand Down
Expand Up @@ -68,6 +68,12 @@
#include "services/data_decoder/data_decoder_service.h"
#include "services/service_manager/public/cpp/test/test_connector_factory.h"

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
#include "chrome/browser/supervised_user/supervised_user_service.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#include "components/supervised_user/core/common/features.h"
#endif

namespace extensions {

namespace {
Expand Down Expand Up @@ -2773,10 +2779,23 @@ TEST_F(DeveloperPrivateApiAllowlistUnitTest,
api::developer_private::EVENT_TYPE_PREFS_CHANGED));
}

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
class DeveloperPrivateApiSupervisedUserUnitTest
: public DeveloperPrivateApiUnitTest {
: public DeveloperPrivateApiUnitTest,
public testing::WithParamInterface<bool> {
public:
DeveloperPrivateApiSupervisedUserUnitTest() = default;
DeveloperPrivateApiSupervisedUserUnitTest() {
if (extensions_permissions_for_supervised_users_on_desktop()) {
feature_list_.InitAndEnableFeature(
supervised_user::
kEnableExtensionsPermissionsForSupervisedUsersOnDesktop);

} else {
feature_list_.InitAndDisableFeature(
supervised_user::
kEnableExtensionsPermissionsForSupervisedUsersOnDesktop);
}
}

DeveloperPrivateApiSupervisedUserUnitTest(
const DeveloperPrivateApiSupervisedUserUnitTest&) = delete;
Expand All @@ -2786,27 +2805,55 @@ class DeveloperPrivateApiSupervisedUserUnitTest
~DeveloperPrivateApiSupervisedUserUnitTest() override = default;

bool ProfileIsSupervised() const override { return true; }

bool extensions_permissions_for_supervised_users_on_desktop() const {
return GetParam();
}

private:
base::test::ScopedFeatureList feature_list_;
};

// Tests trying to call loadUnpacked when the profile shouldn't be allowed to.
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
TEST_F(DeveloperPrivateApiSupervisedUserUnitTest,
TEST_P(DeveloperPrivateApiSupervisedUserUnitTest,
LoadUnpackedFailsForSupervisedUsers) {
std::unique_ptr<content::WebContents> web_contents(
content::WebContentsTester::CreateTestWebContents(profile(), nullptr));

base::FilePath path = data_dir().AppendASCII("simple_with_popup");
api::EntryPicker::SkipPickerAndAlwaysSelectPathForTest(&path);

ASSERT_TRUE(profile()->IsChild());

auto function =
base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
std::string error = extension_function_test_utils::RunFunctionAndReturnError(
function.get(), "[]", browser());
EXPECT_THAT(error, testing::HasSubstr("Child account"));
SupervisedUserService* service =
SupervisedUserServiceFactory::GetForProfile(profile());
EXPECT_NE(service, nullptr);
if (extensions_permissions_for_supervised_users_on_desktop()) {
EXPECT_TRUE(service->AreExtensionsPermissionsEnabled());
auto function =
base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
std::string error =
extension_function_test_utils::RunFunctionAndReturnError(
function.get(), "[]", browser());
EXPECT_THAT(error, testing::HasSubstr("Child account"));
} else {
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
EXPECT_TRUE(service->AreExtensionsPermissionsEnabled());
auto function =
base::MakeRefCounted<api::DeveloperPrivateLoadUnpackedFunction>();
function->SetRenderFrameHost(web_contents->GetPrimaryMainFrame());
std::string error =
extension_function_test_utils::RunFunctionAndReturnError(
function.get(), "[]", browser());
EXPECT_THAT(error, testing::HasSubstr("Child account"));
#else
EXPECT_FALSE(service->AreExtensionsPermissionsEnabled());
#endif
}
}

INSTANTIATE_TEST_SUITE_P(
ExtensionsPermissionsForSupervisedUsersOnDesktopFeature,
DeveloperPrivateApiSupervisedUserUnitTest,
testing::Bool());
#endif

} // namespace extensions
Expand Up @@ -526,7 +526,8 @@ void WebstorePrivateBeginInstallWithManifest3Function::OnWebstoreParseSuccess(
if (!dummy_extension_->is_theme()) {
SupervisedUserService* service =
SupervisedUserServiceFactory::GetForProfile(profile_);
if (profile_->IsChild() && !service->CanInstallExtensions()) {
if (service->AreExtensionsPermissionsEnabled() &&
!service->CanInstallExtensions()) {
SupervisedUserExtensionsDelegate* supervised_user_extensions_delegate =
ManagementAPI::GetFactoryInstance()
->Get(profile_)
Expand Down Expand Up @@ -662,7 +663,9 @@ void WebstorePrivateBeginInstallWithManifest3Function::

bool WebstorePrivateBeginInstallWithManifest3Function::
PromptForParentApproval() {
DCHECK(profile_->IsChild());
SupervisedUserService* service =
SupervisedUserServiceFactory::GetForProfile(profile_);
DCHECK(service->AreExtensionsPermissionsEnabled());
content::WebContents* web_contents = GetSenderWebContents();
if (!web_contents) {
// The browser window has gone away.
Expand Down Expand Up @@ -736,11 +739,13 @@ void WebstorePrivateBeginInstallWithManifest3Function::OnInstallPromptDone(
case ExtensionInstallPrompt::Result::ACCEPTED:
case ExtensionInstallPrompt::Result::ACCEPTED_WITH_WITHHELD_PERMISSIONS: {
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
SupervisedUserService* service =
SupervisedUserServiceFactory::GetForProfile(profile_);
// Handle parent permission for child accounts on ChromeOS.
if (!dummy_extension_->is_theme() // Parent permission not required for
// theme installation
&& g_browser_process->profile_manager()->IsValidProfile(profile_) &&
profile_->IsChild()) {
service->AreExtensionsPermissionsEnabled()) {
if (PromptForParentApproval()) {
// If are showing parent permission dialog, return instead of
// break, so that we don't release the ref below.
Expand Down Expand Up @@ -886,12 +891,15 @@ void WebstorePrivateBeginInstallWithManifest3Function::ShowInstallDialog(

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
if (!dummy_extension_->is_theme()) {
const bool is_child = profile_->IsChild();
SupervisedUserService* service =
SupervisedUserServiceFactory::GetForProfile(profile_);
const bool requires_parent_permission =
service->AreExtensionsPermissionsEnabled();
// We don't prompt for parent permission for themes, so no need
// to configure the install prompt to indicate that this is a child
// asking a parent for installation permission.
prompt->set_requires_parent_permission(is_child);
if (is_child) {
prompt->set_requires_parent_permission(requires_parent_permission);
if (requires_parent_permission) {
prompt->AddObserver(&supervised_user_extensions_metrics_recorder_);
}
}
Expand Down Expand Up @@ -1176,11 +1184,13 @@ WebstorePrivateIsPendingCustodianApprovalFunction::Run() {
IsPendingCustodianApproval::Params::Create(args());
EXTENSION_FUNCTION_VALIDATE(params);

if (!Profile::FromBrowserContext(browser_context())->IsChild())
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
SupervisedUserService* service = SupervisedUserServiceFactory::GetForProfile(
Profile::FromBrowserContext(browser_context()));
if (!service->AreExtensionsPermissionsEnabled()) {
return RespondNow(BuildResponse(false));

}
ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());

const Extension* extension =
registry->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING);
if (!extension) {
Expand All @@ -1198,6 +1208,9 @@ WebstorePrivateIsPendingCustodianApprovalFunction::Run() {
params->id, disable_reason::DISABLE_CUSTODIAN_APPROVAL_REQUIRED);

return RespondNow(BuildResponse(is_pending_approval));
#else
return RespondNow(BuildResponse(false));
#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS)
}

ExtensionFunction::ResponseValue
Expand Down
4 changes: 1 addition & 3 deletions chrome/browser/extensions/extension_management.cc
Expand Up @@ -62,9 +62,7 @@
namespace extensions {

ExtensionManagement::ExtensionManagement(Profile* profile)
: profile_(profile),
pref_service_(profile_->GetPrefs()),
is_child_(profile_->IsChild()) {
: profile_(profile), pref_service_(profile_->GetPrefs()) {
TRACE_EVENT0("browser,startup",
"ExtensionManagement::ExtensionManagement::ctor");
#if BUILDFLAG(IS_CHROMEOS_ASH)
Expand Down
4 changes: 0 additions & 4 deletions chrome/browser/extensions/extension_management.h
Expand Up @@ -233,9 +233,6 @@ class ExtensionManagement : public KeyedService {
// aren't deferred).
ExtensionIdSet GetForcePinnedList() const;

// Returns whether the profile associated with this instance is supervised.
bool is_child() const { return is_child_; }

private:
using SettingsIdMap =
std::unordered_map<ExtensionId,
Expand Down Expand Up @@ -339,7 +336,6 @@ class ExtensionManagement : public KeyedService {
const raw_ptr<Profile> profile_ = nullptr;
raw_ptr<PrefService> pref_service_ = nullptr;
bool is_signin_profile_ = false;
bool is_child_ = false;

base::ObserverList<Observer, true>::Unchecked observer_list_;
PrefChangeRegistrar pref_change_registrar_;
Expand Down
13 changes: 12 additions & 1 deletion chrome/browser/extensions/extension_service.cc
Expand Up @@ -127,6 +127,11 @@
#include "storage/browser/file_system/file_system_context.h"
#endif

#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
#include "chrome/browser/supervised_user/supervised_user_service.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#endif // BUILDFLAG(ENABLE_SUPERVISED_USERS)

using content::BrowserContext;
using content::BrowserThread;
using extensions::mojom::ManifestLocation;
Expand Down Expand Up @@ -1222,7 +1227,13 @@ void ExtensionService::CheckManagementPolicy() {

// If this profile is not supervised, then remove any supervised user
// related disable reasons.
if (!profile()->IsChild()) {
bool extensions_permissions_enabled = true;
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
extensions_permissions_enabled =
SupervisedUserServiceFactory::GetForProfile(profile())
->AreExtensionsPermissionsEnabled();
#endif
if (extensions_permissions_enabled) {
disable_reasons &= (~disable_reason::DISABLE_CUSTODIAN_APPROVAL_REQUIRED);
}

Expand Down

0 comments on commit d37abec

Please sign in to comment.