Skip to content

Instantly share code, notes, and snippets.

@mphasize
Created May 20, 2014 07:38
Show Gist options
  • Save mphasize/2bd0f40e220e03c5e2ab to your computer and use it in GitHub Desktop.
Save mphasize/2bd0f40e220e03c5e2ab to your computer and use it in GitHub Desktop.
Sails.js - protect attributes on blueprint routes with policy and model setting

I am keeping this as a reference to balderdashy/sails#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

@clark0x
Copy link

clark0x commented May 27, 2014

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

@leejt489
Copy link

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

@lucasmonstrox
Copy link

@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
Copy link

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
Copy link

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