2016-06-07 52 views
1

我們正在設計一個協作軟件數據庫結構並使用MEAN堆棧,而我缺乏ACL權限的經驗引發了這個問題。確定用戶查詢中每個對象的權限?

高層次,該軟件用於協作者和審計人員在項目中工作/查看任務。

MongoDB中的'Project'實體/表用於管理ACL組。每個項目都有一個'Collaborator'用戶指針數組和一個'Auditor'數組用戶指針。 Collaborators數組中的用戶被添加到具有讀/寫訪問權限的項目'Collaborator'ACL組中,Auditors數組中的用戶被添加到只讀的項目auditor acl組中。

在MongoDB中還有另一個名爲'Task'的實體,每個任務都綁定到一個項目,並且只有一個項目。一個項目可以有多個任務。任務獲取項目添加到其中的協作ACL組和審計員ACL組。

這樣一切都很好。現在,用戶Bob是項目A上的協作者,項目B上是審計人員。如果Bob在數據庫中查詢任務,他將取回他可以讀/寫的任務(項目A)以及他只能讀取的任務(項目B)。但是,前端如何知道他有哪些任務可以寫入權限以及哪些只讀?因爲前端僅需要在用戶具有寫入權限的任務旁邊顯示「編輯」按鈕。

我在ACL權限中看到,我可以執行一個調用來檢查用戶是否對單個對象具有寫權限,但這是每個對象,並且對於每個對象執行額外調用的性能會受到阻止,即使它已完成在發送初始查詢響應之前在服務器上。

我可以使用類似'AND當前用戶權限包含寫入'的過濾器查詢mongo中的任務實體組嗎?或者應該如何處理?

回答

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 - 如果將callculated快速檢查,如果我們在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 
    ] 
} 
+0

感謝您的答覆,現在消化... – Augie

+0

@Augie'null'可以被過濾掉,以避免噪音最後一個'$ project'階段 – profesor79

+0

構建了這個測試,效果很棒!謝謝。 – Augie