Deblan blog

Simon Vieille

IT director at Zenitude Groupe, symfony expert and debian addict

Monter un partage Sharepoint Office365 sur Linux (Webdav/Davfs)

Dans le cadre de mon travail, je développe une application web (nommée Tools) qui fait office de boite à outils pour le groupe Zenitude. L'idée de l'application est de fournir un ensemble d'outils pour faciliter le travail de mes collaborateurs.

Parmi la flopée de fonctionnalités, on trouve des interfaces qui affichent des données récupérées depuis des fichiers Excel. Elles sont analysées et mises en page par l'application (graphiques et tableaux).

Ces fichiers sont initialement déposés sur un espace collaboratif Sharepoint délivré par Office365. J'avais pour objectif de travailler avec les API de Microsoft mais c'est un véritable calvère. C'est mal documenté et le support technique de premier niveau est complètement naze. Du coup, je me suis résolu à faire des formulaires pour déposer les fichiers manuellement.

Pour éviter d'avoir des formulaires d'upload de fichier, je souhaite monter le partage Sharepoint sur le serveur afin d'accéder, en quasi temps réel, au contenu des fichiers qui m'intéressent. Microsoft fournit OneDrive qui est un outil de synchronisation pour monter le partage Sharepoint sur son ordinateur mais seul Microsoft Windows et IOS sont supportés. Il s'appuie sur le protocole WebDAV mais authentifie les utilisateurs avec le protocole OAuth2.

Sous Linux, davfs2 permet de faire des montages WebDAV dans son système de fichiers. La problématique d'authentification via OAuth2 est réelle car impossible de passer un couple login/mot de passe classique. Une solution existe et consiste à récupérer des cookies générés après l'authentification OAuth2 via un navigateur et indiquer à davfs2 de les injecter dans les requêtes HTTP WebDAV.

Pour des questions de sécurité, j'ai ajouté à l'organisation Office365 un compte utilisateur qui, par défaut, ne peut lire que les fichiers du partage. Lorsque que je me connecte à Office365 via un navigateur web en utilisant ce compte, 2 cookies sont créés : rtFa et FedAuth. Il faut conserver leur valeur respective car nous en auront besoin pour configurer le montage.

On va installer le driver davfs2 pour réaliser le montage :

# aptitude install davfs2

Je décide que le point de montage sera dans /mnt/sharepoint. Dans /etc/davfs2/davfs2.conf, on indique à davfs2 d'ajouter les cookies. Il faut bien évidement remplacer XXXXXX et YYYYYY par ce que vous avez récupéré :

[/mnt/sharepoint/]
ask_auth 0
add_header Cookie rtFa=XXXXXX;FedAuth=YYYYYY

Il reste maintenant à faire le montage :

# mount.davfs -o ro "https://foo.sharepoint.com/bar/Documents partages" /mnt/sharepoint

Si tout se passe bien, vous devrier avoir le montage fonctionnel. Ça ne sera pas détaillé ici mais vous pouvez maintenant affiner la configuration, faire du cache sur les fichiers, gérer les permissions plus finement, passer par /etc/fstab pour automatiser le montage, etc.


Gist 1.9.0 en ligne… Vive le monde du dev front !

La version 1.8.3 aussitôt publiée, j'avais complètement oublié la mort de bower au profit de yarn. Du coup, une tentative d'installation et tout fonctionne sauf les assets qui étaient gérés avec bower.

J'avais 2 choix possibles : utiliser yarn pour remplacer bower pour sans doute le voir disparaître dans quelques mois ou choisir un outil un peu plus bas niveau : NPM. La version 1.9.0 inclue donc NPM pour gérer les assets de Gist.

Dans cette version, il y a également un script exécuté à la fin des commandes composer pour configurer l'application sans passer par une édition manuelle des fichiers :

Pour mettre à jour votre application Gist coté client et serveur : make à la racine du projet.


Gist 1.8.3 released! 2 bugs majeurs fixés

Gist est un service en ligne et une application auto-hébergeable pour partager du code sur le web et en ligne de commande.

J'ai publié à l'instant la version 1.8.3 qui corrige 2 bugs majeurs concernant l'API :

  • La mise à jour d'un GIST requêtait le mauvais end point (diff)
  • Le contrôleur PHP pour la mise à jour d'un Gist pouvait récupérer un Gist qui n'était pas celui qu'on voulait mettre à jour (diff)

Pour mettre à jour votre application Gist coté client et serveur :


Remote i3-wm WS : ma télécommande pour bureau Debian GNU/Linux

Il m'arrive d'avoir besoin de prendre le contrôle de ma machine via mon Android (bouger la souris, scroller et taper du texte).

J'ai quasiment toujours utilisé l'application Pointer Host. elle s'appuie sur un serveur Java lancé sur ma machine. Pour bouger la souris et générer des cliques, elle est très efficace. Cependant, l'écriture de caractères a toujours posé problème (chiffres et lettres accentuées erronés).

Depuis quelques semaines, j'ai envie de jouer avec les websockets et réécrire une appli du genre m'a semblé être un bon exercice.

Ce que je vais vous présenter est une POC. Cette application n'est pas sécurisée et est orientée pour mes besoins. Il est cependant très simple de la faire évoluer.

Voici mon cahier des charges :

  1. aucune application ne doit être installée sur mon téléphone
  2. utilisation du navigateur web pour le pilotage
  3. pouvoir bouger la souris
  4. pouvoir générer des cliques
  5. pouvoir scroller
  6. pouvoir taper des mots
  7. pouvoir lancer des raccouris claviers
  8. pouvoir gérer le volume du son
  9. pour Spotify : lancer et mettre en pause la musique, avancer et reculer dans la playlist en cours de lecture
  10. pouvoir changer de workspace dans mon gestionnaire de fenêtres i3-wm

Les outils pour scripter tout ça sont connus :

  • xdotool pour simuler un clavier et une souris (3, 4, 5, 6, 7) :
    • xdotool type "ceci va être tapé"
    • xdotool key Enter (touche Entrée)
    • xdotool click 1 (clique gauche)
  • amixer pour gérer le volume (8) :
    • amixer set Master 50% (volume à 50%)
  • playerctl pour piloter Spotify (9) :
    • playerctl -p spotify next (titre suivant)
  • i3-msg pour piloter i3-wm (10) :
    • i3-msg 'workspace "Foo"' (affichage du workspace Foo)

Websocket est un protocole réseau issu du web qui permet de créer un canal full-duplex entre un client et un serveur. Ils peuvent donc communiquer en temps réel dans une connexion TCP.

Comme à mon habitude et par esprit de contradiction (pas de NodeJS), j'ai décidé d'écrire la partie serveur en PHP 7. La partie cliente est en HTML 5 avec un peu de javascript.

Entre le serveur et le client, ce sont des messages textes qui sont échangés. J'ai décidé de les formater en JSON et seul le client va en envoyer. Ils sont toujours sous cette forme : {"type":"un type de message", [données complémentaires]}. Voici quelques exemples :

  • {"type":"workspace","value":"1. IRC"}
  • {"type":"pointer","click":"left"}
  • {"type":"media","value":"next"}
  • {"type":"volume","value":"down"}
  • {"type":"scroll","value":"up"}
  • {"type":"pointer","x":"-2","y":"3"}
  • {"type":"text","value":"Un texte"}

On peut aussi envoyer plusieurs messages dans un seul. Voici un exemple qui va permettre d'ouvrir urxvt via dmenu que je lance avec win+d :

{"type":"messages","value":[{"type":"keys","value":"win,d"},{"type":"text","value":"urxvt"},{"type":"key","value":"enter"}]}

Ces messages sont générés par le client et sont interprétés par des messageHandler une fois transmis au serveur. En voici un exemple :

Le code source de l'application est disponible sur deblan/remote-i3wm-ws et la procédure d'installation est simple :

Pour lancer le serveur websocket, il faut exécuter server/server start (@see restart et stop). Le serveur va écouter sur le port 14598. Concernant la partie cliente, vous pouvez créer un vhost Apache/Nginx qui pointera sur client/ ou lancer le serveur web built-in de PHP via php -S 0.0.0.0:15000 -t client/. Il faudra à présent vous connecter au serveur web depuis un navigateur.

Quelques captures de la partie cliente :

Remote i3-wm WS: keyboardRemote i3-wm WS: i3Remote i3-wm WS: mouseRemote i3-wm WS: media

Je vais essayer de faire une vidéo de démonstration. Depuis mon Samsung S8, ça fonctionne du feu de dieu et sur un petit Iphone 4S, c'est tout aussi fonctionnel (à part l'interface web un peu étriquée).

Edit 1

  • dbus-send a été remplacé par playerctl (merci Thomas L)
  • le type messages a été ajouté et permet d'envoyer plusieurs messages (cf l'exemple avec urxvt) et les mises à jour du code

Edit 2

  • Le code PHP du serveur a été déplacé dans server/src/resource/server.php
  • server/server est à présent un script shell et permet de lancer, relancer et stopper le serveur websocket (server/server start|restart|stop)

Monitordisplay : gérer ses dispositions d'écrans

Je branche très souvent des écrans externes à mon laptop et je suis un peu lassé de bidouiller xrandr. En effet, ses instructions sont simples mais assez longues et pénibles à écrire.

Ainsi, j'ai décidé de me faire un outil pour pouvoir configurer des modes d'affichage, pouvoir ajouter plusieurs dispositions et les activer rapidement.

Comme à mon habitude, c'est un outil en ligne de commande. J'ai décidé d'utiliser PHP pour une question de pratique pour moi.

Installation de monitordisplay

Il faut installer l'interpréteur PHP (5 ou 7) :

Maintenant que PHP est installé, il faut récupérer le projet :

Configuration

monitordisplay va essayer de charger 3 fichiers. Chaque fichier peut surcharger la configuration du précédent. Voici la liste :

  • /etc/monitordisplay/config.ini
  • $HOME/.config/monitordisplay/config.ini
  • $HOME/.monitordisplay

Je suis le seul utilisateur du laptop donc je vais juste créer le dernier.

Le fichier de configuration copié contient 2 écrans :

laptop et hdmi sont les identifiants "humains" sur lesquels je vais m'appuyer pour réaliser les dispositions. Le paramètre name contient l'identifiant technique passé à xrand. resolutionX et resolutionY indiquent la résolution de l'écran.

Il est possible de configurer plusieurs fois le même écran. Il suffit de modifier l'identifiant humain. Vous pouvez ainsi prévoir plusieurs résolutions.

Maintenant, il reste à renseigner des modes d'affichage. En voici trois exemples :

Tout comme un écran, le mode d'affichage porte un identifiant. Il possède également une liste de dispositions (config[]) et un indicateur (optionnel) d'écran principal (primary). L'ordre des identifiants définie la position, de gauche à droite, des écrans.

Utilisation

Pour activer un mode d'affichage (exemple : work), il suffit de lancer cette ligne de commande :

Le mode work contient deux dispositions. Pour passer à la seconde disposition, il suffit de lancer :

-t permet donc de passer successivement d'une disposition à une autre.

Quand monitordisplay charge un mode ou change de disposition, par défaut, il désactive les écrans non pris en charge. Si vous souhaitez outre-passer ce comportement, il suffit de passer l'argument -s. C'est assez pratique quand vous souhaitez initialiser une résolution sur un écran sans désactiver les autres.

Le code source est disponible sur gitnet et c'est open bar ;)