Bien que les opérations de pipeline offrent un large éventail de fonctionnalités, le moteur de règles est limité à la reconnaissance des filtres de comparaison (par exemple, >) et logiques (par exemple, or) pour garantir la satisfiabilité et la sécurité des contraintes.
Expressions de filtre acceptées
Pour que les opérations de pipeline soient limitées aux limites définies par vos règles, elles doivent utiliser des opérateurs logiques et de comparaison par rapport à des constantes. Le moteur de règles reconnaît les types de filtres suivants :
- Comparaisons :
eq,neq,gt,gte,lt,lte,in,arrayContains. - Logique :
and,or.
Voici quelques exemples :
where(eq("foo", 2))where(lt("foo", 2))documents("/user/1", "/user/2").where(...)
Propriétés de la requête
Vous pouvez continuer à utiliser l'objet request pour valider l'authentification et le contexte de requête, bien que certaines propriétés disponibles dans les requêtes standards ne soient pas compatibles avec les opérations de pipeline.
Propriétés acceptées
Le nouveau moteur continue d'être compatible avec les propriétés suivantes :
request.auth: accédez aux données d'UID et de jeton de l'utilisateur.request.method: identifie l'opération (par exemple,get,list).request.path: chemin d'accès à la ressource consultée.request.time: code temporel côté serveur de la requête.
Propriétés non acceptées
Les propriétés request.query telles que limit, offset et orderBy ne sont pas compatibles avec les vérifications des règles d'opérations de pipeline en raison de la complexité de la détermination de ces valeurs dans les requêtes à plusieurs étapes.
Gestion et autorisations des étapes du pipeline
Il existe différentes étapes de pipeline qui correspondent à des opérations précises dans les règles de sécurité :
- Autorisations
allow list: déclenchées par les étapescollection(),collectionGroup()etdatabase(). - Autorisations
allow get: déclenchées par l'étapedocuments(), qui est traitée de la même manière qu'une opérationgetpar lot. - Étape des littéraux : l'étape
literals()ne lit pas les données de la base de données, mais peut entraîner des coûts. Pour éviter tout abus, il doit être associé à une autre étape (commecollection()) qui peut être validée par des règles.
Étapes de modification des champs
Les règles ne s'appliquent qu'aux données stockées, et non aux valeurs dérivées. Si un pipeline inclut des étapes qui modifient des champs (par exemple, add_fields(...), replace_with(...), select(...), remove_fields(...)), le moteur de règles cesse d'appliquer les contraintes de filtre après cette étape. Pour vous assurer que les règles fonctionnent comme prévu, placez vos étapes de filtrage (c'est-à-dire where) avant toute étape susceptible de modifier les documents stockés d'origine.
Prenons l'exemple de la règle de sécurité suivante :
match /databases/{database}/documents {
match /cities/{city} {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
allow read: if resource.data.visibility == 'public';
}
}
Refusé : cette règle rejette le pipeline suivant, car l'étape addFields se produit avant le filtrage des documents où visibility est public :
const results = await db.pipeline()
.collection("/cities")
// Filters after a modification stage are ignored by Rules.
.addFields(constant(1000).as("population"))
.where(eq(field("visibility"), constant("public")))
.execute();
Autorisé : cette règle autorise le pipeline suivant, car l'étape where(eq(field("visibility"), constant("public"))) se produit avant toute étape de modification :
const results = await db.pipeline()
.collection("/cities")
.where(eq(field("visibility"), constant("public")))
.addFields(constant(1000).as("population"))
.execute();