【问题标题】:Determine users permissions per object in query?确定查询中每个对象的用户权限?
【发布时间】:2016-10-07 15:56:36
【问题描述】:

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

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

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

在 MongoDB 中有另一个名为“任务”的实体,每个任务都与一个且只有一个项目相关联。一个项目可以有多个任务。任务获取添加到其中的项目 Collaborate ACL 组和 Auditor ACL 组。

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

我在 ACL 权限中看到,我可以调用以检查用户是否对单个对象具有写入权限,但这是针对每个对象的,即使在服务器在发送初始查询响应之前。

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

【问题讨论】:

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


    【解决方案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
        ]
    }
    

    【讨论】:

    • @Augie null 可以被过滤掉以避免在最后一个$project 阶段产生噪音
    • @Augie 乐于助人 :-)
    猜你喜欢
    • 2020-01-30
    • 1970-01-01
    • 2012-11-27
    • 2013-02-26
    • 1970-01-01
    • 2016-01-18
    • 2020-04-16
    • 2021-02-22
    • 1970-01-01
    相关资源
    最近更新 更多