Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sails.js - protect attributes on blueprint routes with policy and model setting

I am keeping this as a reference to https://github.com/balderdashy/sails/issues/352

Working with SailsJS v0.10-rc5: I am trying to keep the magic of blueprint controllers while at the same time protecting some model attributes from being changed by users on the default routes. I.e.: prevent access to the is_admin attribute on regular CRUD routes and implement a promote action or something similar on the UserController which makes the neccessary checks.

In order to do this, I came up with the following policy in combination with a small addition to the model definitions:

// file: api/policies/protectedAttributes.js

/**
 * protectedAttributes
 *
 * @module      :: Policy
 * @description :: Simple policy to protect certain attributes as returned by Model.protectedAttributes()
 * @docs        :: http://sailsjs.org/#!documentation/policies
 *
 */

var actionUtil = require( '../../node_modules/sails/lib/hooks/blueprints/actionUtil' );

module.exports = function ( req, res, next ) {

	var Model = actionUtil.parseModel( req );

	if ( Model.protectedAttributes ) {
		var attributes = Model.protectedAttributes();
		_.each( attributes, function ( attr ) {
			if ( req.params.hasOwnProperty( attr ) ) {
				delete req.params[ attr ];
			}
			if ( req.query.hasOwnProperty( attr ) ) {
				delete req.query[ attr ];
			}
			if ( req.body.hasOwnProperty( attr ) ) {
				delete req.body[ attr ];
			}

		} );
	}
	return next();
};

Inside a model I add the following function as a class method:

protectedAttributes: function () {
	return [ "is_admin", "email_verified" ];
},

So whenever I enable this policy on a route it reads the protected attributes and simply deletes all matching parameters from the request. The solution still feels a bit crude to me, but I get the behavior I want out of it. Any thoughts?

Cheers! Marcus

@clarkorz

This comment has been minimized.

Copy link

clarkorz commented May 27, 2014

I think this only avoid protected attributes being updated, not being retrieved.

@leejt489

This comment has been minimized.

Copy link

leejt489 commented Nov 13, 2014

@clarkorz You can use model instance method toJSON() to prevent attributes being retrieved

@luqezman

This comment has been minimized.

Copy link

luqezman commented Jan 6, 2015

@leejt489

Imagine if u have a model with attr "active", this is a boolean value and u want to remove it when someone make a post ... with this protection, u can :) I dont know why u are talking about "toJSON()" :-/

@hussainb

This comment has been minimized.

Copy link

hussainb commented Mar 21, 2015

Thank you for this gist Marcus.
Is the way to do this in the version 0.11.0 or some default functionality added now?

@albertpeiro

This comment has been minimized.

Copy link

albertpeiro commented Apr 16, 2015

As @hussainb says be great to know support for this on 0.11.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.