Last active
December 21, 2020 16:58
-
-
Save mphasize/d62ad412e85bda06377c to your computer and use it in GitHub Desktop.
A naive implementation of custom hooks to enable access control (extending the Sails blueprints).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/balderdashy/sails/blob/master/lib/hooks/blueprints/actionUtil.js | |
/** | |
* AccessControl proxy function, expects a Waterline query object for before* hooks and an array of records for after* hooks. | |
* @param {Collection} model Waterline collectio, from parseModel | |
* @param {String} action blueprint or hook, e.g. beforeFind, afterFind, beforeCreate, afterCreate --> translates to accessControlBeforeFind, etc. | |
* @param {Object} options Options: query {Query} Waterline query object for before* hooks, records: {Array} records for after* hooks, {Model} current user record | |
* @return {Query|Array} returns the modified query (with altered criteria) for before* or the filtered/extended record array for after*. | |
*/ | |
accessControl: function ( model, action, options, callback ) { | |
var primaryArgument = null; | |
var capitaliseFirstLetter = function ( string ) { | |
return string.charAt( 0 ).toUpperCase() + string.slice( 1 ); | |
}; | |
if ( action.indexOf( "before" ) === 0 ) { | |
if ( !options.query ) throw new Error( "accessControl before* hook needs option: query!" ); | |
primaryArgument = options.query; | |
} else if ( action.indexOf( "after" ) === 0 ) { | |
if ( !options.records ) throw new Error( "accessControl after* hook needs option: records!" ); | |
primaryArgument = options.records; | |
} else { | |
throw new Error( "accessControl action '" + action + "' doesn't fit into before/after pattern." ); | |
} | |
action = capitaliseFirstLetter( action ); | |
if ( typeof model[ "control" + action ] === "function" ) { | |
primaryArgument = model[ "control" + action ]( primaryArgument, options, callback ); | |
} else { | |
console.log( "Dev: Model " + model.identity + " is missing control " + action + "!" ); | |
if ( callback ) { | |
callback( null, primaryArgument ); | |
} | |
} | |
return primaryArgument; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/balderdashy/sails/blob/master/lib/hooks/blueprints/actions/find.js | |
// Before the query is executed | |
query = actionUtil.accessControl( Model, "beforeFind", { | |
query: query, | |
user: req.user | |
} ); | |
// After the query is executed, with the results in "matchingRecords" | |
actionUtil.accessControl( Model, "afterFind", { | |
query: query, | |
user: req.user, | |
records: matchingRecords | |
}, function ( err, controlledRecords ) { | |
if ( err ) return res.serverError( err ); | |
// wrapping: | |
// pubsub / subscribe | |
// res ... return the data | |
} ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// in any of the model files | |
controlBeforeFind: function ( query, options ) { | |
// modify the query criteria according to your needs | |
return query; | |
}, | |
controlAfterFind: function ( records, options, callback ) { | |
// modify the records result set according to your needs | |
callback( err, records ); | |
}, | |
// controlBefore* ... | |
// controlAfter* ... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
how do I install/implement this?