Правила Vuexfire / Firestore: основанный на ролях доступ к выбранным элементам коллекции - PullRequest
0 голосов
/ 06 февраля 2019

У меня проблемы с реализацией системы доступа на основе ролей с использованием правил Firestore и Vuexfire.

Моя цель - иметь возможность привязать список в моем приложении к коллекции Firestore только с частью ее элементов.видимый / редактируемый, основанный на пользовательских ролях.

При попытке сделать это с моей текущей структурой предоставление доступа на чтение / запись к одному элементу в коллекции возвращает ошибку «Недостаточно прав» при привязке к коллекции, и ничего не происходит.найдено.

Я пытаюсь добиться поведения:

  • При доступе к списку в моем приложении пользователь будет видеть только те элементы, к которым ему предоставлен доступ к его коллекции ролей.
  • Пустой список должен появляться только в том случае, если либо коллекция пуста, либо пользователь не имеет соответствующей роли над каким-либо элементом в коллекции.

Текущая структура может быть проиллюстрирована следующим образом:

hotels/
  hotelA
    name: "hotel-a"
    rooms/
      roomA
      roomB
  hotelB
    name: "hotel-b"
    rooms/

users/
  adminA
    roles/
      hotelA
        role: "admin"

Используя следующие правила:

service cloud.firestore {
  match /databases/{database}/documents {
    allow read: if request.auth != null;

    match /hotels/{hotel} {
      function isSignedIn() {
        return request.auth != null;
      }
      function getRole(rsc) {
        return get(/databases/$(database)/documents/users/$(request.auth.uid)/roles/$(rsc.id)).data.role;
      }
      function isOneOfRoles(rsc, array) {
        return isSignedIn() && (getRole(rsc) in array);
      }

      allow read, write: if isOneOfRoles(resource, ["admin"]);
    }
  }
}

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

const setListHotelRefFromId = (context) => {
  var db = firebase.firestore()
  var listHotelRef = db.collection('hotels')
  context.dispatch('setListHotelRef', { ref: listHotelRef })
}

const setListHotelRef = firebaseAction(({ bindFirebaseRef, unbindFirebaseRef, commit }, { ref }) => {
  commit(types.SET_LOADING, true)
  bindFirebaseRef('list.hotel', ref).then(() => {
    commit(types.SET_LOADING, false)
  })
})

В среде, описанной выше, предположим, что я вошел в систему как пользователь с идентификатором пользователя «AdminA» и получил доступ к списку отелей.Я ожидал увидеть список с единственной записью «hotelA», но вместо этого получил бы ошибку «Недостаточно прав» из Firestore.

...