Firebase FireStore правила безопасности обмена данными - PullRequest
1 голос
/ 10 октября 2019

У меня есть эта структура данных в firestore, где я пытаюсь связать пользователя с профилем, а затем с событием. Профиль может совместно использоваться несколькими пользователями и должен иметь возможность доступа к событиям для этого профиля.

user
    - id
    - email
    - name
    - profilePicUrl

profile
    - id
    - name
    - dateOfBirth
    - owners: [ "user1","user2" ]
    - etc.

event
    - id
    - profileId
    - name
    - startDate
    - endDate

В настоящее время у меня есть:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{id} {
      allow read, write: if request.auth.uid == id;
    }
    match /profiles/{id} {
        allow read, write: if ("owners" in resource.data && resource.data.owners != null && request.auth.uid in resource.data.owners);
    }
    match /events/{id} {
        allow read, write: if hasAccess(userId, resource) == true;
    }
  }
}

function hasAccess(userId, resource) {
    // Not sure what to put here but basically need
    // to get profiles where user is owner
    // and get events for these profiles
}

Но не уверен, что поместить в hasAccessфункция. Спасибо, если кто-то может направить меня.

ОБНОВЛЕНИЕ 2019/10/11

Каким-то образом я заставил это работать, используя следующее правило:

    match /events/{id} {
            allow read, write: if (exists(/databases/$(database)/documents/profiles/$(resource.data.profileId)) && 
                                  "owners" in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data && 
                                  get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners != null && 
                                  request.auth.uid in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners);
        }

ОБНОВЛЕНИЕ 2019/10/14

У меня есть некоторые проблемы с правами записи, поэтому мне пришлось пересмотреть ее, как показано ниже:

match /events/{id} {
  allow read: if ( exists(/databases/$(database)/documents/profiles/$(resource.data.profileId)) 
                     &&   "owners" in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data 
                     &&   get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners != null 
                     &&   request.auth.uid in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners);
  allow write: if ( request.auth.uid in get(/databases/$(database)/documents/profiles/$(resource.data.profileId)).data.owners );
}

1 Ответ

0 голосов
/ 10 октября 2019

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

Вместо этого вы можете дублировать данные, необходимые для правила, в каждый документ, который необходимо защитить. Это означает, что каждый документ события должен иметь копию каждого списка владельцев в качестве поля. Да, это будет больше хлопот, чтобы держать все события в актуальном состоянии, если список владельцев для события должен измениться.

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