Une recherche qui répète des secrets
Une recherche bien réglée ne montre à une personne que ce qu’elle a le droit de lire. Elle oublie aussi le texte supprimé ou ancien. Les deux comptent parce qu’une recherche copie vos documents dans un index, et que la copie ignore les règles de l’original.
Une étudiante cherche « dates des vacances » et obtient une page de paie. Ou une règle supprimée répond encore.
À la fin de cette leçon
Remarque
Je peux garder une recherche dans ce que chaque personne peut voir et faire arriver à l’index une suppression ou une nouvelle version.
Mots clés
| Mot | Ce que ça veut dire |
|---|---|
| Filtre d’accès | une règle qui ne garde que ce qu’une personne peut lire |
| Groupe | un ensemble nommé de personnes qui partagent un accès |
| Périmé | une copie plus ancienne que la version actuelle |
| Version | un numéro qui monte à chaque modification du document |
| Marque de suppression | une trace qu’une chose a été supprimée |
| Fuite | montrer quelque chose à qui n’a pas le droit de le voir |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Filtrez avant de classer, jamais après
Chaque morceau porte les groupes qui peuvent le lire, une sorte de métadonnée. Au moment de la requête, la recherche ne garde que les morceaux que les groupes de la personne autorisent, puis prend les k meilleurs.
Filtrer après les k premiers se trompe deux fois. Une page cachée occupe une place, donc la personne obtient moins de résultats qu’elle ne devrait. Et un compte « 3 résultats, 2 cachés » lui apprend que ces pages existent.
Exemple détaillé : Léa cherche les dates des vacances
| Méthode | Résultats pour Léa | Ce qui va mal |
|---|---|---|
| Filtrer après les 2 premiers | e1 | Une page de paie a pris une place, puis a été cachée |
| Filtrer avant les 2 premiers | e1, e3 | Rien |
| Filtrer avant, périmées retirées | e1 | L’ancienne copie e3 a disparu |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une suppression doit atteindre l’index
L’index garde sa propre copie de chaque document. Supprimer le fichier source ne touche pas cette copie, donc l’ancien texte répond encore. Supprimez chaque morceau du document dans l’index, et dans tout cache de réponses, en une seule étape.
Un document modifié pose le même problème. Donnez à chaque morceau une version. Retirez les morceaux plus anciens que la version actuelle quand on rafraîchit le document.
Une erreur courante
Attention
Beaucoup pensent que supprimer le fichier source retire le texte de la recherche. L’index en a gardé une copie, donc le texte reste trouvé. Supprimez aussi dans l’index, et vérifiez en cherchant une phrase de la page supprimée.
Écrire la recherche avec droits, partie 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const entrees = [' ' { id: \"e2\", doc: \"paie\", groupes: [\"personnel\"], version: 1, texte: \"primes et dates de vacances pour les cadres\" },' ' { id: \"e4\", doc: \"planning\", groupes: [\"personnel\"], version: 1, texte: \"qui travaille pendant les vacances\" },' ' { id: \"e1\", doc: \"manuel\", groupes: [\"personnel\", \"etudiants\"], version: 2, texte: \"dates des vacances du trimestre\" },' ' { id: \"e3\", doc: \"manuel\", groupes: [\"personnel\", \"etudiants\"], version: 1, texte: \"anciennes dates de vacances\" },' '];' 'const actuelle = { manuel: 2, paie: 1, planning: 1 };' 'const lea = { nom: \"léa\", groupes: [\"etudiants\"] };' > acces1.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire la recherche avec droits, partie 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function permis(e, user) { return e.groupes.some(function (g) { return user.groupes.includes(g); }); }' 'function score(e, q) { return q.filter(function (m) { return e.texte.split(\" \").includes(m); }).length; }' 'function haut(liste, q, k) {' ' return liste.filter(function (e) { return score(e, q) > 0; })' ' .sort(function (a, b) { return score(b, q) - score(a, q); })' ' .slice(0, k);' '}' 'function ids(liste) { return liste.map(function (e) { return e.id; }).join(\" \") || \"rien\"; }' >> acces1.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Écrire la recherche avec droits, partie 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const q = [\"vacances\", \"dates\"];' 'function miens(liste) { return liste.filter(function (e) { return permis(e, lea); }); }' 'console.log(\"filtre après les 2 premiers :\", ids(miens(haut(entrees, q, 2))));' 'console.log(\"filtre avant les 2 premiers :\", ids(haut(miens(entrees), q, 2)));' 'const fraiches = entrees.filter(function (e) { return e.version >= actuelle[e.doc]; });' 'console.log(\"et copies périmées retirées :\", ids(haut(miens(fraiches), q, 2)));' 'const reste = entrees.filter(function (e) { return e.doc === \"manuel\" ? false : true; });' 'console.log(\"après suppression du manuel, Léa trouve :\", ids(haut(miens(reste), q, 2)));' >> acces1.js"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lancer et comparer les filtres
docker exec -w /home/node/project agent node acces1.jsAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ceci est une maquette
L’index est une liste de quatre entrées et une personne est un nom avec des groupes. Un vrai système filtre dans son moteur de recherche, à partir du compte connecté, et une suppression est un vrai appel à ce moteur.
Le Run n’appelle aucun modèle. La règle reste la même : filtrer d’abord, supprimer partout.
Ce que le Run affiche
| Ligne | Résultat |
|---|---|
| filtre après les 2 premiers | e1 |
| filtre avant les 2 premiers | e1 e3 |
| et copies périmées retirées | e1 |
| après suppression du manuel, Léa trouve | rien |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.