发布用户在组中的项目(Alanning Roles and Publications)

时间:2015-02-23 13:53:39

标签: meteor meteor-publications meteor-collections

我正在使用Alanning Roles为我的应用程序的用户维护一组组/角色。当用户创建"应用程序"时,我为他们生成app_name + UUID的新角色,然后将其作为具有Admin角色的组添加到创建它的用户。然后,我可以使用生成的组名称加上AdminViewer角色的组合来确定用户有权查看和/或编辑的Applications

我遇到的问题是,我无法找到一个好的方法让出版物只发布用户应该看到的内容。我知道,至少默认情况下,出版物不是“反应性的”。在客户端的方式,他们只对他们返回的游标有反应。但是,在我的代码中,我首先创建组/角色,将其添加到用户,然后保存"应用程序",我认为这将重新运行我的出版物,但它没有:

Meteor.publish('myApplications', function(groups) {
  if (this.userId) {
    console.log('Running myApplications publication...');
    console.log('Found roles for user ' + this.userId + ': ', Roles.getGroupsForUser(this.userId));
    return Applications.find({group: {$in: Roles.getGroupsForUser(this.userId)}});
  } else {
    //console.log("Skipping null user");
    return null;
  }
});

但是,与我认为会发生的情况相反(整个发布方法会重新运行),我猜测真正发生的是只有Cursor是更新。因此,对于我的下一次尝试,我添加了mrt:reactive-publications软件包,并简单地为用户提供了一个指向Meteor.users集合的游标,认为这将触发"触发"当用户使用新的组/角色进行更新时重新运行的出版物,但是没有用。

我最终通过简单地为用户传递组来完成这项工作:

Meteor.publish('myApplications', function(groups) {
  if (this.userId) {
    if (!groups || groups.length === 0) {
      groups = Roles.getGroupsForUser(this.userId);
    }
    console.log('Running myApplications publication...');
    console.log('Found roles for user ' + this.userId + ': ', Roles.getGroupsForUser(this.userId));
    return Applications.find({group: {$in: groups}});
  } else {
    //console.log("Skipping null user");
    return null;
  }
});

然后我只是在我的路线Meteor.subscribe('myApplications', Roles.getGroupsForUser(Meteor.userId()))中将出版物称为waitOn,但这意味着任何客户都可以调用相同的出版物并传入他们喜欢的任何群组,并且可能会看到他们不打算看到的文件。这似乎是一个非常大的安全漏洞。

有没有更好的方法来实现这一点,以致客户端无法哄骗他们的方式来看到他们的东西?我认为唯一真正的方法是在出版方面收集小组,但随后它会打破反应。

1 个答案:

答案 0 :(得分:1)

在筛选了一堆文档和一些非常有用的堆栈帖子之后,这是我提出的替代方案。像魅力一样工作!

我的目标是发布'客人'用户'向群组管理员提供用于批准/拒绝增强权限的信息。

Meteor.publish('groupAdmin', function(groupId) {
  // only publish guest users info to group admins
  if(Roles.userIsInRole(this.userId, ['group-admin'], groupId)) {
    // I can't explain it but it works!
    var obj = {key: {$in: ['guest']}};
    var query = {};
    var key = ('roles.' + groupId);
    query[key] = {$in: ['guest']};
    return Meteor.users.find(query, {
        fields: {
          createdAt: 1,
          profile: 1
        }
      });
  } else {
    this.stop();
    return;
  }
});

参考:How to set mongo field from variable &安培; How do I use a variable as a field name in a Mongo query in Meteor?