SailsJs用策略保护蓝图

时间:2016-03-03 20:35:08

标签: javascript node.js express sails.js

我有一个模型:api/models/Agency.js

attributes: {

        // attributes for agency

        // One agency can have many owners
        owners: {

          collection: 'user',
          required: true,
          via: 'agencies'
        },

        employees: {

          collection:   'user',
          via:          'employer'
        }
    }

该模型与用户有多对多的关系;许多用户可以拥有许多代理商。

我想使用名为AgencyController.js政策保护代理商(isOwner.js)的蓝图控制器;在允许用户进行编辑之前,确保用户是代理商的所有者。我的策略基于Sails.js docs中的示例,我试图确保userId(在会话中找到)是资源的所有者。

api/policies/isOwner.js

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

    var userId = req.session.passport.user;

    req.options.where = req.options.where || {};

    req.options.where.owners = userId;

    return next();

};

然后在我的config/policies.js文件中添加了以下内容:

    AgencyController: {

          destroy:  ['isOwner'],
          update:   ['isOwner']
    },

这不起作用。我认为这是因为两个模型之间的多对多关系。我的问题是我可以创建一个可以查询多对多关系的策略吗?或者只能通过一对多关系来实现?

感谢。

1 个答案:

答案 0 :(得分:0)

我无法通过策略找到一种很好地保护蓝图方法的方法,所以我创建了一个服务,检查用户是模型的所有者,然后在我的控制器中扩展更新和销毁方法。

API /服务/ isOwner.js:

/**
 * Only allow access to models if they are the owner.
 * Assumes an attribute called owners on the model and assumes it has a relationship that can be queried through the
 * 'populate' waterline method.
 */
var actionUtil = require( 'sails/lib/hooks/blueprints/actionUtil' );
var _ = require( 'underscore' );

/**
 * @param req
 * @param res
 * @param is {function} called if the user is the owner
 * @param isnt {function} called if the user is not the owner. If not present will redirect 403 not authorised.
 */
module.exports = function isOwner( req, res, is, isnt ){

    var ownerEmail = req.options.where.owner;
    var Model = actionUtil.parseModel( req );

    isnt = isnt || res.forbidden;

    is = is || function(){

            sails.log.warn( 'No callback defined for isOwner' );
            res.ok();
        };


    Model.findOne({ id: req.params.id }).populate( 'owners' ).exec( function( error, model ){

        var canEdit = _.find( model.owners, function( owner ){

            return owner.email === ownerEmail;
        });

        canEdit ? is() : isnt();
    });
};

API /控制器/ AgencyController.js:

var update = require( 'sails/lib/hooks/blueprints/actions/update' );
var isOwner = require( '../services/isOwner' );

module.exports = {

    /**
     * Override the default blueprint update behaviour so only the owner can update a record.
     *
     * @param req
     * @param res
     */
    update: function( req, res ){

        isOwner( req, res, update );
    }
};

感觉不是最好的方式,但这是我能想到的唯一方式。只是觉得我在这里分享它只是因为有人遇到同样的问题或有人有更好的解决方案。