Deblan blog

Développement

Supprimer les mots de passe d'un fichier Excel

Dans le cadre de mon travail, je vais devoir supprimer les mots de passe définis dans plusieurs dizaines de fichiers Excel.

Un fichier Excel, ainsi que n'importe quel type de fichier généré par la suite Office, est ni plus ni moins qu'une archive Zip contenant des répertoires et des fichiers XML. Les mots de passe ne chiffrent aucune donnée dans le cas d'une protection simple (le comportement par défaut). Par conséquant, et uniquement dans ce cas de figure, le mot de passe est un artifice pour bloquer l'accès à du contenu. Dans le cas d'un chiffrement des données, il n'est pas possible de supprimer le mot de passe comme je vais le faire. Les données sont stockées au format XML, il est donc très simple de retirer les mots de passe d'un classeur et de ses feuilles.

Afin d'industrialiser les modifications, j'ai écris un script qui fait toutes les modifications automatiquement : Excel password terminator.

Pour l'installer, il suffit simplement de clôner le projet ou de télécharger une archive de dépots. Les dépendances sont très peu nombreuses : zip, unzip, grep et sed.

asciicast


Migration de blog vers Murph

Mon blog a été mon premier vrai projet quand j'ai commencé de faire du développement web et il me suit toujours aujourd'hui.

Beaucoup de versions ont été réalisées car elles suivent mon évolution et les technologies que j'utilise. La précédente mouture était basée sur Trinity, un CMF basé sur Symfony 2, développé par web&design et sur lequel j'ai beaucoup travaillé. Trinity est puissant mais la conception n'est plus d'actualité et la migration vers une version récente de Symfony est impossible.
Je travaille sur la refonte du site web de l'association Tinternet & cie et s'est rapidement posée la question du CMS. Cela m'a permis d'entreprendre l'écriture de Murph, un CMF qui repose sur Symfony 5 et qui reprend les bonnes idées de Trinity avec une conception qui tient plus la route.

Tandis que Trinity était un hommage à Matrix, Murph est tout droit tiré d'Interstellar, un film pour lequel j'ai une affection très particulière. Voici quelques images du backoffice.

Si le projet vous intéresse, le code source du blog est disponible ici et celui du squelette de Murph se trouve là.


Mon thème pour ZSH

Cela fait des années que j'utilise ZSH comme interpréteur de commande. En complément, j'utilise également des plugins disponibles via l'excellent projet oh-my-zsh.

J'ai harmonisé l'ensemble des configurations sur mes différents accès. Pour ce faire, j'ai principalement travaillé sur le prompt et je publie aujourd'hui le code de mon thème.

Voici une capture d'écran qui décrit l'ensemble des fonctionnalités de mon thème :

  • Une gestion des codes de sortie avec différentes couleurs et éventuellement le code
  • L'affichage de l'heure
  • L'affichage de l'utilisateur et de la machine
  • Changement de couleur si l'utilisateur⋅trice est privilégié⋅e
  • Le chemin courant avec un retour à la ligne s'il dépasse une certaine longueur
  • Intégration de GIT (nécessite olivierverdier/zsh-git-prompt)

Mon thème pour ZSH

Le code source est disponible sur cette page et il est totalement libre.


Mail RSS : transformer des mails en flux RSS

J'essaye de plus en plus de réduire le volume de mails que je reçois. Du coup, quand une newsletter m'intéresse et que les auteurs ne fournissent pas de flux RSS, cela me donne un prétexte pour écrire un nouveau projet : Mail RSS.

Comment ça marche ?

L'idée est assez simple : en utilisant les alias de mail dans Postfix, on peut faire en sorte qu'un mail qui arrive sur le serveur soit traité par une commande. J'ai décidé de rediriger les mails dans un répertoire précis du serveur et je demande à Mail RSS de les lire et de les importer.

Prenons la newsletter de TechTrash comme exemple.

Configuration du serveur de mail

Il faut ajouter un alias qui va générer des fichiers.

techtrash: "| cat > /var/lib/mailrss/techtrash-$(date +%s) && chmod o+rw /var/lib/mailrss/techtrash-$(date +%s)"

Au préalable, j'ai créé le répertoire /var/lib/mailrss et je me suis assuré que mon application pouvait lire et écrire dedans, de même que Postfix (nobody:nogroup).

Configuration de l'application

On doit générer un mailing pour TechTrash. Quand on va importer les mails de TechTrash, on pourra les associer au mailing via son identifiant (ID). On pourra ensuite accéder au flux RSS via le lien généré à sa création. Évidement, on peut créer autant de mailing que l'on veut, les modifier et les supprimer.

$ php bin/console mailing:new "TechTrash"
$ php bin/console mailing:list
 ------------ -------------------------------------- ------------------------------------------------------------------------ --------------------- --------------------- 
  Label        ID                                     Feed                                                                     Created at            Updated at           
 ------------ -------------------------------------- ------------------------------------------------------------------------ --------------------- --------------------- 
  Tech Trash   xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx   https://exemple.fr/mailing/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/rss      2020-11-12 13:37:00   2020-11-12 13:37:00  
 ------------ -------------------------------------- ------------------------------------------------------------------------ --------------------- --------------------- 

Enfin, il faut un script qui va traiter les fichiers de /var/lib/mailrss en les important dans le mailing correspondant et qui les supprime du serveur.

#!/bin/sh

cd "/path/to/exemple.fr"

import_mails() {
    LABEL="$1"
    MAILING_ID="$2"

    find /var/lib/mailrss -name "${LABEL}-*" | while read MAIL; do
        php bin/console mail:import "${MAILING_ID}" -f "$MAIL" && rm "$MAIL"
    done
}

import_mails "techtrash" "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Quand un mail est importé, les données récupérées sont :

  • Le sujet du mail
  • La date du mail
  • Le contenu HTML
  • Le contenu texte
  • Les pièces jointes

Toutes ces données seront accessibles à la consultation.

L'application s'appuie sur Symfony (en version de développement) et le code est totalement libre 😄


Cohabitation de Collabora Online et OnlyOffice sur Nextcloud

J'utilise énormément mon instance Nextcloud et dans certaines situations, j'ai besoin d'éditer soit des fichiers Open Document Format (format natif de LibreOffice) ou soit des fichiers Open XML (format natif de la suite office de Microsoft).

L'an passé, j'utilisais exclusivement OnlyOffice via son connecteur Nextcloud et une instance installée sur un serveur dédié. Puis, lors d'un déboire au sujet de l'édition depuis un terminal mobile, j'ai décidé de migrer vers Collabora Online via son connecteur Nextcloud et une instance installée sur un serveur (presque) dédié.

Le problème est que si Collabora Online sait très bien traiter les fichiers ODF, il galère un peu plus avec les fichiers Open XML. Aussi, force est de constater que OnlyOffice reste très performant pour jouer avec Open XML. J'ai donc décidé de les installer ensemble. Collabora Online est donc l'éditeur ouvert pour les documents ODF tandis que OnlyOffice le sera pour les fichiers Open XML.

Collabora Online et OnlyOffice

Afin de les discerner dans le menu pour créer un nouveau document, j'ai développé un bout de javascript que vous pouvez injecter via JSLoader. Je pense d'ailleurs que cela sera une bonne idée de forker cette application afin d'en reprendre la maintenance.

Cohabitation de Collabora Online et OnlyOffice sur Nextcloud

Alors ce n'est sans doute pas le code le plus élégant mais il fonctionne bien.

try {
    setInterval(function() {
        var elements = {
            'docx': 'onlyofficeDocx',
            'xlsx': 'onlyofficeXlsx',
            'pptx': 'onlyofficePpts',
        };

        for (var i in elements) {
            var selector = 'a.menuitem[data-action="' + elements[i] + '"] .displayname';
            var span = document.querySelector(selector);

            if (!span) {
                return;
            }

            if (span.innerHTML.indexOf(i) !== -1) {
                continue;
            }

            span.innerHTML = (i !== 'docx' ? 'Nouvelle ' : 'Nouveau ') + span.innerHTML.toLowerCase() + ' (' + i + ')';
        }

        elements = {
            'odt': 'add-odt',
            'ods': 'add-ods',
            'odp': 'add-odp',
        };

        for (var i in elements) {
            var selector = 'a.menuitem[data-action="' + elements[i] + '"] .displayname';
            var span = document.querySelector(selector);

            if (!span) {
                return;
            }

            if (span.innerHTML.indexOf(i) !== -1) {
                continue;
            }

            span.innerHTML = span.innerHTML + ' (' + i + ')';
        }
    }, 100);
} catch (e) {

}