browser/components/enterprisepolicies/PoliciesValidator.jsm
author Kris Maglione <maglione.k@gmail.com>
Mon, 29 Jan 2018 15:20:18 -0800
changeset 453844 34c999fa006bffe8705cf50c54708aa21a962e62
parent 453830 505fc52bd6080c95bf27458a5753340b326f0fa1
child 453889 c6e0fe339cb1e7c0c029e68be5332e52f53ab6b7
permissions -rw-r--r--
Bug 1431533: Part 5a - Auto-rewrite code to use ChromeUtils import methods. r=florian This was done using the following script: https://bitbucket.org/kmaglione/m-c-rewrites/src/37e3803c7a23385bab5ea077ba8692bcfe1608fc/processors/chromeutils-import.jsm MozReview-Commit-ID: 1Nc3XDu0wGl

/* 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/. */

"use strict";

const Ci = Components.interfaces;
const Cc = Components.classes;
const Cr = Components.results;
const Cu = Components.utils;

ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");

const PREF_LOGLEVEL           = "browser.policies.loglevel";

XPCOMUtils.defineLazyGetter(this, "log", () => {
  let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
  return new ConsoleAPI({
    prefix: "PoliciesValidator.jsm",
    // tip: set maxLogLevel to "debug" and use log.debug() to create detailed
    // messages during development. See LOG_LEVELS in Console.jsm for details.
    maxLogLevel: "error",
    maxLogLevelPref: PREF_LOGLEVEL,
  });
});

this.EXPORTED_SYMBOLS = ["PoliciesValidator"];

this.PoliciesValidator = {
  validateAndParseParameters(param, properties) {
    return validateAndParseParamRecursive(param, properties);
  }
};

function validateAndParseParamRecursive(param, properties) {
  if (properties.enum) {
    if (properties.enum.includes(param)) {
      return [true, param];
    }
    return [false, null];
  }

  log.debug(`checking @${param}@ for type ${properties.type}`);
  switch (properties.type) {
    case "boolean":
    case "number":
    case "integer":
    case "string":
    case "URL":
    case "origin":
      return validateAndParseSimpleParam(param, properties.type);

    case "array":
      if (!Array.isArray(param)) {
        log.error("Array expected but not received");
        return [false, null];
      }

      let parsedArray = [];
      for (let item of param) {
        log.debug(`in array, checking @${item}@ for type ${properties.items.type}`);
        let [valid, parsedValue] = validateAndParseParamRecursive(item, properties.items);
        if (!valid) {
          return [false, null];
        }

        parsedArray.push(parsedValue);
      }

      return [true, parsedArray];

    case "object": {
      if (typeof(param) != "object") {
        log.error("Object expected but not received");
        return [false, null];
      }

      let parsedObj = {};
      for (let property of Object.keys(properties.properties)) {
        log.debug(`in object, for property ${property} checking @${param[property]}@ for type ${properties.properties[property].type}`);
        let [valid, parsedValue] = validateAndParseParamRecursive(param[property], properties.properties[property]);
        if (!valid) {
          return [false, null];
        }

        parsedObj[property] = parsedValue;
      }

      return [true, parsedObj];
    }
  }

  return [false, null];
}

function validateAndParseSimpleParam(param, type) {
  let valid = false;
  let parsedParam = param;

  switch (type) {
    case "boolean":
    case "number":
    case "string":
      valid = (typeof(param) == type);
      break;

    // integer is an alias to "number" that some JSON schema tools use
    case "integer":
      valid = (typeof(param) == "number");
      break;

    case "origin":
      if (typeof(param) != "string") {
        break;
      }

      try {
        parsedParam = Services.io.newURI(param);

        let pathQueryRef = parsedParam.pathQueryRef;
        // Make sure that "origin" types won't accept full URLs.
        if (pathQueryRef != "/" && pathQueryRef != "") {
          valid = false;
        } else {
          valid = true;
        }
      } catch (ex) {
        valid = false;
      }
      break;

    case "URL":
      if (typeof(param) != "string") {
        break;
      }

      try {
        parsedParam = Services.io.newURI(param);
        valid = true;
      } catch (ex) {
        valid = false;
      }
      break;
  }

  return [valid, parsedParam];
}