Skip to content

Instantly share code, notes, and snippets.

@felipc
Created November 17, 2017 02:06
Show Gist options
  • Save felipc/e29931dbbd1ab1565a05e454d7c6d99b to your computer and use it in GitHub Desktop.
Save felipc/e29931dbbd1ab1565a05e454d7c6d99b to your computer and use it in GitHub Desktop.
First draft of an enterprise policies component
diff --git a/browser/components/enterprisepolicies/EnterprisePolicies.js b/browser/components/enterprisepolicies/EnterprisePolicies.js
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/EnterprisePolicies.js
@@ -0,0 +1,157 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/AppConstants.jsm");
+
+
+// TODO: THIS JSON WILL LIVE IN A SEPARATE FILE
+const SAMPLE_JSON = {
+ version: 1,
+ policies: {
+ "block-about-config": true,
+ "block-devtools": true,
+ "custom-homepage": "https://www.mozilla.org/firefox/new/",
+ }
+}
+
+// XPCOM BOILERPLATE
+
+// Factory object
+const EnterprisePoliciesFactory = {
+ _instance: null,
+ createInstance: function BGSF_createInstance(outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+ return this._instance == null ?
+ this._instance = new EnterprisePoliciesManager() : this._instance;
+ }
+};
+
+// END XPCOM BOILERPLATE
+
+// Constructor
+function EnterprisePoliciesManager() {
+ this._init();
+}
+
+let hasValidCustomization = false;
+
+let Policies = {
+ blockAboutConfig: false,
+ blockDevtools: false,
+ customHomepage: null,
+};
+
+
+EnterprisePoliciesManager.prototype = {
+ // for XPCOM
+ classID: Components.ID("{ea4e1414-779b-458b-9d1f-d18e8efbc145}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsISupportsWeakReference,
+ Ci.nsIEnterprisePolicies]),
+
+ // redefine the default factory for XPCOMUtils
+ _xpcom_factory: EnterprisePoliciesFactory,
+
+ // nsIObserver implementation
+ observe: function BG_observe(subject, topic, data) {
+ switch (topic) {
+ case "final-ui-startup":
+ this._beforeUIStartup();
+ break;
+ }
+ },
+
+ _init() {
+ // INIT should only be used to parse the JSON, because
+ // this is running very early.
+ // Any actual work to be done by policies should be done
+ // later (and as late as possible) by using some observer.
+ // There are lots of good examples on nsBrowserGlue.js.
+ let os = Services.obs;
+ os.addObserver(this, "final-ui-startup");
+ this._parseConfiguration();
+ },
+
+ _dispose() {
+ // TODO: call dispose like in nsBrowserGlue
+ let os = Services.obs;
+ os.removeObserver(this, "final-ui-startup");
+ },
+
+ _parseConfiguration() {
+ let json = SAMPLE_JSON; // TODO: replace this by reading the file
+
+ if (json.version != 1) {
+ return;
+ }
+
+ hasValidCustomization = true;
+
+ for (let policyName of Object.keys(json.policies)) {
+ let policySetting = json.policies[policyName];
+
+ switch (policyName) {
+ case "block-about-config":
+ Policies.blockAboutConfig = (policySetting == true);
+ break;
+
+ case "block-devtools":
+ Policies.blockDevtools = (policySetting == true);
+
+ case "custom-homepage":
+ // TODO: parse URL to check if it's a valid URL
+ Policies.customHomepage = policySetting;
+ break;
+
+ // etc.
+
+ default:
+ // TODO: log unknown policy
+
+ }
+
+ }
+ },
+
+ // runs on startup, before the first window is opened)
+ _beforeUIStartup() {
+
+ },
+
+
+ // ------------------------------
+ // public nsIEnterprisePolicies members
+ // ------------------------------
+
+ isAllowed: function BG_sanitize(policy) {
+ if (!hasValidCustomization) {
+ // We assume that all policies that are checked through "isAllowed"
+ // are about restricting access to something, so if there wasn't a
+ // valid customization file, we short-circuit anything to be *allowed*
+ return true;
+ }
+
+ switch (policy) {
+ case "block-devtools":
+ return Policies.blockDevtools;
+
+ case "about:config":
+ return !Policies.blockAboutConfig;
+ }
+
+ return (Math.random() > 0.5);
+ },
+};
+
+
+var components = [EnterprisePoliciesManager];
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
diff --git a/browser/components/enterprisepolicies/EnterprisePolicies.manifest b/browser/components/enterprisepolicies/EnterprisePolicies.manifest
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/EnterprisePolicies.manifest
@@ -0,0 +1,3 @@
+component {ea4e1414-779b-458b-9d1f-d18e8efbc145} EnterprisePolicies.js
+contract @mozilla.org/browser/enterprisepolicies;1 {ea4e1414-779b-458b-9d1f-d18e8efbc145}
+category app-startup EnterprisePolicies service,@mozilla.org/browser/enterprisepolicies;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
diff --git a/browser/components/enterprisepolicies/moz.build b/browser/components/enterprisepolicies/moz.build
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/moz.build
@@ -0,0 +1,21 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files("**"):
+ BUG_COMPONENT = ("Firefox", "General")
+
+XPIDL_SOURCES += [
+ 'nsIEnterprisePolicies.idl',
+]
+
+XPIDL_MODULE = 'enterprisepolicies'
+
+EXTRA_COMPONENTS += [
+ 'EnterprisePolicies.js',
+ 'EnterprisePolicies.manifest',
+]
+
+FINAL_LIBRARY = 'browsercomps'
diff --git a/browser/components/enterprisepolicies/nsIEnterprisePolicies.idl b/browser/components/enterprisepolicies/nsIEnterprisePolicies.idl
new file mode 100644
--- /dev/null
+++ b/browser/components/enterprisepolicies/nsIEnterprisePolicies.idl
@@ -0,0 +1,11 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(6a568972-cc91-4bf5-963e-3768f3319b8a)]
+interface nsIEnterprisePolicies : nsISupports
+{
+ bool isAllowed(in ACString policy);
+};
diff --git a/browser/components/moz.build b/browser/components/moz.build
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -33,16 +33,17 @@ with Files('controlcenter/**'):
DIRS += [
'about',
'contextualidentity',
'customizableui',
'dirprovider',
'downloads',
+ 'enterprisepolicies',
'extensions',
'feeds',
'migration',
'newtab',
'originattributes',
'places',
'preferences',
'privatebrowsing',
diff --git a/toolkit/modules/Services.jsm b/toolkit/modules/Services.jsm
--- a/toolkit/modules/Services.jsm
+++ b/toolkit/modules/Services.jsm
@@ -84,16 +84,17 @@ var initTable = {
droppedLinkHandler: ["@mozilla.org/content/dropped-link-handler;1", "nsIDroppedLinkHandler"],
els: ["@mozilla.org/eventlistenerservice;1", "nsIEventListenerService"],
eTLD: ["@mozilla.org/network/effective-tld-service;1", "nsIEffectiveTLDService"],
intl: ["@mozilla.org/mozintl;1", "mozIMozIntl"],
locale: ["@mozilla.org/intl/localeservice;1", "mozILocaleService"],
logins: ["@mozilla.org/login-manager;1", "nsILoginManager"],
obs: ["@mozilla.org/observer-service;1", "nsIObserverService"],
perms: ["@mozilla.org/permissionmanager;1", "nsIPermissionManager"],
+ policies: ["@mozilla.org/browser/enterprisepolicies;1", "nsIEnterprisePolicies"],
prompt: ["@mozilla.org/embedcomp/prompt-service;1", "nsIPromptService"],
scriptloader: ["@mozilla.org/moz/jssubscript-loader;1", "mozIJSSubScriptLoader"],
scriptSecurityManager: ["@mozilla.org/scriptsecuritymanager;1", "nsIScriptSecurityManager"],
storage: ["@mozilla.org/storage/service;1", "mozIStorageService"],
domStorageManager: ["@mozilla.org/dom/localStorage-manager;1", "nsIDOMStorageManager"],
strings: ["@mozilla.org/intl/stringbundle;1", "nsIStringBundleService"],
telemetry: ["@mozilla.org/base/telemetry;1", "nsITelemetry"],
tm: ["@mozilla.org/thread-manager;1", "nsIThreadManager"],
diff --git a/toolkit/modules/tests/xpcshell/test_Services.js b/toolkit/modules/tests/xpcshell/test_Services.js
--- a/toolkit/modules/tests/xpcshell/test_Services.js
+++ b/toolkit/modules/tests/xpcshell/test_Services.js
@@ -46,16 +46,17 @@ function run_test() {
checkService("io", Ci.nsIIOService2);
checkService("intl", Ci.mozIMozIntl);
checkService("locale", Ci.mozILocaleService);
checkService("logins", Ci.nsILoginManager);
checkService("obs", Ci.nsIObserverService);
checkService("perms", Ci.nsIPermissionManager);
checkService("prefs", Ci.nsIPrefBranch);
checkService("prefs", Ci.nsIPrefService);
+ checkService("policies", Ci.nsIEnterprisePolicies);
checkService("prompt", Ci.nsIPromptService);
checkService("scriptSecurityManager", Ci.nsIScriptSecurityManager);
checkService("scriptloader", Ci.mozIJSSubScriptLoader);
checkService("startup", Ci.nsIAppStartup);
checkService("storage", Ci.mozIStorageService);
checkService("strings", Ci.nsIStringBundleService);
checkService("sysinfo", Ci.nsIPropertyBag2);
checkService("telemetry", Ci.nsITelemetry);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment