Firestore security rule using reference to another

2019-04-07 16:33发布

I am trying to base a security rule on a reference to another object.

I have a collection of users and collection of roles. A user object has a field called "role" that is a reference to a particular document in the roles collection.

users
  id
  name
  role <-- reference to particular role

roles
  id
  name
  isSuperUser

The goal here is to allow a user with a particular role (the role with isSuperUser == true) to edit any other role or it's sub-collections;

Here are my rules that I would have thought would have worked:

service cloud.firestore {
   match /databases/{database}/documents {
    match /users/{userId=**} {
     allow read, write: if request.auth.uid == userId;
   }
   match /roles/{roleId=**} {
      function isSuperUser() {
       return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role.isSuperuser == true;
      }
      allow read: if request.auth.uid != null;
      allow write: if isSuperUser();
   }
}

I have confirmed the following works, but it's not really that useful...

get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role != null;

If there is a better way to accomplish role base security, I am all ears.

The lack of any debugging tools makes this quite frustrating.

2条回答
Lonely孤独者°
2楼-- · 2019-04-07 16:50

I know it's been a while since the original question but I've had a similar issue and I hope this could help you or others.

Your condition is: get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role.isSuperuser == true;

But role is a reference, which (apparently) means you need to get it as well. Try this:

get(get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role).data.isSuperuser == true;

查看更多
相关推荐>>
3楼-- · 2019-04-07 17:03

Have you tried to move the wildcard to a nested path?

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth.uid == userId;
      match /{role=**} {
        allow read: if request.auth.uid != null;
        allow write: if isSuperUser();
      }
    }
  }
}
查看更多
登录 后发表回答