如果用户在允许访问资源的团队中,则应允许他们访问资源。
如何在安全规则中执行此操作?
我有藏品:
团队,每个中有一个.members字段
资源,每个都有一个teamsThatCanAccess
如果我用js写这篇文章,它会像:
canUserAccess = (userId, resource) => {
teams = resource.teamsThatCanAccess
hasAccess = false
teams.forEach((team) => {
if (userId in team.members) {
hasAccess = true
}
}
return hasAccess
}
然而,据我所知,安全规则不喜欢循环。
--编辑--
为了进一步说明,我正在构建的数据库看起来像这样:
teams = [
{ name: "teamA", org: "org1", members: ["uid1", "uid2", "uid3"] },
{ name: "teamB", org: "org1", members: ["uid1", "uid2"] },
{ name: "teamC", org: "org1", members: ["uid3", "uid4", "uid5"] },
{ name: "teamD", org: "org2", members: ["uid201", "uid202"] },
]
resources = [
{
id: "projectId1",
name: "project 1",
org: "org1",
teamsThatCanAccess: ["teamA", "teamB"],
},
{
id: "projectId2",
name: "project 2",
org: "org1",
teamsThatCanAccess: ["teamA", "teamB", "teamC"],
},
{
id: "projectId3",
name: "project 3",
org: "org1",
teamsThatCanAccess: ["teamC"],
},
{
id: "projectId4",
name: "project 201",
org: "org2",
teamsThatCanAccess: ["teamD"],
},
]
projectFiles = [
{ content: "document text", project: "projectId1" },
{ content: "document text 2", project: "projectId1" },
{ content: "document text 3", project: "projectId2" },
]
根据您的描述,您有一个如下所示的结构:
// document at /teams/someTeamId
{
"members": [
"uid1",
"uid2",
"uid3"
],
/* ... */
}
// document at /resources/someResourceId
{
"teamsThatCanAccess": [
"someTeamId",
"otherTeamId"
],
/* ... */
}
为了保护数据安全,您需要引入一个新的文档集合,称为teamsByUser
:
// document at /teamsByUser/uid1
{
"memberOf": [
"someTeamId",
"otherTeamId"
]
}
通过引入此数组,您现在可以使用rules.List#hasAny
方法来查找/teamsByUser/{userId}
中的memberOf
数组和/resources/{resourceId}
中的teamsThatCanAccess
数组之间是否有重叠。
这将允许您将规则配置为
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /resources/{resourceId} {
allow read: if resource.data.size() == 0 // is empty?
|| get(/databases/$(database)/documents/teamsByUser/$(request.auth.uid)).data.memberOf.hasAny(resource.data.teamsThatCanAccess); // accessing user is a member of an allowed team
}
// don't forget to add rules to prevent users joining arbitrary teams from clients
}
}