Skip to content

Instantly share code, notes, and snippets.

@tarlepp
Created August 23, 2014 11:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tarlepp/c4b28b3c60282b0f8973 to your computer and use it in GitHub Desktop.
Save tarlepp/c4b28b3c60282b0f8973 to your computer and use it in GitHub Desktop.
'use strict';
/**
* Generic object specified (row) policy. Policy is attached to all controllers which are accessible
* via blueprints API and this policy will call object specified service method to mutate current
* where object that way that it contains necessary right specified limit conditions.
*
* Implementation is pretty straightforward:
* 1) Create new API
* 2) Add API specified right checker to 'ObjectRight' service
* 3) Implement that logic
* 4) and there is all, happy coding
*
* Note that service method structure is always following
*
* exports.checkObjectRight[ObjectName] = function(request, response, next) {
* // Parse where criteria
* var where = actionUtil.parseCriteria(request);
*
* here do your stuff for where object, basically add your business logic
* checks here... Yes and those can be complicated - I know . good luck :D
*
* // Remove existing query
* delete request.query;
*
* // Set new query to request, that blueprints will use after this
* request.query = {
* where: where
* };
*
* return next();
* };
*
* @param {Request} request Request object
* @param {Response} response Response object
* @param {Function} next Callback function
*
* @returns {*}
*/
module.exports = function(request, response, next) {
sails.log.verbose(' POLICY - ' + __filename);
// Determine model and method name
var model = request.options.model || request.options.controller;
var method = 'makeObjectRight' + model.charAt(0).toUpperCase() + model.slice(1);
// Yeah we found actual policy service
if (typeof sails.services['objectright'][method] === 'function') {
return sails.services['objectright'][method](request, response, next);
} else { // Oh noes, is this ok or not?
var message = 'There is not object specified right handling for \'' + model + '\' model. '
+ 'Please \'' + method + '\' method this to \'ObjectRight\' service.'
;
sails.log.warn(message);
return next();
}
};
module.exports.policies = {
// Default policy for all controllers and actions
'*': ['passport', 'authenticated'],
ProjectController: {
'*': false,
'find': ['passport', 'authenticated', 'isSocket', 'objectRight'],
'findOne': ['passport', 'authenticated', 'isSocket', 'objectRight'],
'create': ['passport', 'authenticated', 'isSocket', 'addDataCreate'],
'update': ['passport', 'authenticated', 'isSocket', 'addDataUpdate']
},
SprintController: {
'*': false,
'find': ['passport', 'authenticated', 'isSocket', 'objectRight'],
'findOne': ['passport', 'authenticated', 'isSocket', 'objectRight'],
'create': ['passport', 'authenticated', 'isSocket', 'addDataCreate'],
'update': ['passport', 'authenticated', 'isSocket', 'addDataUpdate']
}
};
'use strict';
var _ = require('lodash');
var actionUtil = require('sails/lib/hooks/blueprints/actionUtil');
/**
* Service function which adds necessary object specified conditions to Project
* model queries. Workflow with this is following:
*
* 1) Fetch project ids where current user is attached to
* 2) Mutilate current where condition:
* - if 'id' property exists in query remove not valid projects
* - if not add 'id' property to query with valid projects
*
* @param {Request} request Request object
* @param {Response} response Response object
* @param {Function} next Callback function
*/
exports.makeObjectRightProject = function(request, response, next) {
sails.log.verbose(' POLICY - ' + __filename);
// Determine valid project ids for current user
sails.services['data']
.getCollectionProperty('projectuser', 'project', {user: request.token}, function(error, validIds) {
return sails.services['rights']
.makeObjectCondition(error, validIds, 'id', request, response, next);
});
};
/**
* Service function which adds necessary object specified conditions to Sprint
* model queries. Workflow with this is following:
*
* 1) Fetch project ids where current user is attached to
* 2) Mutilate current where condition:
* - if 'project' property exists in query remove not valid projects
* - if not add 'project' property to query with valid projects
*
* @param {Request} request Request object
* @param {Response} response Response object
* @param {Function} next Callback function
*/
exports.makeObjectRightSprint = function(request, response, next) {
sails.log.verbose(' POLICY - ' + __filename);
// Determine valid project ids for current user
sails.services['data']
.getCollectionProperty('projectuser', 'project', {user: request.token}, function(error, validIds) {
return sails.services['rights']
.makeObjectCondition(error, validIds, 'project', request, response, next);
});
};
/**
* Generic function which will make necessary object (Project, Sprint, etc.) specified conditions
* to blueprints query.
*
* @param {null|Error} error Possible error object
* @param {null|[]} validIds Valid id values that are attached to query
* @param {String} property Model property name where to attach id values
* @param {Request} request Request object
* @param {Response} response Response object
* @param {Function} next Callback function
*
* @returns {*}
*/
exports.makeObjectCondition = function(error, validIds, property, request, response, next) {
if (error) {
return response.negotiate(error);
}
// Make where condition against specified model property with determined id values
var where = sails.services['rights']
.makeConditionValidProperty(validIds, property, request);
// There is no "valid" ids so we need to send 404 back to client
if (_.isEmpty(where[property])) {
error = {
status: 404
};
return response.negotiate(error);
}
// Remove existing query
delete request.query;
// Set new query to request, that blueprints will use after this
request.query = {
where: where
};
return next();
};
/**
* Helper function which will mutilate current where condition. Function will add specified
* property condition with given values to current where object.
*
* @param {[]} validIds Valid id values that are attached to current where condition
* @param {String} property Name of the where condition where to attach id values
* @param {Request} request Request object
*
* @returns {{}} Where object
*/
exports.makeConditionValidProperty = function(validIds, property, request) {
// Parse where criteria
var where = actionUtil.parseCriteria(request);
// Normalize valid id array
validIds = _.map(validIds, function(id) {
return parseInt(id, 10);
});
// Specified property is not yet in where query
if (!where[property]) {
where[property] = validIds;
} else { // We have id condition set so we need to check if that / those are allowed
// Normalize current ids
var currentIds = _.map((!_.isArray(where[property])) ? [where[property]] : where[property], function (id) {
return parseInt(id, 10);
});
// Remove not valid ids
where[property] = _.intersection(currentIds, validIds);
}
return where;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment