<commit_before>var Promise = require('bluebird');
var methodMap = {
  POST: 'create',
  GET: 'read',
  PUT: 'update',
  DELETE: 'delete'
};
var actionMap = {
  create: 'create',
  find: 'read',
  findone: 'read',
  update: 'update',
  destroy: 'delete',
  populate: 'read',
  add: 'update',
  remove: 'update'
};

var findRecords = require('sails/lib/hooks/blueprints/actions/find');
var wlFilter = require('waterline-criteria');

module.exports = {

  /**
   * Given an object, or a list of objects, return true if the list contains
   * objects not owned by the specified user.
   */
  hasForeignObjects: function (objects, user) {
    if (!_.isArray(objects)) {
      return PermissionService.isForeignObject(user.id)(objects);
    }
    return _.any(objects, PermissionService.isForeignObject(user.id));
  },

  /**
   * Return whether the specified object is NOT owned by the specified user.
   */
  isForeignObject: function (owner) {
    return function (object) {
      return object.owner !== owner;
    };
  },

  /**
   * Find objects that some arbitrary action would be performed on, given the
   * same request.
   *
   * @param options.model
   * @param options.query
   *
   * TODO this will be less expensive when waterline supports a caching layer
   */
  findTargetObjects: function (req) {
    return new Promise(function (resolve, reject) {
      findRecords(req, {
        ok: resolve,
        serverError: reject
      });
    });
  },

  /**
   * Query Permissions that grant privileges to a role/user on an action for a
   * model.
   *
   * @param options.action
   * @param options.model
   * @param options.user
   */
  findModelPermissions: function (options) {
    var action = PermissionService.getAction(options);
    var permissionCriteria = {
      model: options.model.id,
      action: action
    };

    return User.findOne(options.user.id)
      .populate('roles')
      .then(function (user) {
        return Permission.find({
          model: options.model.id,
          action: action,
          or: [
            {user: user.id},
            {role: _.pluck(user.roles, 'id')}
          ]
        }).populate('criteria');
      });
  },

  /**
   * Given a list of objects, determine if they all satisfy at least one permission's
   * where clause/attribute blacklist combination
   *
   * @param {Array of objects} objects - The result of the query, or if the action is create,
   * the body of the object to be created
   * @param {Array of Permission objects} permissions - An array of permission objects
   * that are relevant to this particular user query
   * @param {Object} attributes - The body of the request, in an update or create request.
   * The keys of this object are checked against the permissions blacklist
   * @returns boolean - True if there is at least one granted permission that allows the requested action,
   * otherwise false
   */
  hasPassingCriteria: function (objects, permissions, attributes, user) {
    // return success if there are no permissions or objects
    if (_.isEmpty(permissions) || _.isEmpty(objects)) return true;

    if (!_.isArray(objects)) {
        objects = [objects];
    }

    var criteria = permissions.reduce(function (memo, perm) {
        if (perm && perm.criteria) {
            memo = memo.concat(perm.criteria);
        }
        if (perm.relation === 'owner') {
            perm.criteria.forEach(function (criteria) {
                criteria.owner = true;
            });
        }
        return memo;
    }, []);

    if (!_.isArray(criteria)) {
        criteria = [criteria];
    }

    if (_.isEmpty(criteria)) {
        return true;
    }

    // every object must have at least one permission that has a passing criteria and a passing attribute check
    return objects.every(function (obj) {
        return criteria.some(function (criteria) {
            var match = wlFilter([obj], { where: criteria.where }).results;
            var hasUnpermittedAttributes = PermissionService.hasUnpermittedAttributes(attributes, criteria.blacklist);
            var hasOwnership = true; // edge case for scenario where a user has some permissions that are owner based and some that are role based
            if (criteria.owner) {<commit_msg>if a permission has no criteria then it should pass, even if another permission has criteria<commit_after>var Promise = require('bluebird');
var methodMap = {
  POST: 'create',
  GET: 'read',
  PUT: 'update',
  DELETE: 'delete'
};
var actionMap = {
  create: 'create',
  find: 'read',
  findone: 'read',
  update: 'update',
  destroy: 'delete',
  populate: 'read',
  add: 'update',
  remove: 'update'
};

var findRecords = require('sails/lib/hooks/blueprints/actions/find');
var wlFilter = require('waterline-criteria');

module.exports = {

  /**
   * Given an object, or a list of objects, return true if the list contains
   * objects not owned by the specified user.
   */
  hasForeignObjects: function (objects, user) {
    if (!_.isArray(objects)) {
      return PermissionService.isForeignObject(user.id)(objects);
    }
    return _.any(objects, PermissionService.isForeignObject(user.id));
  },

  /**
   * Return whether the specified object is NOT owned by the specified user.
   */
  isForeignObject: function (owner) {
    return function (object) {
      return object.owner !== owner;
    };
  },

  /**
   * Find objects that some arbitrary action would be performed on, given the
   * same request.
   *
   * @param options.model
   * @param options.query
   *
   * TODO this will be less expensive when waterline supports a caching layer
   */
  findTargetObjects: function (req) {
    return new Promise(function (resolve, reject) {
      findRecords(req, {
        ok: resolve,
        serverError: reject
      });
    });
  },

  /**
   * Query Permissions that grant privileges to a role/user on an action for a
   * model.
   *
   * @param options.action
   * @param options.model
   * @param options.user
   */
  findModelPermissions: function (options) {
    var action = PermissionService.getAction(options);
    var permissionCriteria = {
      model: options.model.id,
      action: action
    };

    return User.findOne(options.user.id)
      .populate('roles')
      .then(function (user) {
        return Permission.find({
          model: options.model.id,
          action: action,
          or: [
            {user: user.id},
            {role: _.pluck(user.roles, 'id')}
          ]
        }).populate('criteria');
      });
  },

  /**
   * Given a list of objects, determine if they all satisfy at least one permission's
   * where clause/attribute blacklist combination
   *
   * @param {Array of objects} objects - The result of the query, or if the action is create,
   * the body of the object to be created
   * @param {Array of Permission objects} permissions - An array of permission objects
   * that are relevant to this particular user query
   * @param {Object} attributes - The body of the request, in an update or create request.
   * The keys of this object are checked against the permissions blacklist
   * @returns boolean - True if there is at least one granted permission that allows the requested action,
   * otherwise false
   */
  hasPassingCriteria: function (objects, permissions, attributes, user) {
    // return success if there are no permissions or objects
    if (_.isEmpty(permissions) || _.isEmpty(objects)) return true;

    if (!_.isArray(objects)) {
        objects = [objects];
    }

    var criteria = permissions.reduce(function (memo, perm) {
      if (perm) {
        if (perm.criteria && perm.criteria.where) {
            memo = memo.concat(perm.criteria);
        }
        else {
          // If a permission has no criteria then it passes for all cases
          // (like the admin role)
          memo.concat([{where:{}}]);
        }
        if (perm.relation === 'owner') {
            perm.criteria.forEach(function (criteria) {
                criteria.owner = true;
            });
        }
        return memo;
      }
    }, []);


    if (!_.isArray(criteria)) {
        criteria = [criteria];
    }

    if (_.isEmpty(criteria)) {
        return true;
    }

    // every object must have at least one permission that has a passing criteria and a passing attribute check
    return objects.every(function (obj) {
        return criteria.some(function (criteria) {
            var match = wlFilter([obj], { where: criteria.where }).results;
            var hasUnpermittedAttributes = PermissionService.hasUnpermittedAttributes(attributes, criteria.blacklist);
            var hasOwnership = true; // edge case for scenario where a user has some permissions that are owner based and some that are role based
            if (criteria.owner) {
{'fraction_non_alphanumeric': 0.10751708428246014, 'fraction_numerical': 0.0, 'mean_word_length': 2.604679802955665, 'pattern_counts': {'":': 0, '<': 3, '<?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': '6793970', 'n_tokens_mistral': 2429, 'n_tokens_neox': 2396, 'n_words': 831}