2015-02-23 51 views
3

我使用Alanning Roles爲我的應用程序的用戶維護一組組/角色。當用戶創建一個「應用程序」時,我爲它們生成一個新角色app_name + UUID,然後將其作爲一個角色爲Admin的組添加到創建它的用戶。然後,我可以使用生成的組名稱加上AdminViewer角色的組合來確定用戶有權查看和/或編輯哪個Applications發佈用戶在組中的項目(Alanning角色和發佈)

我遇到的問題是我找不到一個好方法讓出版物只發布用戶應該看到的東西。我知道,至少在默認情況下,出版物並不像客戶那樣是「被動的」,而且他們只對被返回的遊標產生反應。但是,在我的代碼我首先要創建組/角色,把它添加到用戶,然後保存「應用程序」,而且我認爲他會重新運行我的出版物,但它沒有:

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

在篩選了一堆文檔和一些非常有用的帖子後,這是我提出的替代方案。奇蹟般有效!

我的目標是向組管理員發佈「訪客」用戶的信息,以批准/拒絕增強的權限。

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?