17

在 config/policies.js 中配置 Sails 中的策略时,例如:

    ActivityController: {
        create: ['authenticated'],
        update: ['authenticated', 'isActivityOwner'],
        destroy: ['authenticated' ,'isActivityOwner']
    }

是否有任何功能可以让我授予对操作的访问权限,前提是一组策略中的一个或多个成功可能类似于:

    ActivityController: {
        create: ['authenticated'],
        update: ['authenticated', {or:['isActivityOwner', 'isAdmin']}],
        destroy: ['authenticated' ,'isActivityOwner']
    }

或者,是否可以创建复合策略,以便在一个策略中检查一个或多个其他策略?

如果这两个选项看起来都是糟糕的解决方案,您能否提出一种被认为是更好的做法的方法?

如果这有点明显,请原谅我,但总的来说我对帆和节点还很陌生,提前感谢您的帮助!

4

5 回答 5

11

我没有在风帆政策中找到对运营商的任何官方支持,但这就是我正在做的事情。

ActivityController: {
    update: ['authenticated', 'orActivityOwner', 'orAdmin', orPolicy],
}

两者都orActivityOwner返回orAdminnext()就好像它们是有效的一样。但他们也为会话变量设置了一个布尔值。请记住,策略是从左到右执行的。我orPolicy在末尾添加了一个,然后它将评估我们会话变量的状态。

于 2013-11-22T01:00:17.157 回答
7

退房风帆必须

ActivityController: {
    create: 'authenticated',
    update: ['authenticated', must().be.the.owner.or.be.a.member.of('admins')],
    destroy: ['authenticated', must().be.the.owner]
}
于 2015-08-31T15:27:15.383 回答
5

我创建了一个能够向策略添加参数的帆钩:
https ://github.com/mastilver/sails-hook-parametized-policies

我设置了一个定义or策略的示例:

module.exports = function(firstPolicy, secondPolicy){

    return function(req, res, next){


        var fakeRes = {};

        for(var i in res){
            if(i === 'forbidden'){
                // override the functions you want the `or` factory to handle
                fakeRes[i] = function(){
                    secondPolicy(req, res, next);
                };
            }
            else{
                fakeRes[i] = res[i];
            }
        }


        firstPolicy(req, fakeRes, next);
    }
}

你可以这样使用:

ActivityController: {
        create: ['authenticated'],
        update: ['authenticated', 'or(isActivityOwner, isAdmin)'],
        destroy: ['authenticated' ,'isActivityOwner']
    }
于 2015-06-21T19:07:06.810 回答
1

只是为了完成前面的答案,这就像一个魅力:


一点信息

但他们也为会话变量设置了一个布尔值

我自己更喜欢将此布尔值设置为req对象,即:

  • 更具语义性(授予或不授予请求资源的访问权限,而不是整个会话
  • 不需要我手动重置此变量(我应该补充一点,如果您确实想使用 @Travis 解决方案中的会话,则orPolicy必须重置(甚至取消设置)最后一个策略variable以保护下一个请求)

我的实现

配置/policies.js

MyController: {
  find: ['orIsTest1', 'orIsTest2', 'protectedResourceGranted']
}

api/policies/orIsTest1.js

module.exports = function(req, res, next) {
  req.protectedResourceGranted = req.protectedResourceGranted || WHATEVERFIRSTTEST;

  return next();
};

api/policies/orIsTest2.js

module.exports = function(req, res, next) {
  req.protectedResourceGranted = req.protectedResourceGranted || WHATEVERSECONDTEST;

  return next();
};

api/policies/protectedResourceGranted.js

module.exports = function(req, res, next) {
  if(req.protectedResourceGranted) {
    return next();
  }

  return res.forbidden();
};

注意:只是回答,因为我没有足够的声誉来发表评论。

于 2015-03-18T09:43:08.687 回答
0

此处的其他答案效果很好,但这是一个我觉得更干净的实现。

您可以修改现有策略以在AND / OR上下文中使用,而不是创建为OR情况设计的策略,next()即使它们应该失败,也几乎不会改变它们的行为。然后创建一个检查修改后的现有策略的复合策略(如 OP 建议的)。

带有示例控制器和策略的config/ policies.js:

AdminController: {
  adminDashboard: 'isAuthenticated',
},

ItemController: {
  findOne: 'isPublishedOrIsAuthenticated'
}

api/policies/isAuthenticated.jsapi/policies/isPublished.js以及您想用作AND / OR检查的一部分的任何其他策略:

如果next设置为true布尔值(与回调相反),则返回truefalse在策略通常返回之前返回next(),res.notFound()等。

module.exports = function(req, res, next) {
  // do some checking
  if(next === true) return true; // or return false
  return next();
};

请注意,我们需要在这里使用三等号。

api/policies/isPublishedOrIsAuthenticated.js

module.exports = function(req, res, next) {
  var isPublished = require('./isPublished.js');
  var isAuthenticated = require('./isAuthenticated.js');

  // This reads like what we are trying to achieve!
  // The third argument in each call tells the function to return a boolean
  if(isPublished(req, res, true) || isAuthenticated(req, res, true))
    return next();

  return res.notFound();
};
于 2015-03-30T18:10:49.783 回答