diff --git a/data/org.gnome.shell.gschema.xml.in b/data/org.gnome.shell.gschema.xml.in index f4fa86d01..4ddc6a119 100644 --- a/data/org.gnome.shell.gschema.xml.in +++ b/data/org.gnome.shell.gschema.xml.in @@ -40,6 +40,17 @@ the “enabled-extension” setting. + + true + Allow extension installation + + Allow users to install extensions in their home folder. If disabled, + the InstallRemoteExtension D-Bus method will fail, and extensions + are only loaded from system directories on startup. + It does not affect extensions that are already loaded, so a change + only takes full effect on the next login. + + false Disables the validation of extension version compatibility diff --git a/js/misc/dbusErrors.js b/js/misc/dbusErrors.js index 6f4f80b51..ec726e89c 100644 --- a/js/misc/dbusErrors.js +++ b/js/misc/dbusErrors.js @@ -40,6 +40,7 @@ export const ExtensionError = { DOWNLOAD_FAILED: 1, EXTRACT_FAILED: 2, ENABLE_FAILED: 3, + NOT_ALLOWED: 4, }; export const ExtensionErrors = registerErrorDomain('Extensions', ExtensionError); diff --git a/js/ui/extensionDownloader.js b/js/ui/extensionDownloader.js index 6486bbcad..33f168ce6 100644 --- a/js/ui/extensionDownloader.js +++ b/js/ui/extensionDownloader.js @@ -32,6 +32,13 @@ let _httpSession; * @returns {void} */ export async function installExtension(uuid, invocation) { + if (!global.settings.get_boolean('allow-extension-installation')) { + invocation.return_error_literal( + ExtensionErrors, ExtensionError.NOT_ALLOWED, + 'Extension installation is not allowed'); + return; + } + const params = { uuid, shell_version: Config.PACKAGE_VERSION, diff --git a/js/ui/extensionSystem.js b/js/ui/extensionSystem.js index 07be8066c..76ae58ff4 100644 --- a/js/ui/extensionSystem.js +++ b/js/ui/extensionSystem.js @@ -86,8 +86,11 @@ export class ExtensionManager extends Signals.EventEmitter { get updatesSupported() { const appSys = Shell.AppSystem.get_default(); - return (appSys.lookup_app('org.gnome.Extensions.desktop') !== null) || - (appSys.lookup_app('com.mattjakeman.ExtensionManager.desktop') !== null); + const hasUpdatesApp = + appSys.lookup_app('org.gnome.Extensions.desktop') !== null || + appSys.lookup_app('com.mattjakeman.ExtensionManager.desktop') !== null; + const allowed = global.settings.get_boolean('allow-extension-installation'); + return allowed && hasUpdatesApp; } lookup(uuid) { @@ -745,7 +748,8 @@ export class ExtensionManager extends Signals.EventEmitter { let perUserDir = Gio.File.new_for_path(global.userdatadir); - const extensionFiles = [...FileUtils.collectFromDatadirs('extensions', true)]; + const includeUserDir = global.settings.get_boolean('allow-extension-installation'); + const extensionFiles = [...FileUtils.collectFromDatadirs('extensions', includeUserDir)]; const extensionObjects = extensionFiles.map(({dir, info}) => { let fileType = info.get_file_type(); if (fileType !== Gio.FileType.DIRECTORY)