Firebase 文档中对象的安全规则

Firebase 文档中对象的安全规则,firebase,google-cloud-firestore,firebase-authentication,firebase-security,Firebase,Google Cloud Firestore,Firebase Authentication,Firebase Security,我有以下收藏 /公司 /使用者 在用户文档中,我有一个引用其公司成员身份的CompanyUID和一个名为permissions的对象,该对象有两个属性: { admin : true|false superAdmin: true | false } 我的应用程序逻辑如下: 超级管理员可以做任何事情,包括向其他用户授予超级管理员或管理员权限 管理员只能向具有相同公司UID的其他用户授予管理员访问权限 非管理员不能授予任何管理员权限 管理员不应删除自己的管理员权限 我关心的是,鉴于我

我有以下收藏

/公司

/使用者

在用户文档中,我有一个引用其公司成员身份的CompanyUID和一个名为permissions的对象,该对象有两个属性:

{ 
  admin : true|false
  superAdmin: true | false
}
我的应用程序逻辑如下:

  • 超级管理员可以做任何事情,包括向其他用户授予超级管理员或管理员权限
  • 管理员只能向具有相同公司UID的其他用户授予管理员访问权限
  • 非管理员不能授予任何管理员权限
  • 管理员不应删除自己的管理员权限
我关心的是,鉴于我将权限存储在用户文档中,如何有效防止非管理员写入其权限对象,同时允许他们编辑用户文档中的字段

我这里有一些代码,看起来太复杂了,我想,必须有一个更简单的方法。如果您能为我指出正确的方向,我将不胜感激:

  match /users/{userUuid} { 

      allow read: if request.auth != null && belongsToSameCompany()

      function areAdminPermissionsIntact(){
        return request.resource.permissions.admin == resource.permissions.admin
      }

      function areSuperAdminPermissionsIntact(){
        return request.resource.permissions.superAdmin == resource.permissions.superAdmin
      }

      function isNotTheSameUser(){
        return resource.data.uuid != request.auth.uid
      }

       function belongsToSameCompany(){
        return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.companyUuid == resource.data.companyUuid    
      }

      allow write: if request.auth != null 
        && 
       (areAdminPermissionsIntact() || areAdminPermissionsIntact() == false && resource.data.permissions.admin == true && isNotTheSameUser() && belongsToSameCompany()) 
        &&    
       (areSuperAdminPermissionsIntact() || areSuperAdminPermissionsIntact() == false && resource.data.permissions.superAdmin == true && isNotTheSameUser() && belongsToSameCompany())
    }

没有比这更简单的了。您必须检查不应该更改的字段是否没有更改,这正是您在这里所做的


您可以使用检查请求和资源之间未更改的字段列表来表达这一点,但老实说,这并不会降低复杂性。

非常感谢@Doug,您总是这样,拯救人们的生命,或者,我考虑了另一种方法,在阅读了Muall的文章之后,我创建了两个单独的集合来跟踪权限admins/userUuid/companyUuid和superAdmins/userUuid,然后在公司文档中添加了一个admins数组,随后添加了一个触发器来保持admins集合的同步。然后,在公司的集合中添加了一个写安全规则,只允许管理员编辑公司的信息,包括权限。