Premier point Les formats ne doivent pas se chevaucher
Deuxième point les formats qui devront s’afficher en plus d’un format affiché devront avoir le mot clé OVERLAY
Troisième points Pour que le contenu d’un format soit lu il faut
Exfmt + ou touche CF ou Write + Read
Notre écran a 3 formats (Haut , Milieu, Bas) c’est le milieu qui doit être en exfmt (reçoit le focus)
Le DSPF
A DSPSIZ(24 80 *DS3)
A R HAUT
A ZONE1 10A B 6 3
A 4 3'Format haut'
A R MILIEU
A OVERLAY
A CA03(03)
A ZONE2 10A B 12 3
A 10 3'Format milieu'
A R BAS
A OVERLAY
A 22 10'F3 = Exit'
A 21 3'Format bas'
**free
Ctl-Opt DFTACTGRP(*NO);
Dcl-f overlay WORKSTN;
dou *in03 ;
write haut ;
write bas ;
exfmt milieu ;
if not *in03 ;
read haut ;
dsply zone1 ;
dsply zone2 ;
endif ;
enddo ;
*inlr = *on;
Remarque :
cette règle s’applique dans les formats Fenêtres (WINDOW) par contre les règles de chevauchement pour les fenêtres sont différentes
https://www.gaia.fr/wp-content/uploads/2017/02/team3.png600600Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2024-02-26 07:25:242024-02-26 15:34:02Superposition dans les DSPF OVERLAY
https://www.gaia.fr/wp-content/uploads/2017/02/team3.png600600Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2024-02-19 07:09:142024-04-23 16:11:47Tester l’affichage de vos écrans
Vous utilisez UIM pour faire vos AIDES et vos menus
Vous voulez avoir une version multi langue sans changer votre panel de groupe
Il n’existe pas de solution dynamique, mais vous pouvez utiliser les fichiers messages, comme pour les commandes et les écrans, à la compile il vous suffira de mettre en ligne la bibliothèque avec le bon langage
rappel un message est identifié par 7 caractéres xxxnnnn xxx est est généralement 3 lettres (mais avec des exceptions exemple SQL et SQ2) nnnn est composé de 4 chiffres
La partie utilisée dans les écrans et les commandes, c’est uniquement le message sur 132 caractères c’est le paramètre MSG()
dans notre exemple : Nous avons différencié 3 Types de messages pour simplifier TXT sur la structure du menu OPT sur le texte des options à afficher HLP sur les aides d’option à afficher USR sur les commandes (mais pas utilisé pour l’instant le tag MENUI ne semblant pas admettre de message ) c’est le standard des fichiers de messages associés au menu SDA
Nous avons créer une commande
CRTMNUMOD qui génère ces messages dans le msgf, par défaut c’est un menu de 10 options avec texte en Français
Les identifiants de messages sont remplacés par les textes des messages, si vous avez une version par langue , mettez la bibliothèque de la langue en ligne avant la compile et c’est joué.
Vous pouvez utiliser la même technique sur les panneaux d’aide
Vous pouvez indiquer de nouveaux identifiants si vous avez des textes de plus de 132 caractères
Vous pouvez utiliser des caractères spéciaux pour éviter certains problèmes de syntaxe
Pour les traductions vous pouvez même les automatiser en utilisant des webservices type Google , reverso, ou deepl bientôt nous ferons un article sur ce blog
/wp-content/uploads/2017/05/logogaia.png00Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2024-02-18 12:14:302024-02-19 20:00:48Créer un menu UIM multi-langue
Pour rappel, les listes de validation sont des objets sur IBMi, de type VLDL.
Par ligne de commande, on peut seulement créer une liste ou la supprimer.
L’utilisation classique des listes d’autorisation est la sécurisation de vos serveurs IWS par authentification basique. Celles-ci permettent l’utilisation d’un profil qui n’est pas un réel utilisateur IBM i.
La gestion, de ces listes, se passe dans navigator for i, dans le HTTPAdmin :
Onglet « Advanced »
Ce que vous pouvez faire :
Ajouter une entrée dans la liste, si la liste de validation n’existe pas, elle sera créé pour l’occasion. A minima, il faut renseigner la liste de validation, un profil et un mot de passe
Changer le mot de passe d’une entrée
Supprimer une entrée
Lister les entrées d’une liste
Ce que vous ne pouvez pas faire :
Consulter le mot de passe en cours d’une entrée, un classique en terme de sécurité.
Supprimer une liste de validation, il faut utiliser la commande 5250 DLTVLDL
Pour mettre en place la sécurisation d’un serveur via ces listes, il faut, toujours depuis le HTTPAdmin, au niveau de la gestion des sécurités de votre serveur HTTP*, sélectionner l’option liste de validation :
Avantage :
Ne pas créer de réel utilisateur IBMi pour l’authentification.
Permettre à des tiers extérieurs d’avoir un login ne pouvant servir que dans le cadre d’appel HTTP à un serveur protéger par la liste d’autorisation dont est issu le login
Encryption de la liste au niveau OS. Pas de possibilité d’accès aux données de la liste de façon simple.
En cas d’appel depuis l’extérieur du réseau de confiance, ça semble une bonne option.
Inconvénient :
Il faut connaître en amont le client qui va se connecter, et donc avoir une gestion de demande /création de compte
L’interface de gestion n’est pas compatible avec un grand nombre d’entrées dans la liste. Dans ce cas il faudra, soit trouver une autre solution pour sécuriser son serveur, soit utiliser les API misent à disposition par IBM
* Sur les versions récentes, la sécurité peut aussi être gérée au niveau du serveur applicatif. A vous de voir, si vous voulez un duo de serveurs HTTP/applicatif ou seulement un serveur applicatif, mais c’est un autre sujet…
IBM nous fournit des API pour gérer les listes de validation. On retrouve les actions possibles dans Navigator for i…. Et d’autres !
En regardant de plus près ces API, on constate sur la création d’une entrée de la présence d’un attribut permettant ou non de décrypter un mot de passe :
Navigator for i utilisant les valeurs par défaut, lorsqu’on crée une entrée par ce biais, le mot de passe n’est pas décryptable. Par contre, si on crée une entrée par l’API correspondante, avec cet attribut positionné à QSY_VFY_FIND (1), on peut par la suite récupérer le mot de passe via l’API C QsyFindValidationLstEntry() ou son équivalent QSYFDVLE
Prenons des exemples :
Je crée dans une liste de validation, dédié à l’article, DTFORM/DEMOBLOG, un profil MdpnonVIsible avec l’attribut de décryptage à ‘0’, et un profil MdpVisible avec l’attribut de décryptage à ‘1’.
Première remarque : l’appel d’api d’ajout d’une entrée dans une liste de validation renvoie un erreur si la liste n’existe pas. Il faut la créer au préalable par la commande CRTVLDL.
En regardant dans Navigator for i, les deux entrées apparaissent sans distinction :
Lors du décryptage, si on tente un appel de l’API find avec une erreur, mauvais nom de liste, profil inexistant, …, le retour est en erreur, comme pour toutes les API : -1. On peut récupérer le message détaillé de l’erreur, on reste sur de la gestion standard :
Si on lance l’API Find avec pour le profil MdpnonVisible :
L’API renvoie un code retour ok, mais pas de mot de passe, normal, il n’est pas décryptable.
Avec le profil décryptable, on récupère bien le mot de passe initial :
Par cette méthode, vous pouvez donc récupérer des mots de passe stockés dans une liste de validation, à la condition que l’entrée ait été créée avec le top de décryptage à ‘1‘.
Pour compléter la sécurité sur le décryptage des mots de passe, vous pouvez mettre :
Sur la liste de validation
Un profil technique comme propriétaire
Aucun droit sur aucun autre profil .
Avoir un programme dédié au décryptage avec :
Comme propriétaire le même que celui de la liste de validation
Compilé pour faire de l’adoption de droit.
Et si on veut aller plus loin, en cas de debug possible en prod, protéger les sources, du programme de décryptage et ses appelants, par mot de passe.
Bien entendu cette stratégie n’est valable que si la gestion des droits utilisateurs est rigoureuse… Pas de *allobj sur les profils par exemple !
Conclusion :
Vous pouvez utiliser les listes de validation pour stocker des profils/mot de passe, sans les stocker en clair sur la machine. Mais on peut très bien imaginer utiliser ces listes pour stocker toutes les données sensibles permettant les échanges inter-applications ou autre :
URL d’invocation de WS
IP ou nom DNS pour FTP / SFTP
…
Et pour cela de se créer une liste par usage, liste pour URL, liste pour IP/DNS, …, de mettre dans le profil, un code application, et dans le mot de passe la valeur que l’on veut récupérer, avec la limitation de 600 caractères pour le mot de passe, à part pour des URL très spécifique, ça ne devrait pas être limitatif.
Les listes de validation restent des objets très peu connu, mais qui mérite de l’être !
/wp-content/uploads/2017/05/logogaia.png00Damien Trijasson/wp-content/uploads/2017/05/logogaia.pngDamien Trijasson2024-02-05 14:16:002025-03-19 10:40:31Utiliser les listes de validation comme coffre fort de mot de passe
On connait les triggers before et after, mais on peut créer des triggers instead of pour remplacer l’action prévue, par exemple en écrivant dans une autre table
Ce type de trigger ne peut être mis que sur des vues
Voici un exemple
Création d’une table des frais
CREATE TABLE PLB/CLIENT_FRAIS ( NOM CHAR ( 40) NOT NULL WITH DEFAULT, PRENOM CHAR ( 30) NOT NULL WITH DEFAULT, MONTANT DEC ( 9, 2) NOT NULL WITH DEFAULT, NUMEMP CHAR ( 6) NOT NULL WITH DEFAULT)
Création d’une table audit des frais
CREATE TABLE PLB/AUDIT_FRAIS ( NUMEMP CHAR ( 06) NOT NULL WITH DEFAULT, MONTANT DEC ( 9, 2) NOT NULL WITH DEFAULT, DATFRAIS DATE NOT NULL WITH DEFAULT, HEUREFRAIS TIME NOT NULL WITH DEFAULT)
Création d’une vue sur la table des frais
CREATE VIEW PLB/CLIENT_FRAIS_vue AS SELECT * FROM PLB/CLIENT_FRAIS
Création d’un trigger Instead of sur cette vue Qui quand on écrit dans la table des frais remplace cette écriture par une écriture dans le fichiers des audits de frais.
CREATE TRIGGER INSTEADTEST INSTEAD OF INSERT ON CLIENT_FRAIS_vue REFERENCING NEW AS N FOR EACH ROW MODE DB2ROW BEGIN ATOMIC INSERT INTO AUDIT_FRAIS VALUES(N.NUMEMP, N.MONTANT, current date , current time);
END;
Test ajout d’un enregistrement
INSERT INTO PLB/CLIENT_FRAIS VALUES(‘Bouzin’, ‘Maurice’, 12100, 253)
Vous retrouvez l’enregistrement dans le fichier audit de frais et non celui des frais
Il est possible d’effectuer un contrôle sur les paramètres passés dans une commande avant que le programme de traitement ne soit exécuté et d’envoyer un message de diagnostic au sein même de la commande en cas d’erreur.
Pour ajouter des contrôles sur les paramètres d’une commande (en plus des contrôles inclus dans celle-ci), on peut lui affecter un programme de contrôle de validité créé en amont.
Ce programme recevra tous les paramètres de la commande et on pourra y réaliser divers contrôles/tests avant l’exécution du programme de traitement. Il permet également d’envoyer des messages de diagnostic pour que l’utilisateur puisse ajuster la saisie de ses paramètres.
Pour assigner le programme de contrôle de validité à la commande, on indique son nom dans le paramètre VLDCKR de la commande CRTCMD (lors de la compilation de la commande).
Cas d’exemple
Prenons le cas où nous souhaitons créer une commande simple qui permettrait de récupérer une extraction CSV des ventes réalisées par un utilisateur sur une année donnée.
On souhaitera donc vérifier deux choses :
L’utilisateur doit exister sur la machine
L’année choisie doit être comprise dans une période de 10 ans avant l’année en cours
On commence donc par créer la commande GETUSRVEN qui recevra ces deux paramètres :
Une fois la commande prête on peut préparer le programme de contrôle de validité. Pour cet exemple on créera un programme VGETUSRVEN (CLLE) :
Dans ce programme, on récupère les différents paramètres de la commande GETUSRVEN et la date actuelle en décimal.
On procède ensuite aux contrôles :
De l’utilisateur
Ici on utilise une suite de requêtes SQL pour vérifier que l’utilisateur existe sur la machine.
En cas d’absence d’utilisateur correspondant au paramètre de notre commande, on utilise la commande SNDPGMMSG (MSGTYPE *DIAG) avec le code message CPD0006 (conçu pour être utilisé dans des programmes de contrôle de validité).
On peut indiquer le message de notre choix dans le paramètre MSGDATA, mais attention, les quatre premiers caractères étant réservés il faut commencer son message par ‘0000’.
Une fois le message de diagnostic indiqué on réutilise la commande SNDPGMMSG (MSGTYPE *ESCAPE) avec le code message CPF0002 ce qui permettra d’indiquer à l’appelant que des erreurs ont été trouvées et de suspendre l’exécution de la commande.
De l’année choisie
On applique ici la même méthode que précédemment, en vérifiant que l’année n’est pas antérieure de 10 ans par rapport à l’année en cours, et qu’elle n’est pas supérieure.
On peut maintenant compiler le programme VGETUSRVEN (commande CRTBNDCL).
Enfin on compile la commande GETUSRVEN en spécifiant VGETUSRVEN dans le paramètre VLDCKR de la commande CRTCMD.
On peut maintenant essayer la commande, et constater les messages de diagnostic en cas de mauvaise saisie :
Il est également possible de voir quel programme de contrôle de validité est utilisé pour une commande (s’il y en a un) avec la commande DSPCMD CMD(nom de la commande) :
/wp-content/uploads/2017/05/logogaia.png00Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2024-01-18 11:36:322024-01-18 12:22:27Les programmes de contrôle de validité sur IBM i
Depuis la V7R1 (SF99701 – DB2 – niveau 23), on peut invoquer des web service via SQL. Les fonctions se trouvent dans SYSTOOLS.
En V7R4 TR5, sont sorties de nouvelles fonctions, elles se trouvent dans QSYS2.
Outre les fonctions HTTP, celles pour encoder / décoder en base64 et pour encoder / décoder L’URL, ont aussi été implémentées dans QSYS2.
Rappel des différences entre ces fonctions
Tout d’abord les performances. Les fonctions de QSYS2 permettent un gain non négligeable, elles sont basé sur les fonctions AXIS en C natif, contrairement à celles de SYSTOOLS qui sont basées sur des classes java.
Les paramètres dans l’entête ou le corps du message sont transmis en JSON pour les fonctions de QSYS2, à la place de XML pour celle de SYSTOOLS.
La gestion des certificats est simplifiée par l’utilisation de DCM, alors qu’avec les fonctions de SYSTOOLS, il fallait pousser le certificat dans le magasin du runtime java utilisé par les fonctions HTTP. En cas de multiple versions de java installées, il fallait s’assurer de laquelle servait pour les fonctions HTTP. L’ajout du certificat, se faisait via des commandes shell.
Les types et tailles des paramètres des fonctions ont été adaptés pour ne plus être des facteurs limitants de l’utilisation des fonctions SQL, voici quelques exemples :
Certaines utilisations ont aussi été simplifiées en automatisant des tâches.
Prenons l’exemple d’un appel à un web service avec une authentification basique. Le couple profil / mot de passe doit être séparé par « : » et l’ensemble encoder en base64. C’est la norme HTTP.
Dans le cas des fonctions de SYSTOOLS, il fallait effectuer l’ensemble des opérations, alors qu’avec les fonctions de QSYS2, il suffit de passer le profil et le mot de passe dans la propriété BasicAuth. La mise en forme et l’encodage étant faits directement par les fonctions AXIS :
Il y a par contre un cas limitatif des fonctions QSYS2, que IBM a rajouté, alors que la norme HTTP autorise ce type d’appel.
Il s’agit d’avoir une authentification basique sur un appel en http.
Ce cas n’est pas trop contraignant, aujourd’hui le https est la norme et le http quasiment disparu…. quasiment ! Nous rencontrons encore chez nos clients des web services « interne » en http. La migration en https n’étant pas vendeur auprès des directions qui n’y voit aucun gain pour le métier. C’est l’éternel problème des changements structurels en IT.
Dans ces cas, la fonction de QSYS2, renverra une erreur, assez claire !
Le premier réflexe est de voir avec le fournisseur du service s’il ne dispose pas d’une version en https.
Maintenant, si vous n’avez pas d’autre choix que d’appeler un web service en http avec authentification basique, il faudra continuer d’utiliser les fonctions de SYSTOOLS. Dans tous les autres cas, aucune hésitation, utilisez les fonctions de QSYS2.
Mais mettons nous d’accord, de l’authentification basique en http, ce n’est pas de la sécurité, c’est une absurdité.
En http, le message passe en clair sur la trame réseau, avec votre profil / mot de passe, encodé en base 64, et non encrypté, donc en clair eux aussi.
Edit :Précision apportée par Gautier Dumas de CFD-innovation. Merci à lui. On peut contourner le problème avec les fonctions de QSYS2. Il ne faut pas utiliser la propriété BASICAUTH, mais construire l’authentification basique comme on le faisait avec celle de SYSTOOLS. VALUES QSYS2.HTTP_GET( ‘http://hostname/wscommon/api/contacts’, ‘{« header »: »Authorization, BASIC dGVzdHVzZXI6dGVzdHB3ZA== »}’); Il n’y a donc vraiment plus de raison de continuer avec les fonctions de SYSTOOLS !
Vous voulez savoir ou vous êtes positionné dans votre écran , pour appeler un programme liste par exemple.
Vous avez plusieurs solutions on va en présenter 4 ici
1) INFDS sur le fichier écran (DSPF)
Permet d’avoir la ligne et la position du curseur sur votre écran dans votre programme Dcl-F votre-ecran WORKSTN INFDS(FICHIERDS) … dcl-ds fichierDS; ligne INT(3) POS(370); // curseur : ligne colonne INT(3) POS(371); // curseur : colonne end-ds; .. if ligne = 4 and colonne = 22; … endif;
Avantage, tout ce passe dans le programme rien à faire dans l’écran
Nous vous conseillons d’utiliser un include pour normaliser l’utilisation de cette data structure
2) Nom de la zone active
dans votre écran A RTNCSRLOC(&W_FMT &W_ZON) A CF04(04) A CA12(12) A CF10(10) A W_FMT 10A H TEXT(‘Nom du format’) A W_ZON 10A H TEXT(‘Nom de la Zone’) dans votre programme
if W_FMT = ‘FMT01’ and C1 = W_ZON = ‘NUMCLI’; … endif;
Avantage, vous avez directement le nom de la zone dans la quelle vous vous trouvez
3) Positionnement du curseur sur souris
Vous devez déclarer dans les dspf les zones qui contiendront les informations dans votre écran
A RTNCSRLOC(MOUSE &L1 &C1 &L2 &C2) A RÉCUPÉRATION DU CURSEUR A L1 3S 0H A C1 3S 0H A L2 3S 0H A C2 3S 0H dans votre programme if C1 = 4 and C1 = 22; … endif;
Avantage, Vous avez un exemple ici https://www.gaia.fr/utilisation-de-la-souris-dans-un-dspf/
c’est la seule solution pour gérer la souris
4) Divers sur sous fichier
Il y a un mot clé méconnu qui permet de connaitre le rang du SFL sans faire de readc dans l’écran A SFLCSRRRN(&R1)) A* RÉCUPÉRATION DU CURSEUR A R1 3S 0H dans votre programme R1 CHAIN SFL01 ;
Avantage , sur les sélections simples c’est une alternative au readc
Remarque :
Vous avez sans doute d’autres solutions, mais celles ci sont simples et efficaces Vous avez des mots clés pour les zones liés au aide, qui ne sont pas traités ici, regardez plutôt la, https://www.gaia.fr/ajouter-de-laide-a-vos-dspf/
https://www.gaia.fr/wp-content/uploads/2017/02/team3.png600600Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2024-01-07 12:10:012024-01-08 08:58:15Pour se repérer dans un écran DSPF
https://www.gaia.fr/wp-content/uploads/2017/02/team3.png600600Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2023-11-19 20:07:162023-11-19 20:07:17Générer un XLS avec SQL