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.

Vider le cache NetBeans

NetBeans possède un cache qui peut s’avérer gênant dans certains cas. Par exemple, dans un projet dans lequel on a créé des EJB et que l’on souhaite les supprimer, les fichiers générés restent et peuvent faire des conflits avec les nouvelles EJB que l’on souhaite créer.

Pour remédier à ce problème, il suffit de vider le cache de NetBeans. Celui ci se trouve dans le dossier :

C:\Users\<USERNAME>\AppData\Local\NetBeans\Cache

sous Windows et sous Linux dans :

~/.cache/netbeans/

Après avoir arrêté votre IDE, en supprimer ce dossier, son cache sera remis à zéro et les fichiers générés n’apparaîtront plus.

Subversion, problème de Working Copy

Subversion, bien qu’aujourd’hui de plus en plus délaissé pour Git, est un gestionnaire de version particulièrement efficace.

Cependant, de temps en temps, surtout avec des projets récupérés après quelques temps de mise de côté, Subversion n’arrive plus à mettre à jour la version locale du code en prétextant une erreur de Working Copy.

Le plus simple pour résoudre cette erreur est de supprimer purement et simplement les fichiers/dossiers .svn présent dans les sources du projet et de reconfigurer son dépôts pour aller récupérer le nouveau code.

Ceci n’est à utiliser qu’en dernier recours cependant si vous ne voulez pas perdre vos historiques locaux ou si vous ne voulez pas que risquer d’écraser du code que vous n’auriez pas encore commit.