Какой запрос Firestore Javascript соответствует этой структуре правил безопасности - PullRequest
0 голосов
/ 12 декабря 2018

Я протестировал эту структуру правил безопасности в консоли Firebase для Firestore, и я думаю, что она делает то, что я хочу, а именно: сохранить карту ролей для пользователей на уровне организация и применить разрешения для организации вложенные коллекции , всегда ссылаясь на родительскую организацию с использованием метода get().

service cloud.firestore {
  match /databases/{database}/documents {

    // ORGANIZATIONS collection
    match /organizations/{organization} {

      function isSignedIn() {
        return request.auth != null;
      }
      function getRole(rsc) {
        // Read from the 'roles' map in the resource (rsc)
        return rsc.data.roles[request.auth.uid];
      }
      function isOneOfRoles(rsc, array) {
        // Determine if the user is one of an array of roles
        return isSignedIn() && (getRole(rsc) in array);
      }

      allow write: if isSignedIn();
      allow read: if isSignedIn() && isOneOfRoles(resource, ['owner']);

      // PROJECTS subcollection
      match /projects/{project} {

        allow write: if isSignedIn() && isOneOfRoles( get(/databases/$(database)/documents/organizations/$(organization)), ['owner']);
        allow read: if isSignedIn() && isOneOfRoles(get(/databases/$(database)/documents/organizations/$(organization)), ['owner', 'member']);
      }
    }
  }
}

Теперь, поскольку запросы должны соответствовать правилам безопасности, я пытаюсь понять, как сделать запрос с использованиемКлиент Javascript, который будет соответствовать приведенным выше правилам безопасности.

У меня есть рабочий запрос для получения организаций, который выглядит следующим образом:

db.collection('organizations').where(`roles.${currentUser.uuid}`, '==', 'owner').get()

, который основан на структуре документа, подобной следующей:

organizations (collection)
  {organization} (document)
    name: string,
    roles: { 
      <user_id_1>: "owner",
      <user_id_2>: "member"
    },
    projects (subcollection)

Возможно ли иметь запрос (или даже несколько запросов) в клиенте Javascript , который проверяет, что пользователь играет определенную роль на уровне organization И проверяет свойства документав подколлекции projects, аналогично правилам безопасности?

РЕДАКТИРОВАТЬ : В конечном счете, яnk это вопрос authorization и поддерживает ли Firestore мой подход.Похоже, что моя лучшая ставка на данный момент - это рекурсивный синтаксис с подстановочными символами - match /organization/{document=**} - но поскольку соответствие любому условию позволяет получить доступ ко всем вложенным документам, этот подход выглядит менее безопасным.

В идеале я мог бы указать путь сбора - например, organizations/{organization}/projects - в своем клиентском запросе и иметь возможность указать, что роли {organization} должны быть проверены перед предоставлением доступа к projectsподнабор.

ПОТЕНЦИАЛЬНОЕ РЕШЕНИЕ : Следующая структура правил безопасности оставляет желать лучшего, но, похоже, это улучшение.Вместо путей, соответствующих конкретным подколлекциям, я просто использую рекурсивный подстановочный синтаксис.Кто-нибудь знает лучшее решение?

service cloud.firestore {
  match /databases/{database}/documents {

    function isSignedIn() {
      return request.auth != null;
    }
    function getRole(rsc) {
      // Read from the 'roles' map in the resource (rsc)
      return rsc.data.roles[request.auth.uid];
    }
    function isOneOfRoles(rsc, array) {
      // Determine if the user is one of an array of roles
      return isSignedIn() && (getRole(rsc) in array);
    }

    // ORGANIZATIONS
    match /organizations/{organization} {

      allow write: if isOneOfRoles(resource, ['owner']);
      allow read: if isOneOfRoles(resource, ['owner', 'member']);

    }

    // Any subcollections under ORGANIZATION
    match /organizations/{organization}/{sub=**} {

      allow write: if isOneOfRoles(get(/databases/$(database)/documents/organizations/$(organization)), ['owner']);
      allow read: if isOneOfRoles(get(/databases/$(database)/documents/organizations/$(organization)), ['owner', 'member']);

    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...