Créer plusieurs dossiers en une seule commande

La création de dossiers peut être fastidieuse lorsqu’il faut répéter les commandes encore et encore. Heureusement, il est possible de créer de multiples dossiers en une seule commande.

mkdir -p /opt/{Signal,jetbrains/{clion,idea,pycharm}}

Il est important de ne pas oublier l’option -p puisque c’est elle qui permet cette magie. Elle permet en effet la création des dossiers parents s’ils n’existent pas.

Avec cette commande, les dossiers Signal et jetbrains seront créés dans le dossier /opt et les dossiers clion, idea et pycharm seront créés dans /opt/jetbrains.

Connaître le chemin absolu d’un script à l’intérieur de celui-ci

On utilise ici une particularité de bash donc attention si vous n’utilisez pas le même shell.

La prise de variable se fait comme ceci :

DIR_SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null 2>&1 && pwd)"

Découpons tout ceci.

Premièrement, DIR_SCRIPT est le nom de la variable que nous pourrons utiliser ensuite.

Ensuite, $(cd "$(dirname "${BASH_SOURCE[0]}")" que nous allons découper en plusieurs parties.
– La plus importante à comprendre : ${BASH_SOURCE[0]}
C’est ici que se joue la particularité à bash de ce script. BASH_SOURCE[0] (ou BASH_SOURCE) contient le chemin (potentiellement relatif) du script qui y fait appel dans tous les scénarios d’invocation possible. Ceci inclue lorsque le script est sourcé, ce qui n’est pas le cas de $0 communément utilisé. $0 est un composant de la spécification POSIX pour les shell alors que BASH_SOURCE, comme son nom l’indique, est spécifique à bash.
– Ensuite dirname permet d’enlever le dernier composant du nom du fichier
– Finalement, cd redirige le script dans ce dossier identifié

Nous redirigeons ensuite avec > /dev/null 2>&1 toute erreur d’affichage ou tout affichage vers /dev/null.

Enfin, nous exécutons pwd dans le nouvel emplacement où nous nous trouvons afin d’en récupérer le chemin absolu. Le résultat de toutes ces opérations est ensuite stocké dans notre variable DIR_SCRIPT.

VTFFAAS – Projet Python

Cela commençait à faire quelques temps que je n’avais pas réellement codé car j’avais surtout tendance à faire du système ou du réseau. Du coup, pour les besoins d’une présentation dans le cadre du Laboratoire Web de mon école, je me suis penché sur les possibilités qu’offrait Python dans le développement Web.

J’ai commencé par regarder les possibilités qu’offrait python seul puis je suis passé à des micro-framework comme Bottle Py ou Flask. Je n’ai pas encore poussé les recherches jusqu’à Django qui supporte enfin la version 3 de Python.

J’ai donc voulu me faire un petit POC pour cette présentation et j’ai réfléchis à ce que je pouvais faire qui soit assez parlant. Il en est ressorti ceci : http://vtffaas.com/

Va Te Faire Foutre As A Service est une plateforme conçue pour permettre facilement de dire à quelqu’un d’aller de se faire foutre.

Le principe de cette plateforme est simple, différents messages sont pré-configurés et on peut les appeler en modifiant certaines variables directement depuis l’URL. Un raccourcisseur d’URL va bientôt être intégré sur la plateforme.

Mine de rien, même si l’utilité d’une telle plateforme est bien évidemment discutable, au niveau du panel d’options vues, elle est très intéressante. J’ai ainsi pu voir les redirections, la manière de traiter les fonctions Python en fonction des appels Web, les connexions à la base de données, les déploiements standalone comme au travers d’Apache, …

En tout cas, Python, bien qu’encore handicapé par le méli-mélo permanent qu’est l’existence de 2 versions non compatibles entre elles du langage, offre des possibilités et des temps de réponse parfaitement adaptés au Web.

Fenêtre maximisée en JAVA

Lors de l’initialisation d’une fenêtre (JFrame) en JAVA, on commence habituellement par définir son titre, sa taille et sa position sur l’écran. Cependant, dans certains cas, on peut vouloir la faire apparaître maximisée à l’écran sans que l’utilisateur n’ait à appuyer sur le bouton de maximisation.

Ceci se fait simplement en procédant comme suit :

import java.awt.HeadlessException;
import javax.swing.JFrame;

public class Frame extends JFrame {

    public Frame() throws HeadlessException {
        this.setTitle("Maximized");
        this.setSize(800,600);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);
        this.setVisible(true);
    }
}

C’est la ligne

this.setExtendedState(this.getExtendedState() | JFrame.MAXIMIZED_BOTH);

qui permet d’obtenir l’effet voulu. On peut aussi choisir de maximiser sa fenêtre dans un sens ou dans l’autre à l’aide des variables MAXIMIZED_HORIZ et MAXIMIZED_VERT.

Activer les numéros de ligne dans PyCharm

Python est réellement un langage fantastique mais je n’ai toujours pas trouvé d’IDE aussi performant que je le souhaiterais. Celui à l’heure actuel qui s’approche le plus de ce que je recherche dans un IDE est PyCharm. Celui ci n’affiche cependant pas de base les numéros de ligne dans les pages de code. Même si ceci n’est pas d’une utilité absolue, c’est un confort que j’apprécie et un point de repère efficace.

Il y a deux manières d’activer les numéros de ligne. La première manière n’active l’affichage que sur la page en cours. Pour cela, faire un clic droit dans la petite bande à gauche de la page de code, avant la colonne d’affichage, et sélectionner « Show Line Numbers« .

La deuxième solution est plus globale puisqu’elle active par défaut l’affichage des numéros de ligne. C’est celle ci que j’ai choisi pour ma part. Pour ceci, il faut aller dans Files -> Settings -> IDE Settings -> Editor -> Appearance et cocher l’option « Show Line Numbers »

La descriptions des différentes options disponibles de cette page peut être trouvé sur la page d’aide de JetBrains correspondante.

Comparer le type d’un objet en Java

Il peut être intéressant dans certains cas de stocker différents types d’objets dans une ArrayList. Ceci implique que tous les objets aient un niveau d’abstraction supplémentaire pour être contenus dans cette liste. Le problème va être d’identifier chaque type d’objet lorsque l’on voudra les sortir de cette liste.

Prenons un exemple concret. Nous souhaitons créer un objet « Carte » qui peut contenir un « Nom« , un « Prenom » et plusieurs « Email » tous héritant de la classe « ElementCarte« . Ne sachant pas quels éléments seront ajoutés à la carte, il est plus simple de créer une ArrayList de « ElementCarte » dans laquelle se trouveront les différents éléments.

Le problème sera lorsque nous souhaiteront exploiter les données enregistrées. Le plus intéressant serait de caster chaque donnée, mais comment savoir à quel type spécifique il correspond ? C’est là qu’intervient instanceof. Il permet de tester le type d’un objet. On pourra donc faire quelque chose comme :

for (ElementCarte ec : maListe) {
    if (ec instanceof Nom) {
        //Alors l'élément est de type Nom
    }
}

Chaque élément peut ainsi être traité en temps que son type et pas en temps que la classe dont il hérite.

Ajouter et enlever des composants dans Glassfish

Le fournisseur de persistance (Persistence Provider) utilisé de base avec Glassfish est EclipseLink. Malheureusement, j’avais besoin d’utiliser Hibernate pour un projet. Il m’a donc fallut l’installer.

Grâce à l’update center, ceci est devenu très simple. Il faut tout d’abord commencer par installer ce dernier si ce n’est pas déjà fait. Il suffit d’exécuter updatetool dans le dossier bin à la racine de l’installation de Glassfish.

Une fois l’update center installé, il suffit de cocher Hibernate JPA dans les composants disponibles pour qu’il soit rajouté à Glassfish.

Voyons maintenant la procédure pour désinstaller un composant précédemment installé par ce biais. Il faut passer par l’outil pkg situé dans le même répertoire bin que tout à l’heure. En effet, il n’est pas possible de décocher un composant pour le supprimer. Il est possible de lister les noms exacts de tous les composants actuellement installés en faisant :

pkg list

Il ne reste plus qu’à supprimer ceux que l’on veut à l’aide de la commande :

pkg uninstall <PACKAGE NAME>

Vous voilà prêt à éviter les erreurs de type :

Exception while preparing the app : java.lang.ClassNotFoundException: org.hibernate.ejb.HibernatePersistence

Hasher une chaîne de caractères en Java

Une notion élémentaire de sécurité informatique est de ne jamais stocker un mot de passe en clair. La moindre brèche de sécurité qui donnerait accès à la base de stockage des comptes utilisateurs aurait des conséquences catastrophiques.

Pour éviter un tel problème, on prend l’habitude systématique de hasher les mots de passe. On prend aussi l’habitude de faire ce que l’on appelle « saler » les mots de passe mais je reviendrai là dessus à la fin.

En Java, le code suivant retourne le hash sous la forme d’un tableau de byte. Son avantage est de ne pas se limiter au seul hash MD5.

public byte[] hasher(String toHash, String algorythm) {
	byte[] hash = null;

    try {
    	hash = MessageDigest.getInstance(algorythm).digest(toHash.getBytes());
    } catch (NoSuchAlgorithmException ex) {
    	Logger.getLogger(Hasher.class.getName()).log(Level.SEVERE, null, ex);
    }

    return hash;
}

Le hash MD5 produit un résultat sur 128 bits. Il est le plus souvent écrit comme une suite de 32 caractères hexadécimaux. Cependant, grâce à ce code, on peut aussi hasher des chaines en SHA-1, SHA-256, …

Il existe plusieurs manières de transformer ce tableau de byte en chaîne de caractères lisible. La plus simple que j’ai trouvé est celle ci :

public String toReadable(byte[] hash) {
    StringBuilder stringBuilder = new StringBuilder();
    for (byte byt : hash) {
        String hex = Integer.toHexString(byt);
        if (hex.length() == 1) {
            stringBuilder.append(0);
            stringBuilder.append(hex.charAt(hex.length() - 1));
        } else {
            stringBuilder.append(hex.substring(hex.length() - 2));
        }
    }
    return stringBuilder.toString();
}

On obtient ainsi un hash de n’importe quelle chaîne, et ce, dans l’algorithme que l’on souhaite.

Maintenant, je vais vous expliquer ce que l’on appelle le sel (salt) et quel est son intérêt.

Un sel est une séquence de bits dont le but est de modifier une séquence originel, dans notre cas, un mot de passe. La séquence peut être aléatoire ou choisie, mise avant ou après, voire même imbriquée. Le but de ce sel est de rendre unique la séquence finale afin de compliquer la tâche d’un attaquant éventuel. Le sel contre particulièrement bien les attaques que l’on appelle attaque par dictionnaire en diminuant les chances que la chaîne se trouve dans l’un d’entre eux.

De plus, même si le hash final ainsi que le sel sont trouvés, il faudrait générer un dictionnaire par sel. Autant dire une tâche longue et fastidieuse à laquelle aucun attaquant ne se lance tellement sa rentabilité est faible.

Conventions de nommage en Python

Python est un langage dont la force principale est d’obliger les développeurs à opter pour un code clair et indenté. Ainsi, je me suis demandé jusqu’où allaient leurs exigences et notamment avec les conventions de nommage. Celles ci, dont le respect est indispensable dans d’autres langages, s’avèrent volontairement inutiles en Python.

Ainsi, il n’y a pas de manière particulière dictée de nommer un paquet ou une variable. Python résume d’ailleurs sa philosophie en deux phrases :

Explicit is better than implicit.

et

Namespaces are one honking great idea — let’s do more of those!

Ces deux phrases sont tirées de The Zen of Python de Tim Peters (PEP 20). Ce sont d’ailleurs ces PEP (Python Enhancement Proposals) que les développeurs suivent pour structurer leurs codes. La PEP 8 dicte les règles s’appliquant aux variables et donne des exemples précis de chaque cas.

Le choix de faire sauter un certain nombre de conventions comme les « com.name.projectname.groupname.filename » est en partie dû au fait que les import Python permettent de faire :

import com.name.projectname.groupname.filename as shortfilename

et ainsi permettre un gain de place énorme en évitant nombre de répétitions inutiles.

Vider le cache de Glassfish

J’ai déjà parlé du cache de NetBeans et de la manière de le vider. Des problèmes similaires peuvent apparaître avec Glassfish dans d’autres conditions.

Pour vider son cache, il faut commencer par arrêter son serveur d’application, puis supprimer les éléments présents dans :

<Dossier de Glassfish>\glassfish\domains\<Nom de votre domaine>\generated

Après redémarrage, Glasshfish aura un cache vidé et tout propre.