web-dev-qa-db-fra.com

Règles de sécurité Firestore basées sur des valeurs de carte

Je souhaite enregistrer si un utilisateur est autorisé à lire un document dans le document lui-même, en fonction de l'adresse de messagerie de l'utilisateur. Plusieurs utilisateurs devraient avoir accès au même document.

Selon la documentation Firestore n'autorise pas l'interrogation des membres du groupe. C’est pourquoi je stocke les adresses électroniques des utilisateurs dans une mappe String-Bool avec l’adresse électronique en tant que clé.

Dans l'exemple suivant, je n'utilise pas les courriers électroniques comme clés de carte, car cela ne fonctionne déjà pas avec les chaînes de base.

La structure de la base de données ressemble à ceci:

lists
  list_1
    id: String
    name: String
    owner: E-Mail
    type: String
    shared:
      test: true

Toutes les règles de sécurité sont énumérées ici:

service cloud.firestore {
  match /databases/{database}/documents {
    match /lists/{listId=**} {
        allow read: if resource.data.shared.test == true
    }
  }
}

Edit: Cela ne fonctionne pas non plus si j'utilise match /lists/{listId} au lieu de match /lists/{listId=**}

Si je comprends bien, ces règles de sécurité devraient permettre l'accès en lecture à tout le monde si la valeur de la carte shared[test] est vraie.

Par souci d’exhaustivité: c’est la requête que j’utilise (Kotlin sur Android):

collection.whereEqualTo("shared.test", true).get()
        .addOnCompleteListener(activity, { task ->
            if (task.isSuccessful) {
                Log.i("FIRESTORE", "Query was successful")
            } else {
                Log.e("FIRESTORE", "Failed to query existing from Firestore. Error ${task.exception}")
            }
        })

Je suppose que je ne peux pas accéder aux valeurs de carte à partir des règles de sécurité. Alors, quelle serait une solution alternative à mon problème?

Dans la référence des règles Firestore il est écrit que les cartes peuvent être accessibles comme ceci resource.data.property == 'property' alors, qu'est-ce que je fais mal?

13
Marcel Bochtler

Edit: Ce problème devrait être résolu maintenant. Si vous le voyez toujours (et que vous êtes certain que c'est un bogue avec l'évaluateur de règles), faites-le moi savoir dans les commentaires.

J'ai discuté avec certaines personnes du problème que vous rencontrez, et cela semble être un problème avec les règles de sécurité elles-mêmes. En gros, le problème semble être spécifique à l'évaluation des champs imbriqués dans les requêtes, comme ce que vous faites.

Donc, en gros, ce que vous faites devrait fonctionner correctement et vous devrez attendre une mise à jour de l'équipe Firestore pour que cette requête fonctionne. Je vais essayer de me rappeler de mettre à jour cette réponse lorsque cela se produira. Désolé pour ça!

9
Todd Kerpelman

Chaque fois que vous avez (facultatif) propriétés imbriquées vous devez vous assurer que la propriété existe avant de continuer à vérifier sa valeur, par exemple.

allow read: if role in request.auth.token && request.auth.token[role] == true

dans ton cas: 

allow read: if test in resource.data.shared && resource.data.shared.test == true

, Je me suis longtemps débattu avec les rôles jusqu’à ce que j’ai réalisé que, pour les utilisateurs non-administrateurs, le champ admin est indéfini et que les règles de la mémoire de secours se bloquent et ne vérifient plus les correspondances possibles.

Pour un utilisateur sans token.admin, cela va toujours planter peu importe si vous avez d'autres correspondances vraies, par exemple:

function userHasRole(role) {
  return isSignedIn() && request.auth.token[role] == true
}
0
Gerard Lamusse