How do I write a Firestore security rule so that only someone who is listed as an admin can perform certain actions and everyone else can only read?

huangapple go评论56阅读模式
英文:

How do I write a Firestore security rule so that only someone who is listed as an admin can perform certain actions and everyone else can only read?

问题

以下是翻译好的部分:

结构如下:

/groups/{groupID}

在这个{groupID}记录中,它将具有以下字段(最后一个是子集合)。此集合中列出的adminUID应该具有额外的权限。

groupID
groupName
adminUID
adminUsername
createDate
creatorUID
creatorUsername
initialGroupCreate
groupMembersSubcollection

对于静态字段,管理员应该能够:

  • 使用这些静态字段创建{groupID}记录,但不能修改/删除

组的成员只能读取,但不能写入/删除。

对于子集合,管理员应该能够:

  • 在groupMembersSubcollection中创建/删除任意数量的记录;不能修改

组的成员只能读取这个子集合中的记录。

英文:

The structure is:

/groups/{groupID}

Inside this {groupID} record, it will have the following fields (the last one is a subcollection). The adminUID listed in this collection is the one who should have the extra permissions.

groupID
groupName
adminUID
adminUsername
createDate
creatorUID
creatorUsername
initialGroupCreate
groupMembersSubcollection

For the static fields, the admin should be able to:

  • create the {groupID} record with these static fields, cannot modify/delete

The members of the group can only read but not write/delete.

For the subcollection, the admin should be able to:

  • create/delete any number of records in the groupMembersSubcollection; cannot modify

The members of the group can only read records in this sub-collection.

答案1

得分: 1

以下是您要翻译的内容:

假设您的Firestore集合结构如下,而且您的groupMembersSubcollection中的文档以group Members user.uid为文档ID:

Firestore数据库
└── groups -(集合)
    └── {groupID}-文档ID
        ├── groupID
        ├── groupName
        ├── adminUID
        ├── adminUsername
        ├── createDate
        ├── creatorUID
        ├── creatorUsername
        ├── initialGroupCreate
        └── groupMembersSubcollection -(子集合)

然后您所需的安全规则如下:

rules_version = '2';
service cloud.firestore {
    match /databases/{database}/documents {
        // function to check member or not
        function isMemerOrNot(groupId) {
            return exists(/databases/$(database)/documents/groups/$(groupId)/groupMembersSubcollection/$(request.auth.uid)); // Not verified
        }

        // Rule 1: Static fields in the groups collection
        match /groups/{groupId} {
            allow read : if request.auth != null && isMemerOrNot(groupId);
            allow create: if request.resource.data.keys().hasAll([ //making sure all fields are there while creating this document
                'groupID', 
                'groupName', 
                'adminUID', 
                'adminUsername', 
                'createDate', 
                'creatorUID', 
                'creatorUsername', 
                'initialGroupCreate']) &&
            request.resource.data.adminUID == request.auth.uid; // allowed only for admins
            allow update, delete: if false; // No updates or deletes allowed
        }

        // Rule 2: groupMembersSubcollection
        match /groups/{groupId}/groupMembersSubcollection/{userId} { 
            allow read: if request.auth != null && request.auth.uid == userId // Members can read the subcollection
            allow create, delete: if 
            request.auth.uid == get(/databases/$(database)/documents/groups/$(groupId)).data.adminUID;
            allow update: if false; // No updates allowed for subcollection documents
        }
    }
}

解释:

  1. 对于规则1:

    • read规则仅允许已认证用户,也是成员的用户(对于isMemberOrNot函数,您需要检查是否存在具有该uid的成员,您可以使用exists(/databases/$(database)/documents/groups/$(groupId)/groupMembersSubcollection/$(request.auth.uid));这个技巧来自访问其他文档,但您需要确保子集合已经存在具有成员文档ID的文档)
    • create规则仅允许管理员使用指定的静态字段创建文档。
    • updatedelete规则设置为false,以便任何人都不能修改/删除。
  2. 对于规则2:

    • read规则允许已认证用户和组成员读取groupMembersSubcollection中的文档,借助其user.uid
    • createdelete规则允许管理员(使用父文档中的adminUID来识别)在groupMembersSubcollection中创建或删除文档。
    • update规则设置为false,以禁止对groupMembersSubcollection中的文档进行任何更新。

参考:

英文:

Assuming your Firestore collection structure is as follows and your documents inside groupMembersSubcollection saved with document id as group Members user.uid :

Firestore Database
└── groups - (Collection)
└── {groupID}- Document Id
├── groupID
├── groupName
├── adminUID
├── adminUsername
├── createDate
├── creatorUID
├── creatorUsername
├── initialGroupCreate
└── groupMembersSubcollection - (sub-collection)

Then your desired security rules will be as follows :

rules_version = '2';
service cloud.firestore {
    match /databases/{database}/documents {
        // function to check member or not
        function isMemerOrNot(groupId) {
            return exists(/databases/$(database)/documents/groups/$(groupId)/groupMembersSubcollection/$(request.auth.uid)); // Not verified
        }

        // Rule 1: Static fields in the groups collection
        match /groups/{groupId} {
            allow read : if request.auth != null && isMemerOrNot(groupId);
            allow create: if request.resource.data.keys().hasAll([ //making sure all fields are there while creating this document
                'groupID', 
                'groupName', 
                'adminUID', 
                'adminUsername', 
                'createDate', 
                'creatorUID', 
                'creatorUsername', 
                'initialGroupCreate']) &&
            request.resource.data.adminUID == request.auth.uid; // allowed only for admins
            allow update, delete: if false; // No updates or deletes allowed
        }

        // Rule 2: groupMembersSubcollection
        match /groups/{groupId}/groupMembersSubcollection/{userId} { 
            allow read: if request.auth != null && request.auth.uid == userId // Members can read the subcollection
            allow create, delete: if 
            request.auth.uid == get(/databases/$(database)/documents/groups/$(groupId)).data.adminUID;
            allow update: if false; // No updates allowed for subcollection documents
        }
    }
}

Explanation :

  1. For Rule 1 :
  • The read rule will only allow authenticated users which are also members(for isMemberOrNot function you need to check whether a member with that uid exist or not you can use exists(/databases/$(database)/documents/groups/$(groupId)/groupMembersSubcollection/$(request.auth.uid))
    ;
    technique from Access other documents but you need to be sure that the subcollection have the member documentId as a document already exist )
  • The create rule allows only the admin to create a document in the groups collection with the specified static fields.
  • The update and delete rules are set to false so that no one cannot modify/delete
  1. For Rule 2 :
  • The read rule allows authenticated users and Group Members to read the documents in the groupMembersSubcollection with the help of their user.uid.
  • The create and delete rules allow the admin (using adminUID from parent document to identify) to create or delete documents in the groupMembersSubcollection
  • The update rule is set to false to disallow any updates to the documents in the groupMembersSubcollection.

Reference :

huangapple
  • 本文由 发表于 2023年6月29日 09:41:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76577587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定