<commit_before>// The audit_couchdb API
//

var lib = require('./lib')
  , util = require('util')
  , events = require('events')
  , probe_couchdb = require('./probe_couchdb')
  ;

function CouchAudit(url) {
  var self = this;
  probe_couchdb.Couch.call(self);

  self.on('couchdb', function(welcome) {
    self.low("People know you are using CouchDB v" + welcome.version);
  })

  var ddocs_in_db = {};
  self.on('database_ok', function(url, info, security) {
    self.log.debug("Tracking ddocs in database: " + url);
    ddocs_in_db[url] = [];

    if("readers" in security) {
      // TODO
    } else {
      this.high("No security.readers: " + url);
    }
  })

  self.on('database_unauthorized', function(url) {
    ddocs_in_db[url] = null;
    this.low("Database is unauthorized: " + url);
  })

  self.on('database_done', function(url) {
    var ddocs = ddocs_in_db[url];
    if(ddocs === null) // DB was unauthorized.
      return;

    var validator_count = ddocs.reduce(function(sum, ddoc) { return sum + (ddoc.validate_doc_update ? 1 : 0) }, 0);
    if(validator_count < 1)
      self.medium('No validation functions (' + (ddocs.length === 0 ? 'no design documents' : 'from '+ddocs.length+' design documents') + '): ' + url);
    else if(validator_count < ddocs.length)
      self.low("Only " + validator_count + " validators out of " + ddocs.length + " design documents: " + url);
  })

  self.on('ddoc', function(db_url, ddoc, info) {
    var ddoc_url = lib.join(db_url, ddoc._id);
    ddocs_in_db[db_url].push(ddoc);

    if(typeof ddoc.language === 'undefined') {
      self.low('No language defined (assuming "javascript"): ' + ddoc_url);
      ddoc.language = 'javascript';
    }

    if(ddoc.language !== info.view_index.language)
      throw new Error("Different languages in ddoc vs. index info: " + JSON.stringify(info) + " vs. language = " + JSON.stringify(ddoc.language));

    if(ddoc.language !== 'javascript')
      this.medium("Non-standard language '" + ddoc.language + '": ' + ddoc_url);

    // Detect unsafe rewrites.
    (ddoc.rewrites || []).forEach(function(rule) {
      var parts = rule.to.split(/\//);

      var depth = 0
        , minimum_depth = 0;
      parts.forEach(function(part) {
        depth += (part === '..' ? -1 : 1);
        if(depth < minimum_depth)
          minimum_depth = depth;
      })

      if(minimum_depth === -2)
        self.low("Database-level rewrite " + JSON.stringify(rule) + ": " + ddoc_url);
      else if(minimum_depth === -3)
        self.medium("Root-level rewrite " + JSON.stringify(rule) + ": " + ddoc_url);
      else if(minimum_depth < -3)
        self.high("Unknown rewrite " + JSON.stringify(rule) + ": " + ddoc_url);
    })
  })

  self.on('end', function() {
    console.log("DONE!");
  })
}
util.inherits(CouchAudit, probe_couchdb.Couch);

; ['low', 'medium', 'high'].forEach(function(level) {
  CouchAudit.prototype[level] = function(message) {<commit_msg>Balance quotes<commit_after>// The audit_couchdb API
//

var lib = require('./lib')
  , util = require('util')
  , events = require('events')
  , probe_couchdb = require('./probe_couchdb')
  ;

function CouchAudit(url) {
  var self = this;
  probe_couchdb.Couch.call(self);

  self.on('couchdb', function(welcome) {
    self.low("People know you are using CouchDB v" + welcome.version);
  })

  var ddocs_in_db = {};
  self.on('database_ok', function(url, info, security) {
    self.log.debug("Tracking ddocs in database: " + url);
    ddocs_in_db[url] = [];

    if("readers" in security) {
      // TODO
    } else {
      this.high("No security.readers: " + url);
    }
  })

  self.on('database_unauthorized', function(url) {
    ddocs_in_db[url] = null;
    this.low("Database is unauthorized: " + url);
  })

  self.on('database_done', function(url) {
    var ddocs = ddocs_in_db[url];
    if(ddocs === null) // DB was unauthorized.
      return;

    var validator_count = ddocs.reduce(function(sum, ddoc) { return sum + (ddoc.validate_doc_update ? 1 : 0) }, 0);
    if(validator_count < 1)
      self.medium('No validation functions (' + (ddocs.length === 0 ? 'no design documents' : 'from '+ddocs.length+' design documents') + '): ' + url);
    else if(validator_count < ddocs.length)
      self.low("Only " + validator_count + " validators out of " + ddocs.length + " design documents: " + url);
  })

  self.on('ddoc', function(db_url, ddoc, info) {
    var ddoc_url = lib.join(db_url, ddoc._id);
    ddocs_in_db[db_url].push(ddoc);

    if(typeof ddoc.language === 'undefined') {
      self.low('No language defined (assuming "javascript"): ' + ddoc_url);
      ddoc.language = 'javascript';
    }

    if(ddoc.language !== info.view_index.language)
      throw new Error("Different languages in ddoc vs. index info: " + JSON.stringify(info) + " vs. language = " + JSON.stringify(ddoc.language));

    if(ddoc.language !== 'javascript')
      this.medium('Non-standard language "' + ddoc.language + '": ' + ddoc_url);

    // Detect unsafe rewrites.
    (ddoc.rewrites || []).forEach(function(rule) {
      var parts = rule.to.split(/\//);

      var depth = 0
        , minimum_depth = 0;
      parts.forEach(function(part) {
        depth += (part === '..' ? -1 : 1);
        if(depth < minimum_depth)
          minimum_depth = depth;
      })

      if(minimum_depth === -2)
        self.low("Database-level rewrite " + JSON.stringify(rule) + ": " + ddoc_url);
      else if(minimum_depth === -3)
        self.medium("Root-level rewrite " + JSON.stringify(rule) + ": " + ddoc_url);
      else if(minimum_depth < -3)
        self.high("Unknown rewrite " + JSON.stringify(rule) + ": " + ddoc_url);
    })
  })

  self.on('end', function() {
    console.log("DONE!");
  })
}
util.inherits(CouchAudit, probe_couchdb.Couch);

; ['low', 'medium', 'high'].forEach(function(level) {
  CouchAudit.prototype[level] = function(message) {
{'fraction_non_alphanumeric': 0.17105934364903927, 'fraction_numerical': 0.004080938615881653, 'mean_word_length': 3.0790568654646324, 'pattern_counts': {'":': 8, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '2921075', 'n_tokens_mistral': 2058, 'n_tokens_neox': 1992, 'n_words': 397}