<commit_before>/*    Copyright 2016 Firewalla LLC / Firewalla LLC 
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

'use strict'

const log = require('../net2/logger.js')(__filename);

const util = require('util');
const minimatch = require("minimatch");
const cronParser = require('cron-parser');

const _ = require('lodash');
const flat = require('flat');
const iptool = require('ip');
const POLICY_MIN_EXPIRE_TIME = 60 // if policy is going to expire in 60 seconds, don't bother to enforce it.

function arraysEqual(a, b) {
  if (a === b) return true;
  if (a == null || b == null) return false;
  if (a.length != b.length) return false;

  // If you don't care about the order of the elements inside
  // the array, you should sort both arrays here.

  for (var i = 0; i < a.length; ++i) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}

class Policy {
  constructor(raw) {
    if (!raw) throw new Error("Empty policy payload");
    if (!raw.type && !raw['i.type']) throw new Error("Invalid policy payload");
    if (raw.type == 'internet') throw new Error(`Invalid policy type ${raw.type}`);

    Object.assign(this, raw);

    if (raw.scope) {
      if (_.isString(raw.scope)) {
        try {
          this.scope = JSON.parse(raw.scope)
        } catch (e) {
          log.error("Failed to parse policy scope string:", raw.scope, e)
        }
      } else if (_.isArray(raw.scope)) {
        this.scope = raw.scope.slice(0) // clone array to avoide side effects
      } else {
        log.error("Unsupported scope", raw.scope)
      }

      if (!_.isArray(this.scope) || _.isEmpty(this.scope))
        delete this.scope;
    }

    if (raw.tag) {
      if (_.isString(raw.tag)) {
        try {
          this.tag = JSON.parse(raw.tag)
        } catch (e) {
          log.error("Failed to parse policy tag string:", raw.tag, e)
        }
      } else if (_.isArray(raw.tag)) {
        this.tag = Array.from(raw.tag); // clone array to avoide side effects
      } else {
        log.error("Unsupported tag", raw.tag)
      }

      if (!_.isArray(this.tag) || _.isEmpty(this.tag))
        delete this.tag;
    }
    this.upnp = false;
    if (raw.upnp)
      this.upnp = JSON.parse(raw.upnp);

    this.dnsmasq_only = false;
    if (raw.dnsmasq_only)
      this.dnsmasq_only = JSON.parse(raw.dnsmasq_only);

    if (!raw.direction)
      this.direction = "bidirection";
    
    if (!raw.action)
      this.action = "block";

    if (raw.expire === "") {
      delete this.expire;
    } else if (raw.expire && _.isString(raw.expire)) {
      try {
        this.expire = parseInt(raw.expire)
      } catch (e) {
        log.error("Failed to parse policy expire time:", raw.expire, e);
        delete this.expire;
      }
    }

    if (raw.cronTime === "") {
      delete this.cronTime;
    }

    // backward compatibilities
    if (this['i.type']) {
      this.type = this['i.type'];
      delete this['i.type'];
    }<commit_msg>convert rateLimit and priority to number in Policy constructor<commit_after>/*    Copyright 2016 Firewalla LLC / Firewalla LLC 
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

'use strict'

const log = require('../net2/logger.js')(__filename);

const util = require('util');
const minimatch = require("minimatch");
const cronParser = require('cron-parser');

const _ = require('lodash');
const flat = require('flat');
const iptool = require('ip');
const POLICY_MIN_EXPIRE_TIME = 60 // if policy is going to expire in 60 seconds, don't bother to enforce it.

function arraysEqual(a, b) {
  if (a === b) return true;
  if (a == null || b == null) return false;
  if (a.length != b.length) return false;

  // If you don't care about the order of the elements inside
  // the array, you should sort both arrays here.

  for (var i = 0; i < a.length; ++i) {
    if (a[i] !== b[i]) return false;
  }
  return true;
}

class Policy {
  constructor(raw) {
    if (!raw) throw new Error("Empty policy payload");
    if (!raw.type && !raw['i.type']) throw new Error("Invalid policy payload");
    if (raw.type == 'internet') throw new Error(`Invalid policy type ${raw.type}`);

    Object.assign(this, raw);

    if (raw.scope) {
      if (_.isString(raw.scope)) {
        try {
          this.scope = JSON.parse(raw.scope)
        } catch (e) {
          log.error("Failed to parse policy scope string:", raw.scope, e)
        }
      } else if (_.isArray(raw.scope)) {
        this.scope = raw.scope.slice(0) // clone array to avoide side effects
      } else {
        log.error("Unsupported scope", raw.scope)
      }

      if (!_.isArray(this.scope) || _.isEmpty(this.scope))
        delete this.scope;
    }

    if (raw.tag) {
      if (_.isString(raw.tag)) {
        try {
          this.tag = JSON.parse(raw.tag)
        } catch (e) {
          log.error("Failed to parse policy tag string:", raw.tag, e)
        }
      } else if (_.isArray(raw.tag)) {
        this.tag = Array.from(raw.tag); // clone array to avoide side effects
      } else {
        log.error("Unsupported tag", raw.tag)
      }

      if (!_.isArray(this.tag) || _.isEmpty(this.tag))
        delete this.tag;
    }
    this.upnp = false;
    if (raw.upnp)
      this.upnp = JSON.parse(raw.upnp);

    if (raw.rateLimit)
      this.rateLimit = Number(raw.rateLimit);

    if (raw.priority)
      this.priority = Number(raw.priority);

    this.dnsmasq_only = false;
    if (raw.dnsmasq_only)
      this.dnsmasq_only = JSON.parse(raw.dnsmasq_only);

    if (!raw.direction)
      this.direction = "bidirection";
    
    if (!raw.action)
      this.action = "block";

    if (raw.expire === "") {
      delete this.expire;
    } else if (raw.expire && _.isString(raw.expire)) {
      try {
        this.expire = parseInt(raw.expire)
      } catch (e) {
        log.error("Failed to parse policy expire time:", raw.expire, e);
        delete this.expire;
      }
    }

    if (raw.cronTime === "") {
      delete this.cronTime;
    }

    // backward compatibilities
    if (this['i.type']) {
      this.type = this['i.type'];
      delete this['i.type'];
    }
{'fraction_non_alphanumeric': 0.13491189427312775, 'fraction_numerical': 0.003303964757709251, 'mean_word_length': 2.4611719866603146, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2680730', 'n_tokens_mistral': 2323, 'n_tokens_neox': 2279, 'n_words': 712}