Правило безопасности Firestore с использованием ссылки на другой документ

Я пытаюсь основать правило безопасности на ссылке на другой объект.

У меня есть набор пользователей и набор ролей. Пользовательский объект имеет поле под названием «роль», которое является ссылкой на конкретный документ в коллекции ролей.

users
  id
  name
  role <-- reference to particular role

roles
  id
  name
  isSuperUser

Цель здесь - позволить пользователю с определенной ролью (роль с isSuperUser == true) редактировать любую другую роль или ее подколлекции;

Вот мои правила, которые, как я думал, сработают:

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

Я подтвердил следующие работы, но на самом деле это не так уж и полезно ...

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

Если есть лучший способ обеспечить безопасность ролевой базы, я все слышу.

Отсутствие каких-либо инструментов отладки сильно расстраивает.


person Geo242    schedule 11.11.2017    source источник
comment
В основном я ищу то же самое. У меня есть коллекция рыб, которая принадлежит пользователю. Вместо хранения идентификатора пользователя я храню ссылку на пользователя. Итак, теперь я хочу проверить, совпадает ли fish.user.id с auth.uid. Возможно ли это, или я должен хранить только userId?   -  person Jaap Weijland    schedule 04.12.2017
comment
была идея получить данные непосредственно из ссылки, как в request.data.refField.data, но, очевидно, это не поддерживается < / а>   -  person galki    schedule 20.12.2018


Ответы (2)


Я знаю, что прошло некоторое время с момента первоначального вопроса, но у меня была аналогичная проблема, и я надеюсь, что это может помочь вам или другим.

Ваше состояние: get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role.isSuperuser == true;

Но role - это ссылка, что (очевидно) означает, что вам тоже нужно get. Попробуй это:

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

person blap    schedule 28.04.2018
comment
@JaapWeijland нет, к сожалению, нет. Ссылка на другой объект, похоже, не является путем, который я могу использовать для перехода к функции get. - person Geo242; 05.12.2018

Вы пытались переместить подстановочный знак во вложенный путь?

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();
      }
    }
  }
}
person Sergi Hernando    schedule 27.11.2017