Écrire une stratégie de données
Objectif
Ajouter une règle que la plateforme ne fournit pas — « pas au-delà de votre plafond d’approbation », « plus une fois facturé » — et filtrer l’autorisation d’un rôle selon cette règle.
Prérequis
- Vous êtes connecté au Centre de contrôle d’administration, un environnement est sélectionné, et vous avez ouvert la solution à laquelle la stratégie doit appartenir — c’est là que se trouve l’écran, car la stratégie voyage dans le package de cette solution.
- Vous connaissez les noms logiques des champs que lit votre règle. Ils figurent sur l’écran Champs de la table.
Trois types, et comment choisir le bon
Les stratégies intégrées répondent à la question quels enregistrements — les miens, ceux de mon unité, ceux de tout le monde. Elles couvrent l’essentiel des besoins d’un rôle. Écrivez-en une vous-même lorsqu’elles ne suffisent pas, et la première chose à décider est son type :
| Quels enregistrements | Règle sur chaque enregistrement | |
|---|---|---|
| Ce que c’est | une condition transformée en filtre de base de données | une règle vérifiée lors de l’enregistrement d’un enregistrement |
| À utiliser quand | la réponse dépend de qui pose la question — sa région, son équipe | la réponse dépend de ce que dit l’enregistrement — un plafond d’approbation, un statut |
| Ce que voit l’utilisateur | les enregistrements ne sont tout simplement pas là | un message expliquant pourquoi l’enregistrement a été refusé |
| Exemple | Record.par_region == CurrentUser.par_region | « Ce total dépasse votre plafond d’approbation. » |
Une stratégie Quels enregistrements est le meilleur outil chaque fois qu’elle convient : les enregistrements qu’elle exclut ne quittent jamais le serveur, son application ne coûte donc rien et il n’y a aucun message à lire pour personne. Elle ne peut cependant pas tout faire — elle devient une requête, et ne peut donc que comparer des champs à des valeurs.
Une stratégie Règle sur chaque enregistrement est celle qui peut dire Total is under my approval limit, car ce n’est pas une question portant sur quels enregistrements existent. Elle
s’exécute sur chaque enregistrement en cours d’enregistrement, et elle peut s’expliquer.
Le troisième type, Enregistrements de qui (portail), ne concerne pas du tout les personnes connectées — il répond à la même question « quels enregistrements » pour un visiteur d’un portail, et il est déclaré sur une table plutôt qu’accordé à un rôle. Si c’est ce que vous cherchez, ce n’est pas la bonne page : voir Décider des enregistrements qu’un visiteur voit.
Si votre règle est en réalité « tout le monde doit remplir ce champ », il vous faut plutôt une règle métier ou une étape de plug-in sur la table — elles s’appliquent à tout le monde, ce qu’implique une règle de qualité des données. Une stratégie s’applique à quiconque détient une autorisation soumise à elle, ce qu’implique une autorisation.
Étapes
-
Ouvrez Solutions, ouvrez la solution qui contient votre application, et sélectionnez Stratégies de données dans sa navigation. L’écran liste les stratégies que porte cette solution ; la solution par défaut (« Main ») liste toutes les stratégies de l’environnement.
-
Sélectionnez Nouveau.
-
Donnez-lui un nom d’affichage — le nom sous lequel elle apparaîtra dans la liste des stratégies de l’écran des rôles. Le nom logique se remplit tout seul sous votre préfixe d’éditeur ; vous pouvez le modifier maintenant mais pas plus tard, car c’est le nom auquel chaque attribution fera référence.
-
Choisissez le type. Il détermine ce que demande le reste du formulaire, et il ne peut pas être modifié ensuite. Les étapes ci-dessous concernent Règle sur chaque enregistrement ; pour Quels enregistrements, passez directement à Écrire une stratégie Quels enregistrements.
-
Choisissez Quels enregistrements. Pour une stratégie de règle, c’est la stratégie intégrée qui filtre les listes, et elle n’est pas facultative — voir Pourquoi une stratégie de règle a aussi besoin d’une portée. Tous les enregistrements signifie « tout, sous réserve de ma règle ».
-
Cochez les opérations sur lesquelles la règle doit être vérifiée. Par défaut : création, mise à jour et suppression. Laissez Lecture décochée, sauf intention délibérée : une règle qui refuse une lecture fait disparaître des enregistrements des listes pour une raison que personne ne peut voir.
-
Écrivez la règle. Elle est en BS Lang, le même langage qu’une règle métier, et elle s’exécute sur un seul enregistrement :
if (getValue("par_total") > currentUser("par_approvallimit")) {deny("That total is over your approval limit.");}Appelez
deny("…")pour refuser. Une règle qui ne refuse rien autorise l’opération. Le message que vous écrivez est ce que voit l’utilisateur — dites donc ce qui rendrait l’enregistrement acceptable, plutôt que le fait que quelque chose n’allait pas. -
Sélectionnez Enregistrer. Si la règle ne s’analyse pas, l’enregistrement échoue et indique où. C’est délibéré : l’alternative serait de le découvrir le jour où quelqu’un est refusé par une règle qui ne peut pas s’exécuter.
-
Ouvrez l’écran Rôles de la solution, et réglez la cellule de l’autorisation à filtrer sur votre nouvelle stratégie. Elle apparaît dans la même liste que les stratégies intégrées.
Écrire une stratégie Quels enregistrements
Une stratégie Quels enregistrements devient une requête de base de données : elle s’écrit donc différemment et demande d’autres informations.
-
Choisissez la table. Contrairement à une règle, ce type de stratégie s’écrit sur les champs d’une table : il doit donc en nommer une — et c’est ce qui permet à la plateforme de vérifier, à l’enregistrement, que ces champs existent. Elle ne sera proposée que sur la ligne de cette table, dans l’écran Rôles de la solution.
-
Écrivez la condition — une seule condition, pas un script :
Record.par_region == CurrentUser.par_region && Record.par_status != "Closed"Record.<field>est un champ de la table choisie.CurrentUser.<name>est une information sur la personne connectée — les mêmes noms que ceux listés sous Ce qu’une règle peut lire, plus n’importe quel champ de la table des utilisateurs. Combinez les conditions avec&&et||, et regroupez-les avec des parenthèses. -
Comparer à un ensemble signifie « fait partie de » :
Record.owning_unit == CurrentUser.UnitsAndBelowsélectionne les enregistrements dont le propriétaire se trouve n’importe où dans votre unité ou en dessous. Vous pouvez aussi comparer à une liste écrite en toutes lettres :Record.par_status == ["Draft", "Submitted"]. -
Sélectionnez Enregistrer. Tout ce que la plateforme ne peut pas transformer en requête est refusé immédiatement, avec la raison — voir ci-dessous.
Ce qu’une condition ne peut pas exprimer
C’est volontairement restreint, car tout ce qui s’y trouve doit devenir une requête de base de données :
| Non autorisé | Parce que | À la place |
|---|---|---|
>=, <= | il n’existe pas d’opérateur de requête pour eux | > ou < |
!(…) | une requête ne peut pas être niée | dites ce qu’il faut garder, avec != |
length(x), toute fonction | elle devrait être exécutée, et un filtre ne s’exécute pas | comparez directement le champ |
Record.total * 2 > 100 | l’arithmétique empêche une requête d’utiliser un index | comparez au nombre que vous visez |
Record.account.owner | suivre une recherche est une jointure, et une jointure cachée ralentit chaque requête | un champ de cette table |
| plusieurs conditions sur plusieurs lignes | une stratégie est une seule condition | combinez-les avec && |
Tout cela est refusé à l’enregistrement, en nommant la ligne. C’est toute la raison pour laquelle le langage des conditions est réduit : une condition que la plateforme ne pourrait pas appliquer sans rien dire afficherait des enregistrements que quelqu’un croyait masqués.
Ce qu’une règle peut lire
| Appel | Ce qu’il vous donne |
|---|---|
getValue("par_total") | L’enregistrement tel qu’il sera après la modification. |
getPreValue("par_total") | L’enregistrement tel qu’il est stocké actuellement. Vide lors d’une création. |
currentUser("par_approvallimit") | Un champ de l’enregistrement utilisateur de la personne connectée. |
isOwner() | Si cette personne est propriétaire de l’enregistrement. |
hasRole("Manager") | Si elle détient un rôle. |
operation() | Create, Read, Update ou Delete. |
entityName() | Le nom logique de la table. |
deny("…") | Refuser, avec la raison que lira l’utilisateur. |
currentUser lit la table des utilisateurs de cet environnement : pour comparer à un plafond
d’approbation, ajoutez d’abord ce champ à cette table, exactement comme vous le feriez pour n’importe
quelle autre table.
Pourquoi une stratégie de règle a aussi besoin d’une portée
Une règle a besoin d’un enregistrement déjà chargé. Une liste, c’est précisément ce que vous avez avant d’en avoir chargé un seul : une règle ne peut donc pas la filtrer — la plateforme devrait récupérer toutes les lignes pour décider lesquelles récupérer. Une stratégie Quels enregistrements a la propriété inverse, et c’est exactement pour cela qu’elle constitue un type distinct plutôt qu’une règle plus astucieuse.
Une stratégie de règle porte donc les deux : Quels enregistrements est une stratégie intégrée que la plateforme transmet à la base de données, et la règle est vérifiée ensuite sur chaque enregistrement que quelqu’un ouvre, enregistre ou supprime réellement. Réglez Quels enregistrements sur la stratégie intégrée la plus restreinte qui soit vraie, et laissez la règle gérer le reste.
En désactiver une
Décochez En vigueur et enregistrez. La stratégie existe toujours et chaque attribution qui en dépend continue de fonctionner — avec sa seule réponse Quels enregistrements, sans vérification de la règle. C’est la bonne chose à faire pendant que vous cherchez pourquoi une règle refuse quelque chose ; supprimer la stratégie ne l’est pas, et la plateforme ne vous laissera pas supprimer une stratégie qu’un rôle utilise encore.
Une stratégie Quels enregistrements n’a pas cet interrupteur, et ce n’est pas un oubli : elle est la réponse à la question « quels enregistrements », si bien que la désactiver ne pourrait signifier que tout afficher ou ne rien afficher, et ni l’un ni l’autre n’est ce que l’on entend par la mettre en pause. Modifiez sa condition, ou modifiez l’attribution.
Les stratégies voyagent avec la solution
Une stratégie appartient à une solution, comme une table ou un formulaire, et elle accompagne cette solution lorsque vous l’exportez et arrive avec elle lorsque vous l’importez ailleurs.
C’est tout l’intérêt d’en écrire une. « Une facture au-delà de mon plafond d’approbation n’est pas à moi d’approuver » fait partie du fonctionnement de l’application, et non d’un paramètre que quelqu’un configure par environnement — livrer l’application sans elle laisserait Test et Production autoriser sans rien dire ce que Développement refusait, ce qui est le pire sens dans lequel une règle de sécurité puisse échouer.
Trois conséquences en découlent :
- La règle est revérifiée à l’importation, exactement comme lorsque vous l’avez écrite. Un package portant une stratégie qui ne se compile plus est refusé à l’importation plutôt que découvert par la première personne qu’elle refuse à tort.
- Une stratégie livrée désactivée arrive désactivée. Décochez En vigueur sur une règle préparée en vue d’une mise en service et l’environnement cible la reçoit dans cet état ; l’importation n’activera pas une règle que personne n’a encore demandée.
- Désinstaller la solution supprime la stratégie — ainsi que les attributions faites sous elle, et c’est la seule fois où celles-ci disparaissent sans que l’on vous le demande. Sinon, une attribution dont la stratégie a disparu se mettrait à refuser tout ce qu’elle autorisait auparavant, sans rien à l’écran pour expliquer pourquoi.
Les personnes à qui quelque chose est accordé sous la stratégie ne voyagent pas : cela nomme vos collaborateurs, et reste dans l’environnement où vous l’avez décidé.
Dépannage
- « La règle de la stratégie ne s’analyse pas. » — une faute de frappe dans la règle. Le message indique l’emplacement.
- « … est l’une des stratégies propres à la plateforme. » — vous avez utilisé le nom d’une stratégie intégrée. Vos propres stratégies portent votre préfixe d’éditeur.
- « … filtre encore des autorisations détenues par N rôle(s). » — modifiez d’abord ces attributions dans l’écran Rôles de la solution. Supprimer la stratégie maintenant les refuserait toutes.
- Personne ne peut plus rien enregistrer dans la table. — vérifiez la comparaison de la règle.
Une règle qui lit un champ inexistant obtient une valeur vide, et
"" > 100n’est pas la comparaison que vous vouliez. Décochez En vigueur le temps de trouver la cause. - La règle ne semble jamais s’exécuter. — vérifiez les opérations cochées, et que l’attribution du rôle pointe bien vers votre stratégie plutôt que vers une stratégie intégrée.
- Un utilisateur est refusé avec un message évoquant une stratégie qui n’a pas pu être évaluée. — la règle n’a pas pu s’exécuter. L’opération est refusée plutôt qu’autorisée, car une règle qui n’a pas pu s’exécuter n’a pas dit que l’enregistrement était acceptable. Corrigez la règle, ou décochez En vigueur.
- « Cette condition ne peut pas être transformée en requête. » — une condition Quels enregistrements utilise quelque chose qu’une requête ne peut pas exprimer. Le message indique la ligne et ce qu’il faut utiliser à la place ; le tableau ci-dessus les liste tous.
- Ma stratégie Quels enregistrements n’est pas proposée sur la ligne voulue. — elle est écrite pour une table : elle n’est donc proposée que sur la ligne de cette table, et jamais sur Toutes les tables. Écrivez une stratégie distincte pour l’autre table.
- Une stratégie Quels enregistrements n’affiche rien à personne. — une condition qui ne se résout
en rien ne sélectionne rien, ce qui est le sens sûr que la plateforme choisit toujours. Vérifiez
les noms de champs et, si vous avez comparé à un ensemble comme
CurrentUser.Teams, que la personne en fait réellement partie.