Commit 4b131cbf authored by Danan S's avatar Danan S Committed by Commit Bot

Changes to Management API to support extensions for child users

This CL allows the management API to properly prompt child users for
parent permission when they attempt to install an extension.   This
is required for the chrome://extensions page whose extension
operations are handled via the management API.

It also allows enabling of extensions that are already
parentally-approved.


Bug: 957832
Change-Id: Id40dd2f5138b4f5a85e91f2f9ffa676130ea9daa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2079529
Commit-Queue: Dan S <danan@chromium.org>
Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#749488}
parent 176fa87b
...@@ -5371,6 +5371,8 @@ jumbo_static_library("browser") { ...@@ -5371,6 +5371,8 @@ jumbo_static_library("browser") {
"supervised_user/mature_extension_checker.h", "supervised_user/mature_extension_checker.h",
"supervised_user/supervised_user_extensions_metrics_recorder.cc", "supervised_user/supervised_user_extensions_metrics_recorder.cc",
"supervised_user/supervised_user_extensions_metrics_recorder.h", "supervised_user/supervised_user_extensions_metrics_recorder.h",
"supervised_user/supervised_user_service_management_api_delegate.cc",
"supervised_user/supervised_user_service_management_api_delegate.h",
] ]
} }
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "chrome/browser/search/instant_service_factory.h" #include "chrome/browser/search/instant_service_factory.h"
#include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h" #include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h"
#include "chrome/browser/ui/webui/devtools_ui.h" #include "chrome/browser/ui/webui/devtools_ui.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/common/webui_url_constants.h" #include "chrome/common/webui_url_constants.h"
#include "components/pdf/browser/pdf_web_contents_helper.h" #include "components/pdf/browser/pdf_web_contents_helper.h"
...@@ -54,6 +55,7 @@ ...@@ -54,6 +55,7 @@
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "extensions/browser/api/management/supervised_user_service_delegate.h"
#include "extensions/browser/api/system_display/display_info_provider.h" #include "extensions/browser/api/system_display/display_info_provider.h"
#include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h" #include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h"
#include "extensions/browser/api/web_request/web_request_info.h" #include "extensions/browser/api/web_request/web_request_info.h"
...@@ -76,9 +78,15 @@ ...@@ -76,9 +78,15 @@
#include "chrome/browser/printing/printing_init.h" #include "chrome/browser/printing/printing_init.h"
#endif #endif
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
// TODO(https://crbug.com/1060801): Here and elsewhere, possibly switch build
// flag to #if defined(OS_CHROMEOS)
#include "chrome/browser/supervised_user/supervised_user_service_management_api_delegate.h"
#endif
namespace extensions { namespace extensions {
ChromeExtensionsAPIClient::ChromeExtensionsAPIClient() {} ChromeExtensionsAPIClient::ChromeExtensionsAPIClient() = default;
ChromeExtensionsAPIClient::~ChromeExtensionsAPIClient() {} ChromeExtensionsAPIClient::~ChromeExtensionsAPIClient() {}
...@@ -335,6 +343,15 @@ ManagementAPIDelegate* ChromeExtensionsAPIClient::CreateManagementAPIDelegate() ...@@ -335,6 +343,15 @@ ManagementAPIDelegate* ChromeExtensionsAPIClient::CreateManagementAPIDelegate()
return new ChromeManagementAPIDelegate; return new ChromeManagementAPIDelegate;
} }
std::unique_ptr<SupervisedUserServiceDelegate>
ChromeExtensionsAPIClient::CreateSupervisedUserServiceDelegate() const {
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
return std::make_unique<SupervisedUserServiceManagementAPIDelegate>();
#else
return nullptr;
#endif
}
std::unique_ptr<DisplayInfoProvider> std::unique_ptr<DisplayInfoProvider>
ChromeExtensionsAPIClient::CreateDisplayInfoProvider() const { ChromeExtensionsAPIClient::CreateDisplayInfoProvider() const {
return CreateChromeDisplayInfoProvider(); return CreateChromeDisplayInfoProvider();
......
...@@ -67,6 +67,9 @@ class ChromeExtensionsAPIClient : public ExtensionsAPIClient { ...@@ -67,6 +67,9 @@ class ChromeExtensionsAPIClient : public ExtensionsAPIClient {
std::unique_ptr<VirtualKeyboardDelegate> CreateVirtualKeyboardDelegate( std::unique_ptr<VirtualKeyboardDelegate> CreateVirtualKeyboardDelegate(
content::BrowserContext* browser_context) const override; content::BrowserContext* browser_context) const override;
ManagementAPIDelegate* CreateManagementAPIDelegate() const override; ManagementAPIDelegate* CreateManagementAPIDelegate() const override;
std::unique_ptr<SupervisedUserServiceDelegate>
CreateSupervisedUserServiceDelegate() const override;
std::unique_ptr<DisplayInfoProvider> CreateDisplayInfoProvider() std::unique_ptr<DisplayInfoProvider> CreateDisplayInfoProvider()
const override; const override;
MetricsPrivateDelegate* GetMetricsPrivateDelegate() override; MetricsPrivateDelegate* GetMetricsPrivateDelegate() override;
......
...@@ -64,6 +64,13 @@ ...@@ -64,6 +64,13 @@
#include "components/arc/session/arc_bridge_service.h" #include "components/arc/session/arc_bridge_service.h"
#endif // OS_CHROMEOS #endif // OS_CHROMEOS
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
// TODO(https://crbug.com/1060801): Here and elsewhere, possibly switch build
// flag to #if defined(OS_CHROMEOS)
#include "chrome/browser/supervised_user/supervised_user_service.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#endif
namespace { namespace {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
...@@ -524,6 +531,16 @@ void ChromeManagementAPIDelegate::EnableExtension( ...@@ -524,6 +531,16 @@ void ChromeManagementAPIDelegate::EnableExtension(
const extensions::Extension* extension = const extensions::Extension* extension =
extensions::ExtensionRegistry::Get(context)->GetExtensionById( extensions::ExtensionRegistry::Get(context)->GetExtensionById(
extension_id, extensions::ExtensionRegistry::EVERYTHING); extension_id, extensions::ExtensionRegistry::EVERYTHING);
#if BUILDFLAG(ENABLE_SUPERVISED_USERS)
// We add approval for the extension here under the assumption that prior
// to this point, the supervised child user has already been prompted
// for, and received parent permission to install the extension.
SupervisedUserService* supervised_user_service =
SupervisedUserServiceFactory::GetForBrowserContext(context);
supervised_user_service->AddExtensionApproval(*extension);
#endif
// If the extension was disabled for a permissions increase, the Management // If the extension was disabled for a permissions increase, the Management
// API will have displayed a re-enable prompt to the user, so we know it's // API will have displayed a re-enable prompt to the user, so we know it's
// safe to grant permissions here. // safe to grant permissions here.
......
// Copyright 2020 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/supervised_user/supervised_user_service_management_api_delegate.h"
#include <memory>
#include <utility>
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/supervised_user/supervised_user_service.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#include "chrome/browser/ui/supervised_user/parent_permission_dialog.h"
namespace {
void OnParentPermissionDialogComplete(
std::unique_ptr<ParentPermissionDialog> dialog,
extensions::SupervisedUserServiceDelegate::
ParentPermissionDialogDoneCallback delegate_done_callback,
ParentPermissionDialog::Result result) {
switch (result) {
case ParentPermissionDialog::Result::kParentPermissionReceived:
std::move(delegate_done_callback)
.Run(extensions::SupervisedUserServiceDelegate::
ParentPermissionDialogResult::kParentPermissionReceived);
break;
case ParentPermissionDialog::Result::kParentPermissionCanceled:
std::move(delegate_done_callback)
.Run(extensions::SupervisedUserServiceDelegate::
ParentPermissionDialogResult::kParentPermissionCanceled);
break;
case ParentPermissionDialog::Result::kParentPermissionFailed:
std::move(delegate_done_callback)
.Run(extensions::SupervisedUserServiceDelegate::
ParentPermissionDialogResult::kParentPermissionFailed);
break;
}
}
} // namespace
namespace extensions {
SupervisedUserServiceManagementAPIDelegate::
SupervisedUserServiceManagementAPIDelegate() = default;
SupervisedUserServiceManagementAPIDelegate::
~SupervisedUserServiceManagementAPIDelegate() = default;
bool SupervisedUserServiceManagementAPIDelegate::
IsSupervisedChildWhoMayInstallExtensions(
content::BrowserContext* context) const {
SupervisedUserService* supervised_user_service =
SupervisedUserServiceFactory::GetForBrowserContext(context);
return supervised_user_service->IsChild() &&
supervised_user_service->CanInstallExtensions();
}
bool SupervisedUserServiceManagementAPIDelegate::IsExtensionAllowedByParent(
const extensions::Extension& extension,
content::BrowserContext* context) const {
SupervisedUserService* supervised_user_service =
SupervisedUserServiceFactory::GetForBrowserContext(context);
return IsSupervisedChildWhoMayInstallExtensions(context) &&
supervised_user_service->IsExtensionAllowed(extension);
}
void SupervisedUserServiceManagementAPIDelegate::
ShowParentPermissionDialogForExtension(
const extensions::Extension& extension,
content::BrowserContext* context,
content::WebContents* contents,
ParentPermissionDialogDoneCallback done_callback) {
std::unique_ptr<ParentPermissionDialog> dialog =
std::make_unique<ParentPermissionDialog>(
Profile::FromBrowserContext(context));
// Cache the pointer so we can show the dialog after we pass
// ownership to the callback.
ParentPermissionDialog* dialog_ptr = dialog.get();
// Ownership of the dialog passes to the callback. This allows us
// to have as many instances of the dialog as calls to the management
// API.
ParentPermissionDialog::DoneCallback inner_done_callback =
base::BindOnce(&::OnParentPermissionDialogComplete, std::move(dialog),
std::move(done_callback));
// This is safe because moving a unique_ptr doesn't change the underlying
// object's address.
dialog_ptr->ShowPromptForExtensionInstallation(
contents, &extension, SkBitmap(), std::move(inner_done_callback));
}
} // namespace extensions
// Copyright 2020 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_SUPERVISED_USER_SUPERVISED_USER_SERVICE_MANAGEMENT_API_DELEGATE_H_
#define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SERVICE_MANAGEMENT_API_DELEGATE_H_
#include "extensions/browser/api/management/supervised_user_service_delegate.h"
namespace content {
class BrowserContext;
}
namespace extensions {
class SupervisedUserServiceManagementAPIDelegate
: public extensions::SupervisedUserServiceDelegate {
public:
SupervisedUserServiceManagementAPIDelegate();
~SupervisedUserServiceManagementAPIDelegate() override;
// extensions::SupervisedUserServiceDelegate overrides
bool IsSupervisedChildWhoMayInstallExtensions(
content::BrowserContext* context) const override;
bool IsExtensionAllowedByParent(
const extensions::Extension& extension,
content::BrowserContext* context) const override;
void ShowParentPermissionDialogForExtension(
const extensions::Extension& extension,
content::BrowserContext* context,
content::WebContents* contents,
extensions::SupervisedUserServiceDelegate::
ParentPermissionDialogDoneCallback done_callback) override;
};
} // namespace extensions
#endif // CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SERVICE_MANAGEMENT_API_DELEGATE_H_
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "extensions/browser/api/device_permissions_prompt.h" #include "extensions/browser/api/device_permissions_prompt.h"
#include "extensions/browser/api/management/supervised_user_service_delegate.h"
#include "extensions/browser/api/system_display/display_info_provider.h" #include "extensions/browser/api/system_display/display_info_provider.h"
#include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h" #include "extensions/browser/api/virtual_keyboard_private/virtual_keyboard_delegate.h"
#include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h" #include "extensions/browser/guest_view/extensions_guest_view_manager_delegate.h"
...@@ -120,6 +121,11 @@ ManagementAPIDelegate* ExtensionsAPIClient::CreateManagementAPIDelegate() ...@@ -120,6 +121,11 @@ ManagementAPIDelegate* ExtensionsAPIClient::CreateManagementAPIDelegate()
return nullptr; return nullptr;
} }
std::unique_ptr<SupervisedUserServiceDelegate>
ExtensionsAPIClient::CreateSupervisedUserServiceDelegate() const {
return nullptr;
}
std::unique_ptr<DisplayInfoProvider> std::unique_ptr<DisplayInfoProvider>
ExtensionsAPIClient::CreateDisplayInfoProvider() const { ExtensionsAPIClient::CreateDisplayInfoProvider() const {
return nullptr; return nullptr;
......
...@@ -55,6 +55,7 @@ class NetworkingCastPrivateDelegate; ...@@ -55,6 +55,7 @@ class NetworkingCastPrivateDelegate;
class NonNativeFileSystemDelegate; class NonNativeFileSystemDelegate;
class RulesCacheDelegate; class RulesCacheDelegate;
class SettingsObserver; class SettingsObserver;
class SupervisedUserServiceDelegate;
class ValueStoreCache; class ValueStoreCache;
class ValueStoreFactory; class ValueStoreFactory;
class VirtualKeyboardDelegate; class VirtualKeyboardDelegate;
...@@ -167,6 +168,11 @@ class ExtensionsAPIClient { ...@@ -167,6 +168,11 @@ class ExtensionsAPIClient {
// Creates a delegate for handling the management extension api. // Creates a delegate for handling the management extension api.
virtual ManagementAPIDelegate* CreateManagementAPIDelegate() const; virtual ManagementAPIDelegate* CreateManagementAPIDelegate() const;
// Creates a delegate for calling into the SupervisedUserService from the
// Management API.
virtual std::unique_ptr<SupervisedUserServiceDelegate>
CreateSupervisedUserServiceDelegate() const;
// Creates and returns the DisplayInfoProvider used by the // Creates and returns the DisplayInfoProvider used by the
// chrome.system.display extension API. // chrome.system.display extension API.
virtual std::unique_ptr<DisplayInfoProvider> CreateDisplayInfoProvider() virtual std::unique_ptr<DisplayInfoProvider> CreateDisplayInfoProvider()
......
...@@ -14,6 +14,7 @@ source_set("management") { ...@@ -14,6 +14,7 @@ source_set("management") {
"management_api_constants.cc", "management_api_constants.cc",
"management_api_constants.h", "management_api_constants.h",
"management_api_delegate.h", "management_api_delegate.h",
"supervised_user_service_delegate.h",
] ]
deps = [ "//extensions/common/api" ] deps = [ "//extensions/common/api" ]
......
...@@ -406,11 +406,9 @@ ExtensionFunction::ResponseAction ManagementLaunchAppFunction::Run() { ...@@ -406,11 +406,9 @@ ExtensionFunction::ResponseAction ManagementLaunchAppFunction::Run() {
return RespondNow(NoArguments()); return RespondNow(NoArguments());
} }
ManagementSetEnabledFunction::ManagementSetEnabledFunction() { ManagementSetEnabledFunction::ManagementSetEnabledFunction() = default;
}
ManagementSetEnabledFunction::~ManagementSetEnabledFunction() { ManagementSetEnabledFunction::~ManagementSetEnabledFunction() = default;
}
ExtensionFunction::ResponseAction ManagementSetEnabledFunction::Run() { ExtensionFunction::ResponseAction ManagementSetEnabledFunction::Run() {
std::unique_ptr<management::SetEnabled::Params> params( std::unique_ptr<management::SetEnabled::Params> params(
...@@ -432,12 +430,41 @@ ExtensionFunction::ResponseAction ManagementSetEnabledFunction::Run() { ...@@ -432,12 +430,41 @@ ExtensionFunction::ResponseAction ManagementSetEnabledFunction::Run() {
return RespondNow(Error(keys::kNoExtensionError, extension_id_)); return RespondNow(Error(keys::kNoExtensionError, extension_id_));
bool enabled = params->enabled; bool enabled = params->enabled;
const SupervisedUserServiceDelegate* supervised_user_service_delegate =
ManagementAPI::GetFactoryInstance()
->Get(browser_context())
->GetSupervisedUserServiceDelegate();
const bool is_supervised_child_who_may_install_extensions =
supervised_user_service_delegate
? supervised_user_service_delegate
->IsSupervisedChildWhoMayInstallExtensions(browser_context())
: false;
const ManagementPolicy* policy = const ManagementPolicy* policy =
ExtensionSystem::Get(browser_context())->management_policy(); ExtensionSystem::Get(browser_context())->management_policy();
if (!policy->ExtensionMayModifySettings(extension(), target_extension, if (!policy->ExtensionMayModifySettings(extension(), target_extension,
nullptr) || nullptr)) {
(enabled && return RespondNow(Error(keys::kUserCantModifyError, extension_id_));
policy->MustRemainDisabled(target_extension, nullptr, nullptr))) { }
disable_reason::DisableReason reason;
bool disallow_enable =
enabled && policy->MustRemainDisabled(target_extension, &reason, nullptr);
// Figure out if we should prompt for parental approval.
bool prompt_parent_for_approval =
disallow_enable && is_supervised_child_who_may_install_extensions &&
reason ==
disable_reason::DisableReason::DISABLE_CUSTODIAN_APPROVAL_REQUIRED;
// If the extension can't be enabled, only continue if we plan to prompt for
// parental approval.
if (disallow_enable && !prompt_parent_for_approval) {
LOG(ERROR) << "ManagementSetEnabledFunction::Run: extension may not be "
"enabled, and we're not prompting for parent approval";
return RespondNow(Error(keys::kUserCantModifyError, extension_id_)); return RespondNow(Error(keys::kUserCantModifyError, extension_id_));
} }
...@@ -467,6 +494,18 @@ ExtensionFunction::ResponseAction ManagementSetEnabledFunction::Run() { ...@@ -467,6 +494,18 @@ ExtensionFunction::ResponseAction ManagementSetEnabledFunction::Run() {
this)); // This bind creates a reference. this)); // This bind creates a reference.
return RespondLater(); return RespondLater();
} }
// Handle parental approval for child accounts that have the
// ability to install extensions.
if (prompt_parent_for_approval &&
// Don't re-prompt the parent for extensions that have already been
// approved for a child.
!supervised_user_service_delegate->IsExtensionAllowedByParent(
*target_extension, browser_context())) {
LOG(ERROR) << "ManagementSetEnabledFunction::Run: prompting for parent "
"approval";
return RequestParentPermission(target_extension);
}
delegate->EnableExtension(browser_context(), extension_id_); delegate->EnableExtension(browser_context(), extension_id_);
} else if (currently_enabled && !params->enabled) { } else if (currently_enabled && !params->enabled) {
delegate->DisableExtension( delegate->DisableExtension(
...@@ -506,6 +545,54 @@ void ManagementSetEnabledFunction::OnRequirementsChecked( ...@@ -506,6 +545,54 @@ void ManagementSetEnabledFunction::OnRequirementsChecked(
} }
} }
ExtensionFunction::ResponseAction
ManagementSetEnabledFunction::RequestParentPermission(
const Extension* extension) {
content::WebContents* web_contents = GetSenderWebContents();
if (!web_contents)
return RespondNow(Error(keys::kWebContentsDisappearedError));
// Show parental approval prompt.
auto callback = base::BindOnce(
&ManagementSetEnabledFunction::OnParentPermissionDone, this);
SupervisedUserServiceDelegate* supervised_user_service_delegate =
ManagementAPI::GetFactoryInstance()
->Get(browser_context())
->GetSupervisedUserServiceDelegate();
DCHECK(supervised_user_service_delegate);
supervised_user_service_delegate->ShowParentPermissionDialogForExtension(
*extension, browser_context(), web_contents, std::move(callback));
return RespondLater();
}
void ManagementSetEnabledFunction::OnParentPermissionDone(
SupervisedUserServiceDelegate::ParentPermissionDialogResult result) {
switch (result) {
case SupervisedUserServiceDelegate::ParentPermissionDialogResult::
kParentPermissionReceived: {
const ManagementAPIDelegate* delegate =
ManagementAPI::GetFactoryInstance()
->Get(browser_context())
->GetDelegate();
delegate->EnableExtension(browser_context(), extension_id_);
Respond(OneArgument(std::make_unique<base::Value>(true)));
break;
}
case SupervisedUserServiceDelegate::ParentPermissionDialogResult::
kParentPermissionCanceled: {
Respond(Error(keys::kUserDidNotReEnableError));
break;
}
case SupervisedUserServiceDelegate::ParentPermissionDialogResult::
kParentPermissionFailed: {
Respond(Error(keys::kParentPermissionFailedError));
break;
}
}
}
ManagementUninstallFunctionBase::ManagementUninstallFunctionBase() { ManagementUninstallFunctionBase::ManagementUninstallFunctionBase() {
} }
...@@ -1043,7 +1130,9 @@ void ManagementEventRouter::BroadcastEvent( ...@@ -1043,7 +1130,9 @@ void ManagementEventRouter::BroadcastEvent(
ManagementAPI::ManagementAPI(content::BrowserContext* context) ManagementAPI::ManagementAPI(content::BrowserContext* context)
: browser_context_(context), : browser_context_(context),
delegate_(ExtensionsAPIClient::Get()->CreateManagementAPIDelegate()) { delegate_(ExtensionsAPIClient::Get()->CreateManagementAPIDelegate()),
supervised_user_service_delegate_(
ExtensionsAPIClient::Get()->CreateSupervisedUserServiceDelegate()) {
EventRouter* event_router = EventRouter::Get(browser_context_); EventRouter* event_router = EventRouter::Get(browser_context_);
event_router->RegisterObserver(this, management::OnInstalled::kEventName); event_router->RegisterObserver(this, management::OnInstalled::kEventName);
event_router->RegisterObserver(this, management::OnUninstalled::kEventName); event_router->RegisterObserver(this, management::OnUninstalled::kEventName);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "extensions/browser/api/management/management_api_delegate.h" #include "extensions/browser/api/management/management_api_delegate.h"
#include "extensions/browser/api/management/supervised_user_service_delegate.h"
#include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/event_router.h" #include "extensions/browser/event_router.h"
#include "extensions/browser/extension_event_histogram_value.h" #include "extensions/browser/extension_event_histogram_value.h"
...@@ -116,6 +117,15 @@ class ManagementSetEnabledFunction : public ExtensionFunction { ...@@ -116,6 +117,15 @@ class ManagementSetEnabledFunction : public ExtensionFunction {
void OnRequirementsChecked(const PreloadCheck::Errors& errors); void OnRequirementsChecked(const PreloadCheck::Errors& errors);
ExtensionFunction::ResponseAction RequestParentPermission(
const Extension* extension);
void OnParentPermissionDone(
SupervisedUserServiceDelegate::ParentPermissionDialogResult result);
std::unique_ptr<SupervisedUserServiceDelegate::ParentPermissionDialogResult>
parental_permission_dialog_;
std::string extension_id_; std::string extension_id_;
std::unique_ptr<InstallPromptDelegate> install_prompt_; std::unique_ptr<InstallPromptDelegate> install_prompt_;
...@@ -315,6 +325,12 @@ class ManagementAPI : public BrowserContextKeyedAPI, ...@@ -315,6 +325,12 @@ class ManagementAPI : public BrowserContextKeyedAPI,
// Returns the ManagementAPI delegate. // Returns the ManagementAPI delegate.
const ManagementAPIDelegate* GetDelegate() const { return delegate_.get(); } const ManagementAPIDelegate* GetDelegate() const { return delegate_.get(); }
// Returns the SupervisedUserService delegate, which might be null depending
// on the extensions embedder.
SupervisedUserServiceDelegate* GetSupervisedUserServiceDelegate() const {
return supervised_user_service_delegate_.get();
}
private: private:
friend class BrowserContextKeyedAPIFactory<ManagementAPI>; friend class BrowserContextKeyedAPIFactory<ManagementAPI>;
...@@ -329,6 +345,8 @@ class ManagementAPI : public BrowserContextKeyedAPI, ...@@ -329,6 +345,8 @@ class ManagementAPI : public BrowserContextKeyedAPI,
std::unique_ptr<ManagementEventRouter> management_event_router_; std::unique_ptr<ManagementEventRouter> management_event_router_;
std::unique_ptr<ManagementAPIDelegate> delegate_; std::unique_ptr<ManagementAPIDelegate> delegate_;
std::unique_ptr<SupervisedUserServiceDelegate>
supervised_user_service_delegate_;
DISALLOW_COPY_AND_ASSIGN(ManagementAPI); DISALLOW_COPY_AND_ASSIGN(ManagementAPI);
}; };
......
...@@ -63,5 +63,8 @@ const char kInstallReplacementAndroidAppNotFromWebstoreError[] = ...@@ -63,5 +63,8 @@ const char kInstallReplacementAndroidAppNotFromWebstoreError[] =
"Only extensions from the web store can install replacement Android apps."; "Only extensions from the web store can install replacement Android apps.";
const char kInstallReplacementAndroidAppCannotInstallApp[] = const char kInstallReplacementAndroidAppCannotInstallApp[] =
"Could not install Android App."; "Could not install Android App.";
const char kWebContentsDisappearedError[] =
"Web contents disappeared while attempting to enable extension.";
const char kParentPermissionFailedError[] = "Parent Permission Request Failed.";
} // namespace extension_management_api_constants } // namespace extension_management_api_constants
...@@ -44,6 +44,8 @@ extern const char kGestureNeededForInstallReplacementAndroidAppError[]; ...@@ -44,6 +44,8 @@ extern const char kGestureNeededForInstallReplacementAndroidAppError[];
extern const char kInstallReplacementAndroidAppCannotInstallApp[]; extern const char kInstallReplacementAndroidAppCannotInstallApp[];
extern const char kInstallReplacementAndroidAppInvalidContextError[]; extern const char kInstallReplacementAndroidAppInvalidContextError[];
extern const char kInstallReplacementAndroidAppNotFromWebstoreError[]; extern const char kInstallReplacementAndroidAppNotFromWebstoreError[];
extern const char kWebContentsDisappearedError[];
extern const char kParentPermissionFailedError[];
} // namespace extension_management_api_constants } // namespace extension_management_api_constants
......
// Copyright 2020 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 EXTENSIONS_BROWSER_API_MANAGEMENT_SUPERVISED_USER_SERVICE_DELEGATE_H_
#define EXTENSIONS_BROWSER_API_MANAGEMENT_SUPERVISED_USER_SERVICE_DELEGATE_H_
#include "base/callback.h"
#include "extensions/common/extension.h"
namespace content {
class BrowserContext;
class WebContents;
} // namespace content
namespace extensions {
class SupervisedUserServiceDelegate {
public:
virtual ~SupervisedUserServiceDelegate() = default;
// Returns true if |context| represents a supervised child account
// who may install extensions with parent permission.
virtual bool IsSupervisedChildWhoMayInstallExtensions(
content::BrowserContext* context) const = 0;
// Returns true if the current child user is allowed to install the specified
// |extension|.
virtual bool IsExtensionAllowedByParent(
const extensions::Extension& extension,
content::BrowserContext* context) const = 0;
// Result of the parent permission dialog invocation.
enum class ParentPermissionDialogResult {
kParentPermissionReceived,
kParentPermissionCanceled,
kParentPermissionFailed,
};
using ParentPermissionDialogDoneCallback =
base::OnceCallback<void(ParentPermissionDialogResult)>;
// Show a parent permission dialog for |extension| and call |done_callback|
// when it completes.
virtual void ShowParentPermissionDialogForExtension(
const extensions::Extension& extension,
content::BrowserContext* context,
content::WebContents* contents,
ParentPermissionDialogDoneCallback done_callback) = 0;
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_MANAGEMENT_SUPERVISED_USER_SERVICE_DELEGATE_H_
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