确定查询中每个对象的用户权限?

时间:2016-06-07 16:25:03

标签: node.js mongodb permissions acl mean-stack

我们正在设计协作软件数据库结构并使用MEAN堆栈,而我缺乏ACL权限体验提示了这个问题。

高级别,该软件可供协作者和审核员在项目中工作/查看任务。

MongoDB中的“Project”实体/表用于管理ACL组。每个项目都有一个'Collaborator'用户指针数组和一个'Auditor'用户指针数组。 Collaborators阵列中的用户被添加到具有读/写访问权限的项目“Collaborator”ACL组中,Auditors阵列中的用户被添加到项目审计员acl组中,该组具有只读权限。

MongoDB中还有另一个名为“Task”的实体,每个任务都与一个项目相关联。一个项目可以有多个任务。任务是添加了协作ACL组和Auditor ACL组的项目。

所以一切都很好。现在,用户Bob是项目A的合作者和项目B的审核员。如果Bob在数据库中查询任务,他将返回他可以读/写的任务(项目A)和他只能读取的任务(项目) B)。但是前端如何知道他有哪些任务写权限以及他只读过哪些任务?因为前端只需要在用户具有写入权限的任务旁边显示“编辑”按钮。

我在ACL权限中看到,我可以通过调用来检查用户是否对单个对象具有写权限,但这是每个对象的性能,并且对每个对象执行额外调用的性能都是禁止的,即使它是在服务器在发送初始查询响应之前。

我可以使用像“当前用户权限包含写入”这样的过滤器来查询mongo中的任务实体组吗?或者应该如何处理?

1 个答案:

答案 0 :(得分:1)

像这样的projectACL:

projectAcl{
    id:1,
    projectId:1,        

    // those subDocuments can be also a groupId and reference for exteral document
    auditors:[{userNAme:"John", userId:2},{userNAme:"Marry", userId:12}], 
    colaborators:[{userNAme:"Anna", userId:3},{userNAme:"Eric", userId:4}]
}

然后在调用对象时 - 服务器端代码需要应用“有效权限”

task{
    id:23,
    projectId:1,
    /*
    all fields needed here
    */
    // and here we have fields aded in serwerSide code
    readOnly:null //
}

readOnly - 如果我们在acl列表中有一个条目,将作为快速检查进行调用

以下聚合列出具有ACL列表的给定用户的所有项目 - 这对于设置任务/项目权限或使用CQRS模式添加额外的层安全性非常有用

var givenUserId = 4;
var matchArraysByUser = {
    $match : {
        $or : [{
                "auditors.userId" : givenUserId
            }, {
                "colaborators.userId" : givenUserId
            }
        ]
    }
}

var filterArrysByUser = {
    $project : {
        _id : 0,
        projectId : 1, //all needed fields set to 1
        colaborator : {
            $filter : {
                input : "$colaborators",
                as : "colaborator",
                cond : {
                    $eq : ["$$colaborator.userId", givenUserId]
                }
            }
        },

        auditor : {
            $filter : {
                input : "$auditors",
                as : "auditor",
                cond : {
                    $eq : ["$$auditor.userId", givenUserId]
                }
            }
        },
    }
}

var group = {
    $group : {
        _id : givenUserId,
        "auditor" : {
            $addToSet : {
                $cond : {
                    if  : {
                        $ne : ["$auditor", []]
                    },
                then : "$projectId",
                else  : null
            }
        }
    },
    "colaborator" : {
        $addToSet : {
            $cond : {
                if  : {
                    $ne : ["$colaborator", []]
                },
            then : "$projectId",
            else  : null
        }
    }
}}}

db.projAcl.aggregate([matchArraysByUser, filterArrysByUser, group])
  

输出:

{
    "_id" : 4.0,
    "auditor" : [ 
        null, 
        2.0
    ],
    "colaborator" : [ 
        1.0, 
        null
    ]
}