Catégories
Développement informatique Licences logicielles

Éthique et poli­tique dans les licences logi­cielles

Je conti­nue mes réflexions sur comment nous, infor­ma­ti­ciens, parti­ci­pons à la poli­tique par nos actions.

Il ne tient qu’à nous de refu­ser de parti­ci­per à des projets et des orga­ni­sa­tions du mauvais côté de la ligne morale. Contrai­re­ment à d’autres profes­sions, nous avons le choix. Utili­sons-le.


Plus que le choix, nous avons un pouvoir, énorme. C’est un des appren­tis­sages des logi­ciels libres. Nous avons quand même réussi que les plus grandes corpo­ra­tions se sentent obli­gées de contri­buer, même de façon mineure, à des logi­ciels communs profi­tant à tous. Nous avons réussi à en faire un argu­ment dans les proces­sus de recru­te­ment.

Imagi­nez, le temple du capi­ta­lisme, les méga star­tup techno qui contrôlent jusque notre vie privée, obli­gées de fait de se plier à contri­buer au domaine commun. Quel pouvoir !


Nous avons utilisé ce pouvoir pour impo­ser le libre accès au logi­ciel et au code source, en nous moquant de qui l’uti­lise et pour faire quoi, comme si cela ne nous concer­nait pas.

Que nous importe que l’im­pri­mante gère des listes de personnes à abattre tant que nous avons accès au code source du pilote pour en corri­ger les défauts. Je ne peux m’exo­né­rer des consé­quences de ce que je créé et de ce que je diffuse.

Avec tout le respect que j’ai pour l’énorme œuvre du logi­ciel libre, j’ai l’im­pres­sion que nous avons partiel­le­ment fait fausse route, privi­lé­giant une vision liber­taire amorale plutôt qu’as­su­mer les consé­quences de ce que nous créons.

Pire, en faisant le logi­ciel libre comme l’al­pha et l’oméga de toute notion poli­tique et éthique dans le logi­ciel, nous nous sommes reti­rés toute capa­cité à inter­ve­nir sur d’autre critères.


Je repense à la licence JSON qui avait fait grand bruit par le passé.

The Soft­ware shall be used for Good, not Evil.

https://www.json.org/license.html

Cette notion m’at­tire, aussi floue et aussi problé­ma­tique soit-elle.

Oui, cette licence n’est pas libre. La licence GPL serait incom­pa­tible avec icelle. Qu’im­porte : L’ac­cès au logi­ciel et à son code source ne me semble pas une valeur si abso­lue qu’il me faille aban­don­ner tout recul sur ce qui est fait avec le logi­ciel.

Je ne suis pas seul, en paral­lèle d’autres ont mis à jour la licence Hippo­cra­tic, qui va globa­le­ment dans le même sens.

The soft­ware may not be used by indi­vi­duals, corpo­ra­tions, govern­ments, or other groups for systems or acti­vi­ties that acti­vely and knowin­gly endan­ger, harm, or other­wise threa­ten the physi­cal, mental, econo­mic, or gene­ral well-being of indi­vi­duals or groups in viola­tion of the United Nations Univer­sal Decla­ra­tion of Human Rights

https://first­do­no­harm.dev/version/1/1/license.html

J’ajou­te­rais proba­ble­ment la conven­tion de Genève, celle des droits de l’en­fant, peut-être un texte de portée simi­laire parlant d’éco­lo­gie (lequel ?), un lié à la vie privée, etc.

Ça reste flou mais ça permet de tout de même donner un cadre, surtout si on ajoute que l’in­ter­pré­ta­tion à donner à ces textes ne doit pas être moins stricte que celle de l’Eu­rope occi­den­tale de notre décen­nie.

Peu importe en réalité. Il s’agit de donner une inten­tion. Je n’ai pas cette préten­tion mais si l’ar­mée ou une corpo­ra­tion sans éthique veut réuti­li­ser mon code, ce n’est pas la licence qui les en empê­chera, flou ou pas.

Je ne prétends certai­ne­ment pas aller devant au tribu­nal. Ma seule arme est l’op­probre publique et le flou n’est ici pas un problème. La préci­sion juri­dique n’est pas un besoin. Au contraire, rester au niveau de l’in­ten­tion permet d’évi­ter les pirouettes en jouant sur les mots ou en trou­vant les failles. Quelque part la formu­la­tion de la licence JSON a ma préfé­rence, juste­ment pour ça.

Ça vous parait fou, irréa­liste, inap­pli­cable, mais combien d’entre nous auraient trou­vés la GPL raison­nable, réaliste et appli­cable à ses débuts ? Les débats n’ont d’ailleurs pas manqué.


Le seul vrai problème, à mon niveau, est bien celui du logi­ciel libre, et plus parti­cu­liè­re­ment de la GPL, incom­pa­tible avec toute autre licence qui fait des choix diffé­rents. Or la GPL est incon­tour­nable dans de nombreuses situa­tions, dans de nombreux contextes.

Une solu­tion pour­rait être de propo­ser une double licence : une licence basée sur l’éthique, tout en prévoyant une excep­tion qui permet de passer sur une AGPL au besoin.

Catégories
Développement web Sécurité informatique

Déve­lop­peurs, vous devriez avoir honte — Règles de mots de passe

Je rage à chaque fois que je saisis un mot de passe fort et que le site m’en­voie bouler parce que je n’ai pas de carac­tère autre qu’al­pha­nu­mé­rique.

Essayons quelque chose d’un peu plus smart pour évaluer la robus­tesse d’un mot de passe

Déve­lop­peurs, vous savez proba­ble­ment tout ça, mais conti­nuez à lire parce que la fin vous est adres­sée

Si j’en crois Hacker­noon on peut calcu­ler envi­ron 800 millions de SHA256 par seconde sur un maté­riel qui coûte 0,82 € par heure sur AWS. Ça fait 3,5 10^12 combi­nai­sons par euro.

Traduit autre­ment, voici le nombre de combi­nai­sons qu’on peut tester, et le même chiffre écrit en puis­sance de deux (arrondi à la déci­male infé­rieure) :

1 €3,5 × 10^122^41,6
10 €3,5 × 10^132^44,9
100 €3,5 × 10^142^48,3
1 000 €3,5 × 10^152^51,6
10 000 €3,5 × 10^162^54,9
100 000 €3,5 × 10^172^58,2

Quand on vous parle ailleurs de bits d’en­tro­pie, ça corres­pond à ces puis­sances de 2. Avec 1 000 € on peut tester toutes les combi­nai­sons de SHA 256 d’une chaîne aléa­toire de 51 bits.

Ok, mais ça me dit quoi ? Une lettre c’est 26 combi­nai­sons, envi­ron 4,7 bits. Si vous ajou­tez les majus­cules vous doublez le nombre de combi­nai­sons et vous ajou­tez 1 bit. Si vous ajou­tez les chiffres et quelques carac­tères spéciaux on arrive à à peine plus de 6 bits.

Petit calcul, en utili­sant juste les 26 lettres de l’al­pha­bet, on peut tester toutes les combi­nai­sons de 8 carac­tères pour moins de 1 €. Vu qu’on aura de bonnes chances de tomber dessus avant d’avoir testé toutes les combi­nai­sons, autant dire que même avec 9 carac­tères, votre mot de passe ne vaut pas plus de 1 €.

Combien faut-il de carac­tères pour se trou­ver rela­ti­ve­ment à l’abri (c’est à dire que la somme inves­tie ne peut pas tester plus de 1% des combi­nai­sons) ? Ça va dépendre de ce que vous y mettez comme types de carac­tères. J’ai fait les calculs pour vous :

a-za-z
A-Z
a-z
A-Z
0–9
a-z
A-Z
0–9
+-%
1 €11998
10 €111099
100 €12101010
1 000 €13111010
10 000 €14111111
100 000 €14121111

Et là magie : 8 carac­tères, même avec des chiffres, des majus­cules et des symboles, ça résiste tout juste à 1 €. Et encore, là c’est en partant du prin­cipe que vous choi­sis­sez réel­le­ment les carac­tères de façon aléa­toire, pas que vous ajou­tez juste un symbole à la fin ou que vous trans­for­mez un E en 3.

Vous voulez que votre mot de passe résiste à un voisin malveillant prêt à mettre plus de 10 € sur la table ? Prévoyez au moins 10 carac­tères.

Et là, seconde magie : Si vous mettez 10 carac­tères on se moque de savoir si vous y avez mis des chiffres ou symboles. La longueur a bien plus d’im­por­tance que l’éven­tail de carac­tères utilisé.


Main­te­nant que vous savez ça, tous les sites qui vous imposent au moins une majus­cule et un symbole mais qui vous laissent ne mettre que 8 carac­tères : Poubelle.

Je ne suis pas en train de vous apprendre à faire un mot de passe fort. Vous devriez utili­ser un gestion­naire de mots de passe et le géné­ra­teur auto­ma­tique qui y est inclus.

Je suis en train d’es­sayer de rendre honteux tous les déve­lop­peurs qui acceptent de mettre ces règles à la con sur les sites web dont ils ont la charge : Vous impo­sez des mots de passe qui sont à la fois imbi­tables et peu robustes.


Vous voulez faire mieux ?

Regar­dez dans quelle colonne est l’uti­li­sa­teur en fonc­tion des carac­tères qu’il a déjà tapé et donnez-lui un indi­ca­teur en fonc­tion de la longueur de son mot de passe.

  • Mot de passe refusé s’il est sur « Have I Been Pwned? »
  • Moins de 10 € ? mot de passe insuf­fi­sant, refusé
  • Moins de 100 € ? mot de passe faible, couleur rouge
  • Moins de 1 000 € ? mot de passe moyen, couleur orange
  • Mot de passe sûr, couleur verte, à partir de 10 000 €

Si vous gérez un site central, par exemple un réseau social public, vous pouvez proba­ble­ment rele­ver tout ça d’un cran.

Si ça donne accès à des données sensibles, à des possi­bi­li­tés d’achat, à la boite e-mail ou à l’opé­ra­teur télé­pho­nique, mieux vaux rele­ver tout ça de deux crans.

Le tout prend proba­ble­ment moins de 10 lignes en javas­cript. C’est une honte que vous accep­tiez encore d’im­plé­men­ter des règles à la con « au moins une majus­cule, un chiffre et un symbole, voici les symboles auto­ri­sés […] ».

Déve­lop­peurs, vous devriez avoir honte.

Catégories
Développement informatique

[code] Liste des imports

J’au­rais évité autant que possible il y a 15 ans, aujourd’­hui je suis amou­reux des import expli­cites en début de fichier, sans aucun symbole externe qui ne soit importé expli­ci­te­ment. Pas de symbole chargé ou défini dans un autre fichier magique­ment acces­sible ailleurs, pas même d’import *. Si je m’écou­tais en ce moment je voudrais même impor­ter les types de base du langage.

Mon histo­rique PHP et Ruby m’ont long­temps fait voir l’ab­sence de tout ça comme un avan­tage. Ça n’est vrai qu’a­vec de très bon IDE. En pratique ça ne permet pas de savoir où est défini le symbole, s’il existe vrai­ment, ni de gérer correc­te­ment les conflits de noms et surcharges locales.

Il y a souvent telle­ment peu de modules, classes et fonc­tions externes diffé­rentes dans un fichier bien struc­turé que l’ex­pli­cite apporte bien plus de béné­fices que de péni­bi­lité. Si on dépasse la dizaine c’est le symp­tôme que quelque chose ne va pas par ailleurs


Côté syntaxe j’ap­pré­cie celle de Python qui montre ce qui est impor­tant systé­ma­tique­ment en fin de ligne.

from xxx import A, B, C as D

Les imports Javas­cript sont pratiques mais la partie la plus signi­fi­ca­tive se retrouve en milieu de ligne, pas toujours là où c’est visuel­le­ment le plus iden­ti­fiable (sans comp­ter la dualité entre import A et import { A })


Soyons fous, on pour­rait même impor­ter les objets de base du langage avec un import { String, Integer, Array } from StdLib. On n’en utilise pas plus d’une poignée dans un même fichier. Point bonus si ça permet que "hello", 42, ou [1, 2, 3] soient des raccour­cis de syntaxe vers les classes ainsi décla­rées en haut de fichier et n’uti­lisent pas forcé­ment les classes natives du langage.

import { String, Integer } from Stdlib
import { MyArray as Array } from MaLibPerso
import { MACONSTANTE, MaClasse } from MonAutreLibPerso

Quitte à faire une liste de course, pour­rait-on faire que les imports avec un chemin absolu « /dir/sub/fichier » réfé­rencent la racine du projet et pas la racine du système de fichier ?

Catégories
CSS javascript React

Où je dis du bien du CSS-in-JS

Il n’y a que les imbé­ciles qui ne changent pas d’avis et c’est mon avis depuis toujours

Coluche

J’ai toujours regardé avec dédain les tenta­tives des dev JS pour contour­ner l’écri­ture de CSS mais je commence à consi­dé­rer que les outils de CSS-in-JS type Emotion sont la bonne solu­tion pour les webapp React.


J’ai été inté­gra­teur, à faire de la belle CSS sépa­rée du code HTML. On finit quand même vite par construire des monstres ou se prendre les pieds dans le tapis dès qu’on fait plus de quelques pages types.

Pour résoudre le problème, élimi­nons le. C’est ce que proposent les conven­tions comme BEM. Si je cari­ca­ture, il s’agit prin­ci­pa­le­ment de reti­rer les sélec­teurs CSS un attri­buant une ou plusieurs classes spéci­fiques à chaque contexte. C’est fran­che­ment moche mais ça fonc­tionne.

CSS-Modules va un peu plus loin. Le prin­cipe est le même mais on permet au déve­lop­peur d’uti­li­ser un nommage plus agréable. C’est l’ou­til de géné­ra­tion qui gère la complexité au lieu du déve­lop­peur.


J’avoue que j’aime bien CSS-modules. C’était mon favori jusqu’à présent.

Ça revient à juste gérer un fichier par compo­sant en se limi­tant à des sélec­teurs très simples pour ne pas créer de conflits de spéci­fi­cité. On reste sur du CSS stan­dard et sur une approche proche de mes habi­tudes histo­riques. Mieux : L’in­té­gra­tion peut se faire indé­pen­dam­ment du langage de déve­lop­pe­ment de l’ap­pli­ca­tif.

C’est top mais ça se base sur des compo­sants qui ne bougent pas beau­coup, dont on connait à l’avance tous les états.

Dès qu’il s’agit de cumu­ler plusieurs états, le résul­tat dépend de l’ordre d’écri­ture dans la CSS. Parfois c’est bien prévu, parfois non.

Dès qu’il s’agit de rendre des choses très dyna­miques, il faut de toutes façons sortir des CSS modules. Vous voulez que dans la vue large les items de navi­ga­tion se colorent au survol en fonc­tion de la caté­go­rie desti­na­tion déter­mi­née dyna­mique­ment mais qu’ils utilisent la couleur neutre dans la vue réduite desti­née aux mobiles ? Vous êtes à poil et il va falloir compo­ser avec d’autres façons d’injec­ter des CSS, peut-être même tâton­ner sur les prio­ri­tés entre classes.


Les classes utili­taires et CSS atomiques à la Tachyon sont là pour indus­tria­li­ser en pous­sant encore plus loin.

J’ai une classe par valeur à appliquer : .ms7-ns applique la septième valeur du cata­logue (7) comme taille hori­zon­tale maxi­mum (ms pour max-width) si la fenêtre a une taille supé­rieure au point de rupture « small » (ns pour non-small).

Ça n’offre quasi­ment aucune abstrac­tion utile (unifor­mi­ser les valeurs on a déjà plein d’ou­tils plus effi­caces). C’est vite cryp­tique, lourd, et mons­trueux dès qu’on multi­plie les valeurs et les points de rupture possibles.

Le seul inté­rêt par rapport à écrire direc­te­ment les attri­buts style c’est que ça permet d’ac­cé­der aux media query et aux pseudo-sélec­teurs.

Malheu­reu­se­ment non seule­ment ça ne résout pas les conflits de prio­ri­tés mais ça les empire. Si je spécia­lise un compo­sant exis­tant en y ajou­tant une classe liée à une direc­tive déjà présente, je joue à la roulette russe. Il faut abso­lu­ment que mon compo­sant initial prévoit lui-même tous les cas possibles pour savoir quelle classe injec­ter et ou ne pas injec­ter. Pas d’al­ter­na­tive.

J’ai vrai­ment l’im­pres­sion d’un retour en arrière mons­trueux avec ces CSS atomiques, cumu­ler les défauts sans aucun avan­tage, et c’est proba­ble­ment ce qui m’a fait reje­ter par prin­cipe les CSS-in-JS jusqu’a­lors.


Les CSS-in-JS c’est fina­le­ment pous­ser la logique de Tachyons un cran plus loin. Quitte à déci­der de tout dans le code HTML, autant écrire direc­te­ment les styles à cet endroit là en utili­sant la vraie syntaxe CSS et en y ajou­tant la possi­bi­lité d’ac­cé­der aux media query et aux pseudo-sélec­teurs.

Emotion c’est ça. On est à la croi­sée entre le « j’écris tout dans un attri­but style » et le « j’at­tache un module CSS ».

En fonc­tion­ne­ment basique c’est comme un CSS module sans le sélec­teur. Je donne les direc­tives en CSS on ne peut plus clas­siques et j’ai accès aux media query, aux pseudo-sélec­teurs et aux anima­tions avec une syntaxe proche de ce que font les prépro­ces­seurs habi­tuels (et en phase avec la direc­tion que prend la syntaxe CSS elle-même).

const style = css`
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
&:hover {
color: blue;
}
`

Je peux direc­te­ment ajou­ter le résul­tat aux classes CSS de mon compo­sant. Il se char­gera de géné­rer un nom de classe, de créer la CSS corres­pon­dante dans le docu­ment, et de lier les deux, comme avec CSS-Modules.

L’exemple est peu parlant. On a juste l’im­pres­sion d’un CSS-Modules écrit dans le fichier JS.

L’avan­tage c’est que je ne suis pas limité aux valeurs en dur. Je peux avoir des valeurs dyna­miques venant de mon Javas­cript ou de mon thème, et je n’en limite pas les effets à ce que me permettent les variables CSS.

Je peux aussi réuti­li­ser, compo­ser ou surchar­ger un élément ou un bloc de styles avec un autre sans risque de conflit de prio­rité.


Tachyons me donnait l’im­pres­sion de cumu­ler les incon­vé­nients, ici j’ai vrai­ment l’im­pres­sion de cumu­ler les avan­tages.

La seule contrainte c’est que mon code CSS se retrouve dans mes fichiers JS. C’est moche quand c’est dit ainsi mais pour une app en React, on a de toutes façons un fichier par compo­sant HTML et ça a du sens de grou­per HTML, JS et CSS lié au compo­sant ensemble quand ils sont forte­ment liés. C’est d’ailleurs le choix de VueJS.

Ce n’est forcé­ment pas adapté à tout, et si vous voulez rester géné­riques les CSS-Modules sont à mon avis l’op­tion la plus saine, mais pour un code React je crois que c’est là que je commen­ce­rai par défaut désor­mais.

Catégories
git

Les petits plus : gitup

J’ai toujours été gêné par l’in­té­gra­tion de grosses modi­fi­ca­tions dans git.

Dans l’idéal on fait une série de modi­fi­ca­tions auto­nomes, on les soumet à la revue des pairs puis on les intègre dans les branche prin­ci­pale qui peut partir en produc­tion à tout moment.

Ça c’est la théo­rie. En pratique je fais des erreurs que je ne vois qu’à la fin des modi­fi­ca­tions. Mes collègues auront de toutes façons des retours sur ce que j’ai poussé en ligne et me deman­de­ront des modi­fi­ca­tions avant l’in­té­gra­tion finale. Si ce n’est pas le cas au moins une fois sur deux, c’est que nous travaillons mal.

Et là… les ennuis commencent.

Mes modi­fi­ca­tions ne sont plus auto­nomes. J’ai des correc­tifs à la fin. Poten­tiel­le­ment mes modi­fi­ca­tions précé­dentes sont donc incom­plètes, de mauvaise qualité ou même défaillantes. Si j’in­tègre mon code à la fin de la revue, je casse toute la belle théo­rie.

J’ai vu deux pratiques suivant les équipes :

La première pratique c’est d’in­té­grer le code tel quel sur la branche master. C’est ce qui m’ap­pa­rait le plus cohé­rent. Le code de la branche est poten­tiel­le­ment instable mais tous les points d’étape de master sont de qualité. Pour parcou­rir les modi­fi­ca­tions de la branche master on ajoute --merges --first-parent histoire de ne pas voir les modi­fi­ca­tions internes des sous-branches. Ni vu, ni connu mais le débo­gage de la branche après coup en cas de besoin ne sera pas idéal.

L’al­ter­na­tive est de fusion­ner en une seule toutes les modi­fi­ca­tions de la branche lors de son inté­gra­tion. On perd toute la granu­la­rité et ça peut rendre bien plus diffi­cile de tracer l’ori­gine d’une anoma­lie par la suite, ou de comprendre le pourquoi et le comment d’un chan­ge­ment. C’est encore viable sur 100 voire 200 lignes bien grou­pées mais ça devient fran­che­ment liti­gieux au delà.

La seule pratique que je réprouve tota­le­ment est celle du rebase sans squash. On importe tous les chan­ge­ments direc­te­ment sur master et on perd tota­le­ment la capa­cité d’avoir un master stable. Ne faites pas ça.

La troi­sième voie c’est la réécri­ture de l’his­to­rique.

En théo­rie c’est mal, au moins pour les branches déjà publiées. En pratique tant qu’au­cun autre code ne se base dessus, ça ne pose pas vrai­ment de problèmes. Sur des équipes en entre­prise ça se maitrise assez bien. Sur du code open source ça me semble plus liti­gieux. Github le gère parfai­te­ment dans les pull-request en cours de revue.

Les vrais, les purs, le font en ligne de commande. Je suis admi­ra­tif devant ceux qui savent décou­per une modi­fi­ca­tion ou ajou­ter un correc­tif dix chan­ge­ments en arrière dans l’his­to­rique sans réflé­chir ni tout casser. Tech­nique­ment ça ne pose pas vrai­ment de diffi­cul­tés mais c’est long, propice aux erreurs, et le moindre faux pas peut faire de gros dégâts irré­mé­diables. Je ne trouve pas les inter­faces graphiques inutiles pour tout ça.

Et là, merci Patrick, gitup vient désor­mais à ma rescousse. L’in­ter­face est simpliste, pas toujours pratique, mais elle fait ce que je n’ai pas vu ailleurs.

  • Je suis capable de sépa­rer un chan­ge­ment en deux quelle que soit sa posi­tion dans l’his­to­rique ;
  • Je suis capable de dépla­cer un chan­ge­ment en haut ou en bas dans l’his­to­rique d’un simple raccourci clavier ;
  • Je suis capable de faire un correc­tif, le descendre dans l’his­to­rique, puis le fusion­ner avec le chan­ge­ment initial qu’il faut corri­ger.

Tout ça graphique­ment, avec la possi­bi­lité de reve­nir en arrière quand je veux si jamais je fais des bêtises.

Catégories
Méthodes agiles scrum

Les esti­ma­tions de petites tâches ne sont pas plus précises

Un des premiers mensonges qu’on vous livre trop souvent avec SCRUM c’est qu’on peut esti­mer des petites tâches avec bien plus de préci­sion que des grandes, et qu’en consé­quence on peut être assez fiable dans l’es­ti­ma­tion des une à trois semaines de chaque itéra­tion.

Foutaises !

Combien de temps faut-il pour mettre les blou­sons avant d’al­ler à l’école ? Mettons 30 secondes si on ne se presse pas. La réalité c’est que ça mettra plus souvent 5 minutes que 30 secondes, et ça c’est si on n’a pas besoin de se battre.

400% de marge d’er­reur ? Comment voulez-vous faire un plan­ning avec de telles esti­ma­tions. Pour­tant on est sur une tâche connue, répé­tée chaque jour. Seule solu­tion, on triche et on compte 2 minutes 30. Même ainsi on a une marge d’er­reur de 100%. Hallu­ci­nant !

Ce n’est pas un exemple choisi. J’ai le même problème pour termi­ner la tartine, pour boire le verre d’eau ou pour passer aux toilettes avant de partir, pour descendre dans la rue, pour faire le trajet, pour trou­ver le badge et passer le portail de l’école, pour montrer ma carte au vigile, pour les 10 mètres dans l’école au milieu des copains et autres parents d’élèves, pour le bisou de bonne jour­née avant de pouvoir repar­tir…

Ce n’est pas non plus la faute d’une mauvaise analo­gie. Esti­mer une petite tâche est juste impos­sible parce que le moindre aléa fait tout explo­ser.

Ajou­ter un lien sur une page ça prend 30 secon­des… sauf si on vous dit de chan­ger l’URL au dernier moment et qu’il faut faire deux fois le travail, sauf si c’est le seul lien à cet endroit et qu’il faut retou­cher les règles de style, sauf si le lien passe à la ligne en plein milieu et que visuel­le­ment ça ne le fait pas du tout sur ce compo­sant, sauf si l’es­pace pris fait glis­ser le bouton qui suit sous le clavier sur un smart­phone une fois le clavier déplié, sauf s’il faut partir à la chasse de la bonne URL parce que c’était « ça n’a pas d’im­pact, on donnera le lien au dernier moment », sauf si on se rend compte qu’il faut mutua­li­ser ce lien avec autre chose ailleurs dans l’ap­pli­ca­tion, sauf si ajou­ter un lien casse le test end-to-end et qu’il faut le réécrire pour faire passer le serveur d’in­té­gra­tion conti­nue au vert, sauf si… pour un simple foutu lien !


Et pour­tant, on n’est jamais en retard à l’école. Malgré les aléas infi­nis à chaque tâche, le projet « aller à l’école » prend 45 minutes à ±15 minutes. Pas plus.

Ce n’est même pas qu’es­ti­mer le projet dans son ensemble permet de lisser les risques de déra­pages, c’est que le temps que prend chaque tâche dépend de toutes les tâches précé­dentes et des options qu’il nous reste pour les suivantes.

S’il faut lutter pour termi­ner le crois­sant alors on active sérieu­se­ment la suite. Si les toilettes s’éter­nisent je prépare le blou­son et le bonnet pendant ce temps. S’il le faut on presse un peu le pas. À l’école, si on arrive dans les derniers, aucun parent d’élève ou cama­rade ne nous retient dans les dix derniers mètres et le bisou sera vite fait. Si vrai­ment on est super en retard on peut toujours sortir le vélo ou prendre le tram.


En réalité si SCRUM estime les fonc­tion­na­li­tés unitaires ce n’est pas pour s’en­ga­ger sur un résul­tat donné à l’avance, ni même pour mesu­rer si l’ité­ra­tion a été une réus­site ou un succès lors de la rétros­pec­tive. C’est unique­ment pour savoir où on va dans la boîte de temps qu’on s’est donnée. Rien de plus.

Quand on vous dit que ça permet d’être plus fiable, derrière se cache l’hydre du « on va trans­for­mer vos esti­ma­tions en enga­ge­ment » voire du « on va ajou­ter vos esti­ma­tions une à une et ça donnera la dead­line de fin de projet si rien ne change ».

Catégories
Développement informatique javascript Sécurité informatique

Une histoire de dépen­dances

Le main­te­neur d’un paquet NPM n’a plus eu envie et a donné la main à un tiers. Ce tiers a injecté un code mali­cieux dans une version publique et poten­tiel­le­ment infecté pas mal de monde. Ça n’a été détecté qu’au bout de deux mois et demi alors que le paquet est utilisé un peu partout.


J’en vois qui lancent des blâmes ou qui se moquent sur l’ac­tua­lité du paquet NPM mali­cieux. Ça défoule mais : Faites-vous mieux ? Permet­tez-moi d’en douter très très forte­ment.

Le moindre projet React, Symfony ou Rails, c’est une centaine de dépen­dances directes et indi­rectes, certaines proviennent de sources dont vous n’avez jamais entendu parler. J’ai listé trois frame­works mais c’est bien la même chose sur les autres langages/tech­nos.

C’est bien le sujet : Sauf si vous avez la taille d’un Face­book/Google ou la criti­cité d’un Thalès ou d’un état, vous n’avez ni les moyens de passer des années-homme à tout reco­der en interne, ni les moyens d’au­di­ter chaque source à chaque mise à jour (si tant est que ça suffise).

Même ceux que j’ai nommé, je ne suis pas certains qu’ils le fassent toujours, sur tous les types de projet. Je suis même assez convaincu du contraire. Le ratio béné­fice/risque n’est juste pas assez impor­tant pour ça. Les moyens et les délais ne sont pas dimen­sion­nés pour.


Alors moquez-vous, de ceux qui utilisent NPM, de ceux qui ne contrôlent pas l’en­semble des dépen­dances, mais vous ne faites proba­ble­ment pas mieux. Il y a pas mal d’hy­po­cri­sie dans les réac­tions que je vois passer.

Ne blâmez pas non plus le main­te­neur d’ori­gine. Lui ne vous a jamais rien promis. C’est même dit expli­ci­te­ment dans la licence « aucune garan­tie d’au­cune sorte ». Ce n’est pas parce que d’autres utilisent son code gratui­te­ment qu’il aurait magique­ment des comptes à rendre. En fait avoir passé la main est plutôt quelque chose d’en­cou­ragé dans l’open source. S’il n’y avait pas eu cette issue, il aurait plutôt fallu le remer­cier.


Alors quoi ? Alors rien.

Le problème a été résolu. Si ça arrive trop souvent alors ça chan­gera le ratio béné­fice/risque et la commu­nauté évaluera le fait d’avoir trop de dépen­dances tierces un (tout petit) peu plus néga­ti­ve­ment, et ainsi de suite.

La ques­tion inté­res­sante que personne ne semble poser c’est celle de l’hon­nê­teté du main­te­neur d’ori­gine. A-t-il vrai­ment passé la main ? et s’il l’a fait, est-ce qu’il en a tiré un béné­fice tout en soupçon­nant ce qui pouvait se passer ? C’est à peu près la seule chose qui pour­rait à mon sens lui faire porter une quel­conque respon­sa­bi­lité.

Catégories
Droit d'auteur Livre PHP Vie personnelle

« PHP 5 avancé » en chiffres

Je vois les auteurs racon­ter leur histoire, leurs rému­né­ra­tions. Je n’ai pas trop envie de m’y mélan­ger vu que je n’ai jamais été auteur profes­sion­nel ni n’ai jamais cher­ché à l’être. Mes enjeux d’au­teur du dimanche sont bien diffé­rents. Ajou­tez y que j’ai écrit dans à propos de tech­nique infor­ma­tique, très loin des auteurs de romans et de bande dessi­née.

Pour autant, c’est aussi l’oc­ca­sion parce que je ne crois pas avoir déjà fait un tel bilan. Peut-être que ça inté­res­sera certain d’entre vous. Dites-moi s’il y a des ques­tions auxquelles je ne réponds pas.

Atten­tion, ce n’est repré­sen­ta­tif de rien d’autre que de mon cas person­nel. J’ai même tendance à penser que mon histoire entre dans l’ex­cep­tion à plus d’un titre. Le fait qu’il y ait des gros chiffres dans la suite ne doit certai­ne­ment pas vous amener à penser que les auteurs roulent habi­tuel­le­ment sur l’or.

Six éditions et quatre colla­bo­ra­teurs

Travail à quatre mains avec Cyril Pierre de Geyer. Le premier chapitre a été fait en février 2003 pour une publi­ca­tion de 700 pages en juin 2004.

PHP a pas mal évolué et le livre serait rapi­de­ment devenu obso­lète. Nous avons du mettre à jour le livre régu­liè­re­ment. Il y a eu une édition par an jusqu’en 2008 puis une sixième de 870 pages en 2012.

La troi­sième édition a été reti­rée sur un format « best-of » en 2007, en paral­lèle de la vente de la quatrième dans son format d’ori­gine. J’avoue que ça me semble toujours étrange, d’au­tant que si nous en avons fait une quatrième édition plutôt qu’un reti­rage c’est que l’évo­lu­tion de PHP rendait l’an­cienne version moins perti­nente.

Nous avons été épaulé par Hugo Hamon pour les relec­tures et l’in­dexa­tion de la cinquième édition. La sixième édition a été parta­gée avec un troi­sième auteur, Frédé­ric Hardy. Il est en petit sur la couver­ture, je le regrette aujourd’­hui.

Les tirages et les ventes

Le premier tirage était prévu à 3000 exem­plaires. Vus les chiffres de vente je suppose qu’il en a plutôt été tiré 3200 (ou alors on a vendu des livres qui n’exis­taient pas). Les chiffres des éditions suivantes ne tombant même pas proches de multiples de 250, j’ima­gine qu’on en imprime toujours un peu plus au cas où et que le chiffre final n’est pas tota­le­ment maitri­sable.

La seconde édition a été tirée à envi­ron 3700 exem­plaires, la troi­sième et la quatrième ont toutes les deux fait entre 3200 et 3300 exem­plaires, plus envi­ron 4000 exem­plaires pour la best-off. La cinquième a béné­fi­cié de deux tirages, proba­ble­ment respec­ti­ve­ment 3400 et 2000 exem­plaires. La dernière a été tirée à quelque chose comme 3800 exem­plaires, proba­ble­ment en deux fois.

Au total j’ai quelque chose comme 26 500 ventes sur les 12 ans de vie du livre.

Le travail d’écri­ture

Diffi­cile d’es­ti­mer le temps passé en écri­ture tant il était très frac­tionné, d’au­tant que ce n’était pas mon acti­vité prin­ci­pale. Sur les 16 mois de travail de l’édi­tion initiale, j’ai quand même du y passer une bonne majo­rité des soirs et week-end, et quelques mois quasi­ment à temps plein. À cela il faut bien entendu ajou­ter le travail de mon co-éditeur.

Chose éton­nante pour moi, nous n’avons pas utilisé de logi­ciel ou de format de fichier spéci­fique à l’édi­tion, juste du Micro­soft Word avec une feuille de styles interne : un fichier par version et par chapitre nommé d’après l’au­teur a avoir créé la version, le tout dans un FTP.

Les autres éditions ont été un effort variable, plus fort pour les premières que pour les dernières. On parle quand même géné­ra­le­ment de plusieurs mois pendant des soirs et des week-ends.

Je n’ai aucune idée du travail total en équi­valent temps plein 35h sala­rié. Si je devais donner un chiffre je dirais proba­ble­ment un an équi­valent temps plein sala­rié, mais en réalité ça peut faci­le­ment être la moitié moins ou moitié plus.

Malgré la moti­va­tion des premiers temps, faire ça en paral­lèle d’un job très prenant n’est pas aisé, surtout au moment des relec­tures. La colla­bo­ra­tion entre auteurs n’a pas toujours été évidente non plus. Ça parait évident après coup mais écrire à deux quand on ne se connait pas vrai­ment et qu’on ne se voit jamais en face à face, c’est forcé­ment un peu diffi­cile.

La rému­né­ra­tion

La rému­né­ra­tion est de 10% du hors taxe pour les ventes françaises grand format (4% sur les ventes à l’étran­ger, 5% sur le format poche — l’édi­teur a souhaité en sortir un une année, nous avons refusé), à parta­ger entre les auteurs initiaux, sans aucune avance, sur des livres qui ont varié de 35 à 45 € pour la collec­tion prin­ci­pale, 25 € pour le best-of.

Même en allant cher­cher dans les archives, je suis encore aujourd’­hui inca­pable de dire combien j’ai gagné que ce soit en net ou en brut. J’ai des comptes de vente, des détails de coti­sa­tions, des avis de paie­ment et des résu­més de sommes à décla­rer au fisc. Rien ne se recoupe vrai­ment, quand je n’ai pas deux docu­ments d’un même type tota­le­ment diffé­rents pour une même année.

Disons que la somme encais­sée avant impôts sur le revenu doit être entre 40 et 47 000 euros nets depuis le premier verse­ment en 2005. Précis hein ?

Ramené à un an de travail c’est effec­ti­ve­ment très bien payé, surtout par rapport à ce que je lis à propos de auteurs en litté­ra­ture, en jeunesse ou en bande dessi­née. Même dans la four­chette haute, en comp­tant deux ans de travail en équi­valent temps plein, ça reste bien au dessus du SMIC. Cela dit il était loin d’être dit que ça rému­nè­re­rait autant, et ce que ça m’a apporté a large­ment dépassé le finan­cier. Je ne pensais pas à l’argent. Je ne m’étais en fait même pas fait de prévi­sion quand j’ai dit oui, et je n’au­rais pas su dire si je m’at­ten­dais à 1 000 ou 10 000 euros.

Cette somme est après paie­ment de la TVA, de la CSG et CRDS, ainsi que d’une coti­sa­tion de 1% à l’Agessa. Tout ça est prelevé pour moi en amont par l’édi­teur. Pas de retraite, pas de prévoyance, et avec dans les 4000€ par an en moyenne je n’au­rais proba­ble­ment eu aucune couver­ture sociale si je n’avais pas eu un emploi sala­rié en paral­lèle.

Pour l’im­pôt sur le revenu je déclare ce que l’édi­teur me dit en trai­te­ments et salaires. C’est peut-être idiot ou anor­mal, je n’ai jamais su (on m’a donné des réponses diffé­rentes à chaque fois que je deman­dais ce que devait faire un auteur de loisir) mais du coup c’est imposé sur le barème progres­sif.

Autant Hugo (en relec­teur) que Frédé­ric (en co-auteur sur la dernière mise à jour) ont été rému­né­rés sur une base fixe, payée par l’édi­teur en plus de nos droits d’au­teur.

L’édi­teur

J’en­tends beau­coup de choses sur les éditeurs. Person­nel­le­ment moi j’ai plutôt eu une très bonne expé­rience d’Ey­rolles. Muriel, tu as été vrai­ment super, Karine aussi, et j’ou­blie certai­ne­ment des gens. Je n’ai eu à me plaindre de personne, au contraire.

Si je devais repro­cher quelque chose, c’est le refus total de consi­dé­rer une durée limi­tée pour la version numé­rique du livre. Je crains cepen­dant qu’il en soit de même pour l’es­sen­tiel des éditeurs et mon co-auteur a de toutes façons refusé toute vente numé­rique par peur du pira­tage (qui a tout de même eu lieu, visi­ble­ment par des fuites des PDF internes desti­nés à l’im­pri­meur, avec les marques de découpe). Oh si, si je devais pinailler, il y a briè­ve­ment eu une mise en vente de la quatrième édition sous forme numé­rique malgré le refus expli­cite au contrat, mais ils y ont mis un terme quand on l’a fait remarquer.

Je ne m’éten­drai pas sur ce point mais on a même eu une diffi­culté de répar­ti­tion des droits entre co-auteurs à un moment. Non seule­ment l’édi­teur a aidé à sa réso­lu­tion mais il a aussi pris le diffé­ren­tiel à sa charge pour solder le passé. Ok, vu les ventes ils pouvaient se le permettre, mais rien ne les y obli­geait non plus.

PHP 7 avancé

Aujoud’­hui PHP 5 avancé n’existe plus. Il y a eu réécri­ture partielle pour construire PHP 7 avancé mais consi­dé­rant les diffi­cul­tés de colla­bo­ra­tion, on a décidé de ne pas forcé­ment le refaire ensemble. Je suis toujours sur la couver­ture en grisé mais j’ai passé la main aux excel­lents Pascal Martin et Julien Pauli, au moins pour les deux premières éditions (la seconde arrive parait-il sous peu).

Catégories
Équipes Méthodes agiles Objectifs

Story points

Points de complexité, points d’ef­fort, tailles de tshirt… J’ai vu des équipes travailler avec des comp­tages allant d’une mesure en heures de travail à des mesures au simple nombre de tickets.

Je n’ai pas trouvé de réelle corré­la­tion entre la réus­site des équipes et leur façon d’es­ti­mer, ou même avec l’exis­tence ou non d’es­ti­ma­tions.

Si je devais trou­ver un critère commun à la majo­rité des équipes que j’ai vu bien fonc­tion­ner, le voilà :

Les esti­ma­tions de tâches indi­vi­duelles sont réali­sées au lance­ment du travail. Elles ne sont pas utili­sées au-delà de la courte période de travail concer­née pour laquelle elles étaient prévues. Elles ne sont pas utili­sées en dehors de l’équipe ou de son fonc­tion­ne­ment interne.


Déci­der. On estime les epic, ces gros blocs qui recoupent géné­ra­le­ment plusieurs semaines voire plusieurs mois. Ces epic servent à faire des choix, déci­der de l’op­por­tu­nité de réali­ser, confron­ter les prio­ri­tés, savoir s’il est réaliste d’at­teindre l’objec­tif avant un événe­ment parti­cu­lier. Dans tous les cas on parle de stra­té­gie et de tactique.

Les points de complexité n’ont aucun sens à ce niveau. On a juste besoin d’un ordre de gran­deur. Les esti­ma­tions se font au doigt mouillé et c’est très bien comme ça. 30% de marge d’er­reur c’est presque de la surqua­lité.

Ces esti­ma­tions n’ont aucune valeur en dehors de la prise de déci­sion. Le péri­mètre n’est pas vrai­ment défini, la tech­nique en est à l’étude de faisa­bi­lité et aux pistes tech­niques crédibles ou non.


Réagir. Et puis à partir de là on passe éven­tuel­le­ment en réali­sa­tion. Mesu­rer l’avan­ce­ment permet de ne pas se perdre, d’iden­ti­fier les blocages, de se rendre compte quand on patauge. C’est ce qui permet éven­tuel­le­ment de dire « on a un problème, il faut chan­ger quelque chose » ou « l’ordre de gran­deur qui a mené à la déci­sion de réali­sa­tion se révèle faux, est-ce qu’on conti­nue ou pas ? ».

On peut mesu­rer en fonc­tion d’es­ti­ma­tions de travail ou en fonc­tion de ce qui est livré à la sortie. Les deux ont du sens et je vous invite à faire les deux. Côté scrum on parle de la burn-down qui trace le travail, limité à une itéra­tion ou à une date butoir, et la burn-up qui trace la valeur produite sur du plus long terme.

Ces esti­ma­tions ne servent qu’à ça, iden­ti­fier d’éven­tuels problèmes pour agir en fonc­tion. Elles ne servent pas à savoir si l’équipe travaille bien ou pas. Ce sont de sacré­ment mauvais indi­ca­teurs pour ça.


Et donc les problèmes arrivent quand on croise les deux.

Les esti­ma­tions et les plans ne sont pas faits pour mesu­rer le succès et le travail d’une équipe. Il sont faits pour déci­der et réagir. Rien de plus.

Un plan long terme ne se construit pas en jouant au puzzle à agen­cer plein de petits blocs ensemble pour les caser dans l’agenda. Ça ne fonc­tionne déjà pas pour les tâches de pure exécu­tion, parce que 18 tâches de 10 minutes ne prennent pas le même temps qu’une tâche de 180 minutes.

Ça fonc­tionne encore moins dès qu’il y a une acti­vité de réflexion, de créa­tion, ou simple­ment l’in­ven­tion de quelque chose qui n’existe pas. On ne connait pas tout à l’avance, le puzzle sera explosé avant d’avoir atteint le premier quart. C’est vrai autant d’un point de vue fonc­tion­nel que tech­nique.

Mais surtout, le plan est fait pour être changé. Mesu­rer la réalité par rapport au plan c’est dire que le chan­ge­ment et l’im­prévu doivent être vali­dés en amont, qu’ils sont anor­maux, qu’en que si la réalité ne corres­pond pas au plan c’est la réalité qui a tort et que le problème se situe donc au niveau de ceux qui suivent le plan.

Malheu­reu­se­ment essayer de tordre ou de contes­ter la réalité ne fonc­tionne que à ma connais­sance que dans les livres et les films de science-fiction (et encore : même là, en géné­ral, on a les problèmes qui nous sautent au visage dès qu’on essaie).

Par­fois il y a aussi des problèmes au niveau de ceux qui suivent le plan, mais savoir si la réalité est conforme au plan est tout sauf le bon indi­ca­teur pour ça.

Catégories
javascript navigateurs et API Sécurité informatique

Comment on fait de la crypto dans le navi­ga­teur ?

Faire de la cryp­to­gra­phie dans le navi­ga­teur se révèle bien plus simple que prévu.

Lais­sez tomber les portages de libso­dium & co. Quasi­ment tous les navi­ga­teurs supportent désor­mais une API native dédiée. Seul IE11 ne le fait pas tota­le­ment mais il a au moins le mini­mum qu’est la géné­ra­tion de nombres réel­le­ment aléa­toires. Ceux qui veulent vrai­ment pour­ront complé­ter l’im­plé­men­ta­tion d’IE11 avec un poly­fill sans risquer de problème de sécu­rité.

Il y a plein de jolis exemples sur qnimate mais certaines choses datent un peu. J’ai tenté de résu­mer ici pour ceux que ça inté­resse. Ici pour du déchif­fre­ment à partir d’une clef secrète.

Avant-propos

Je ne suis pas un expert en chif­fre­ment et ce genre de choses est toujours à manier avec précau­tion. Si vous faites quelque chose de sérieux, ne vous conten­tez pas d’exemples et embau­chez quelqu’un qui sait.

Rien que choi­sir l’al­go­rithme perti­nent demande de savoir ce qu’on fait. AES-CTR semble perti­nent pour mon cas d’usage où n’ai pas besoin de véri­fier l’au­then­ti­cité du message, où je n’ai pas envie de me colti­ner les ques­tions de padding, et où je serai heureux de profi­ter des multiples cœurs des smart­phones.

Si l’al­go­rithme choisi ou autre chose vous dérange et que vous en savez plus que moi, n’hé­si­tez pas à commen­ter.

Récu­pé­rer une clef

Le plus simple est de récu­pé­rer direc­te­ment une clef au format JSON Web Key (en gros la clef en base64url plus un peu de méta­don­nées). Dans ce cas il suffit de passer par importKey :

const crypto = window.crypto.subtle;

const jwk = {
  "kty": "oct",
  "use": "enc",
  "k": "SDRSTgdOpUGfgn3iAwiC1cpzsevLM98r_6ehMXlK1Gk",
  "alg": "A256CTR"
};
const algo = {name: "AES-CTR"};
const exportable = false;
const usage = ["decrypt"];

const key = await crypto.importKey("jwk", jwk, algo, exportable, usage);
Déri­ver une clef

Si on veut partir d’une phrase secrète mémo­ri­sable et non d’une clef complète, on commence par créer une clef tempo­raire et on utilise un algo­rithme de déri­va­tion comme PBKDF2.

Malheu­reu­se­ment pour créer cette première clef il faut passer par un TextEn­co­der et ArrayBuf­fer. peut toujours déri­ver la clef à partir de là. TextEn­co­der n’existe pas sous Edge et IE11, il vous faudra utili­ser une fonc­tion comme uniba­bel qui fait ça pour vous.

const crypto = window.crypto.subtle;
const encoder = TextEncoder();

const passphrase = "l'eau ça mouille, le feu ça brûle";
const buffer = encoder.encode( passphrase );
const d_algo =  {name: 'PBKDF2'};
const d_exportable = false;
const d_usage = ['deriveBits', 'deriveKey'];
const d_key = await crypto.importKey('raw', buffer, d_algo, d_exportable, d_usage);

const deriv = { 
  name: 'PBKDF2',
  salt: encoder.encode( "c'est le week-end !" ),
  iterations = 25,
  hash: 'SHA-256',
};
const algo = {name: "AES-CTR", length: 256}; 
const exportable = false; 
const usage = ["decrypt"];

const key = await crypto.deriveKey(deriv, d_key, algo, exportable, usage);

La sécu­rité de tout ça dépend de la longueur et de l’uni­cité de votre phrase secrète initiale. À vous de trou­ver le bon compro­mis entre la sécu­rité et la puis­sance des smart­phones qui risquent d’uti­li­ser votre code. Le 25 ici est pure­ment arbi­traire et le temps de calcul néces­saire est propor­tion­nel.

Déchif­frer

Déchif­frer n’est pas plus diffi­cile.

Le vecteur d’ini­tia­li­sa­tion (iv) et la donnée chif­frée (encryp­ted) sont atten­dus sous forme d’Ar­rayBuf­fer. Il faudra de nouveau passer par uniba­bel ou une autre solu­tion si vous avez ça sous forme de chaîne binaire ou codé en base64.

Le résul­tat de decrypt() vous est retourné sous la même forme. S’il est petit le plus simple est d’uti­li­ser TextDe­co­der ou uniba­bel. Si vous avez quelque chose de plus volu­mi­neux vous pouvez aussi passer par un Blob et un FileRea­der.

const crypto = window.crypto.subtle;
const decoder = TextDecoder

const key = ...
const iv = ...
const encrypted = ...

const algo = { name: 'AES-CTR', iv: iv }
const buffer = await crypto.decrypt(alg, key, encryted);