Antuan
Antuan

Reputation: 519

Security rule for an object within a document

I have the following collections

/companies

/users

Within the user document I have a companyUuid to reference its company membership and an object called permissions that has two attributes:

{ 
  admin : true|false
  superAdmin: true | false
}

My app logic is as follows:

My concern is, given that I store the permissions within the user document, how do I effectively prevent non-Admins from writing to their permissions object while also allowing them to edit the fields within the user document?

I have some code here, it looks way too complicated I think, there has to be a simpler way. I would greatly appreciate if you point me in the right direction:

  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())
    }

Upvotes: 0

Views: 32

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317958

It doesn't really get any simpler than this. You have to check that the fields that should not change are not changing, and that's exactly what you're doing here.

You could express this a bit differently using the MapDiff API to check the list of fields that are unchanged between the request and resource, but honestly, it's not going to make this any less complicated.

Upvotes: 1

Related Questions