La page de GnunuX

Aller au contenu | Aller au menu | Aller à la recherche

dimanche, octobre 11 2020

Écrire un client Bitwarden en python : créer une organisation et une collection

Je suis en train d'écrire un logiciel qui va interagir avec Bitwarden. Il existe plusieurs clients Bitwarden, mais peu sont suffisamment complet pour mon besoin.

Ce billet fait suite au premier billet écrire un client Bitwarden en python : créer, connecter, valider un compte et au deuxième billet écrire un client Bitwarden en python : créer un identifiant dans mon coffre

On va voir comment créer une organisation et une collection.

Une organisation est un espace de stockage où un ensemble d'utilisateur peut partager des éléments.

Une collection (à ne pas confondre avec les répertoires) permet de ranger les éléments et de les partager avec les membres d'une organisation.

Créer une organisation

Avant de créer une organisation, il va falloir créer une clé symétrique. On ne peut pas utiliser la clé symétrique de son coffre, car l'objectif des organisations est de pouvoir partage des informations avec d'autres utilisateurs. Cette clé symétrique va donc être partage avec tous les utilisateurs.

Ne pouvant être stocké en clair dans la base de Bitwarden et ne pouvant accéder aux clés symétriques des autres utilisateurs, cette clé va être chiffrée avec les clés publiques des clés asymétriques de tous les utilisateurs accédant à cette organisation.

Les utilisateurs utiliseront leur clé privée, protégé, pour accéder à la clé symétrique.

C'est pour cela qu'à la création des utilisateurs nous avons créé une clé asymétrique.

Récupérons la clé asymétrique (la variable login ci-dessous provient de la connexion de l'utilisateur) :

private_key = login['PrivateKey']

Cette clé est chiffrée avec la clé symétrique de l'utilisateur. Il faut donc commencer par la déchiffrer comme vu dans le précédent billet.

On génère ensuite une clé symétrique pour cette organisation :

token = token_bytes(64)

Et on la chiffre avec la clé asymétrique précédemment déchiffrée :

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

rsa_key = RSA.importKey(private_key)
cipher = PKCS1_OAEP.new(rsa_key).encrypt(token)
b64_cipher = b64encode(cipher).decode()

Le secret est mis dans une chaine avec le type 4 pour préciser que la donnée est chiffrée par une clé asymétrique :

encoded_key = f"4.{b64_cipher}"

Pour créer l'organisation il nous manque :

  1. une adresse courriel de facturation (je suppose que c'est utile uniquement sur la plateforme officielle)
  2. le nom de l'organisation chiffrée avec la clé symétrique de cette organisation
  3. le nom de la collection par défaut
data = {"key": encoded_key,
            "collectionName": encoded_organization_name,
            "name": collection_name,
            "billingEmail": email,
            "planType": 0,
        }

Il faut faire un POST avec ce payload sur l'URL ''https://localhost:8001/api/organizations' pour créer l'organisation. Dans l'entête il faut rajouter les informations d'authentification :

{'Authorization': f'Bearer {login["access_token"]}'}

Créer une collection

La création d'une collection est assez simple.

Il faut juste chiffrer avec la clé symétrique de la collection le nom de la collection.

 data = {"groups": [],
               "name": encrypted_name
              }

L'URL pour créer la collection est construite à partir de l'ID de l'organisation : f'https://localhost:8001/api/organizations/{organization_id}/collections'.

Il faut faire un POST avec ce payload sur cette URL. Dans l'entête il faut rajouter les informations d'authentification :

{'Authorization': f'Bearer {login["access_token"]}'}

Invitée un autre utilisateur à cette organisation

L'invitation de l'utilisateur ne pose par de problème (ici je ne m'occupe pas de la gestion des droits) :

email = 'other@gnunux.info'
data = {'emails': [email],
             'collections': None,
             'accessAll': True,
             'type': 2,
             }

L'URL pour invité un utilisateur à la collection est construite à partir de l'ID de l'organisation : f'https://localhost:8001/api/organizations/{organization_id}/users/invite'.

Il faut faire un POST avec ce payload sur cette URL. Dans l'entête il faut rajouter les informations d'authentification :

{'Authorization': f'Bearer {login["access_token"]}'}

Confirmer l'invitation

L'utilisateur devrait alors accepter cette invitation. Un courriel est envoyé à l'utilisateur qui devra cliquer sur le lien et s'authentifier sur Bitwarden.

Il est possible d'automatiser ce processus comme lors de la création d'un utilisateur mais cette fonctionnalité ne m'intéresse pas.

Une fois que l'utilisateur a accepté l'invitation, il faut confirmer l'invitation.

La confirmation consiste principalement à chiffrer la clé symétrique de cette organisation avec la clé publique de la clé asymétrique de l'utilisateur.

Le plus simple pour récupérer cette clé publique, et de récupérer les informations de l'organisation.

Il suffit pour cela de faire un GET sur l'URL f'https://localhost:8001/api/organizations/{organization_id}/users' et de récupérer la réponse dans la variable "users". Dans l'entête il faut rajouter les informations d'authentification :

{'Authorization': f'Bearer {login["access_token"]}'}

À partir de ces informations on va rechercher le numéro utilisateur :

> for user in users['Data']:
>     if user['Email'] == email:
>         user_id = user["UserId"]
>         break

Et nous allons récupérer la clé publique.

Il suffit pour cela de faire un GET sur l'URL f'https://localhost:8001/api/users/{user_id}/public-key' et de récupérer la réponse dans la variable "user_public_key". Dans l'entête il faut rajouter les informations d'authentification :

{'Authorization': f'Bearer {login["access_token"]}'}

Et on retrouve la clé publique :

public_key = b64decode(user_public_key['PublicKey'])

Et on chiffre la clé symétrique de l'organisation avec cette clé publique de la même façon qu'on a chiffrée au-dessus pour la sienne.

Enfin on construit le payload :

data = {"key": key}

L'URL pour confirmer l'invitation d'un utilisateur à la collection est construite à partir de l'ID de l'organisation et de l'utilisateur : f'https://localhost:8001/'api/organizations/{organization_id}/users/{user_id}/confirm'.

Il faut faire un POST avec ce payload sur cette URL. Dans l'entête il faut rajouter les informations d'authentification :

{'Authorization': f'Bearer {login["access_token"]}'}

Pour finir ...

Avec les informations contenues dans ces trois billets, vous devriez être capable d'intéragir avec Bitwarden.

Pour comprendre le fonctionnement de Bitwarden je me suis servi :

  1. de la documentation de l'API de Bitwarden
  2. l'implémentation rust de Bitwarden
  3. de l'implémentation officielle du client en typescript/javascript
  4. d'une implémentation d'un client en python
  5. d'une implémentation d'un client en ruby
  6. d'une implémentation d'un client en rust

Écrire un client Bitwarden en python : créer un identifiant dans mon coffre

Je suis en train d'écrire un logiciel qui va interagir avec Bitwarden. Il existe plusieurs clients Bitwarden, mais peu sont suffisamment complet pour mon besoin.

Ce billet fait suite au premier billet écrire un client Bitwarden en python : créer, connecter, valider un compte.

Voyons maintenant comment créer un "identifiant" dans son propre coffre.

Déchiffrer des données avec clé symétrique

Avant tout, nous allons voir comment déchiffrer des données avec sa clé symétrique.

Comme nous l'avons vu, on reconnait du contenu chiffré par une clé symétrique lorsque la chaine ressemble à :

f'2.{b64_iv}|{b64_ct}|{b64_digest}'

Pour déchiffrer nous avons besoin de la clé symétrique découpé comme cela :

enc = sym_key[:32]
mac = sym_key[32:]

Voici comment déchiffrer le contenu de la variable cipher :

type, cipher_data = cipher.split('.', 1)
assert type == 2  # it's a symetric key

iv, ct, cipher_mac = (b64decode(sdata) for sdata in cipher_data.split('|', 2))
cmac = hmac_new(mac, iv, ct, sha256)
assert cipher_mac == cmac.digest()  # it's the good key

plaintext = AES.new(enc, AES.MODE_CBC, iv).decrypt(ct)
pad_len = plaintext[-1]
padding = bytes([pad_len] * pad_len)
if plaintext[-pad_len:] == padding:
    plaintext = plaintext[:-pad_len]

Chiffrer les données

Pour chiffrer les données, il faut commencer par récupérer la clé de chiffrement symétrique (la variable login ci-dessous provient de la connexion de l'utilisateur) :

master_key = login['master_key']
enc = hkdf_expand(master_key, b'enc', 32, sha256)
mac = hkdf_expand(master_key, b'mac', 32, sha256)

cipher = login['Key']

On peut récupérer la valeur de la clé symétrique en déchiffrant son contenu comme vu dans le paragraphe précédent :

sym_key = plaintext
assert len(sym_key) == 64  # the symetric key has 64 characters

La clé de chiffrement est stockée dans la variable sym_key.

Pour chiffrer le contenu (la variable "content" ci-dessous) avec la clé symétrique il faut faire (comme nous l'avons déjà vu) :

content = content.encode()
enc = sym_key[:32]
mac = sym_key[32:]
iv = token_bytes(16)
pad_len = 16 - len(content) % 16
padding = bytes([ pad_len ] * pad_len)
ct = AES.new(enc, AES.MODE_CBC, iv).encrypt(content + padding)
cmac = hmac_new(mac, iv + ct, sha256)

Puis stocker dans une chaine les informations :

type = 2
b64_iv = b64encode(iv).decode()
b64_ct = b64encode(ct).decode()
b64_digest = b64encode(cmac.digest()).decode()

encoded_content = f'{type}.{b64_iv}|{b64_ct}|{b64_digest}'

Créer un identifiant

Pour créer un identifiant nous avons besoin :

  1. d'un nom d'identifiant
  2. d'un nom d'utilisateur
  3. d'un mot de passe

Ces trois informations doivent être chiffrées avec la clé symétrique comme vu ci-dessus :

data = {"type": 1,
 "folderId": None,
"organizationId": None, 
"name": encoded_name,
"notes": None,
"favorite": False,
"login":{
  "response": None,
  "uris": None,
  "username": encoded_username,
  "password": encoded_password,
  "passwordRevisionDate": None,
  "totp": None
 }
}

Il faut faire un POST avec ce payload sur l'URL https://localhost:8001/api/ciphers pour créer l'identifiant. Dans l'entête il faut rajouter les informations d'authentification :

{'Authorization': f'Bearer {login["access_token"]}'}

La suite

Nous verrons par la suite comment créer une "organisation" et une "collection".

Écrire un client Bitwarden en python : créer, connecter, valider un compte

Je suis en train d'écrire un logiciel qui va interagir avec Bitwarden. Il existe plusieurs clients Bitwarden, mais peu sont suffisamment complet pour mon besoin.

J'ai également trouvé peu de documentation sur comment écrire un client Bitwarden.

La particularité de Bitwarden c'est que toutes la partie cryptographique est réalisé côté client.

Pour être caricatural, le serveur n'est qu'un espace de stockage.

Je n'ai testé ce code que sur l'implémentation Rust de Bitwarden : https://github.com/dani-garcia/bitwarden_rs/.

Dans ce premier billet je vais expliquer comment créer, connecter et valider un compte.

Créer un compte

Créer un compte, signifie d'abord créer deux clés de chiffrement :

  1. une clé de chiffrement symétrique (pour chiffrer le contenu de son coffre)
  2. une clé de chiffrement asymétrique (pour chiffrer les clés de chiffrement symétrique des organisations)

Créer une clé de chiffrement symétrique

Le chiffrement symétrique utilise AES en mode CBC.

Pour créer une clé de chiffrement symétrique, rien de bien compliqué. Il faut un nombre aléatoire de bytes de 64 caractères :

from secrets import token_bytes
token = token_bytes(64)

Chiffrer la clé symétrique

Ces clés sont stockées sur le serveur, mais elles ne doivent pas y être stockées en clair. Sinon quelqu'un qui accèderait à la base de donnée pourrait accéder à l'ensemble des données.

Cette clé est alors chiffrée à partir de quatre éléments :

  1. l'adresse courriel de l'utilisateur
  2. le mot de passe maître de l'utilisateur
  3. un vecteur d'initialisation
  4. un nombre d'itération

Les deux premiers éléments sont connus par l'utilisateur :

password = 'oi29ç&&ZIuçàç3'
email = 'my_mail@gnunux.info'

Attention, l'adresse courriel doit être en minuscule :

email = email.lower()

Le vecteur d'initialisation est généré :

from secrets import token_bytes
iv = token_bytes(16)

Le nombre d'itération peut être récupéré via cURL :

# curl -d '{"email":"my_mail@gnunux.info"}' -H "Content-Type: application/json" -X POST https://localhost:8001/api/accounts/prelogin
{"Kdf":0,"KdfIterations":100000}

Donc ici :

iteration = 100000

Attention la longueur de la clé doit être un multiple de 16. Pour compléter la taille du token on va ajouter n fois la longueur de la clé :

// pad_len = 16 - len(token) % 16 padding = bytes(pad_len * pad_len) content = token + padding // À partir de là il est possible de chiffrer la clé :

from hashlib import pbkdf2_hmac, sha256
from hkdf import hkdf_expand
from base64 import b64encode

master_key = pbkdf2_hmac('sha256', password.encode(), email.encode(), iterations)
enc = hkdf_expand(master_key, b'enc', 32, sha256)
mac = hkdf_expand(master_key, b'mac', 32, sha256)
c = AES.new(enc, AES.MODE_CBC, iv)
ct = c.encrypt(content)
cmac = hmac_new(mac, iv + ct, sha256)

Les informations indispensables sont alors stockées dans une unique chaine.

Quatre informations sont stockées :

  1. le type de la clé (pour les clés symétriques ce type est "2")
  2. le vecteur d'initialisation
  3. le token chiffré
  4. le digest pour valider la clé
type = 2
b64_iv = b64encode(iv).decode()
b64_ct = b64encode(ct).decode()
b64_digest = b64encode(cmac.digest()).decode()

encoded_sym_key = f'{type}.{b64_iv}|{b64_ct}|{b64_digest}'

Créer une clé de chiffrement asymétrique

Le chiffrement asymétrique utilise RSA de longueur 2048.

Pour créer une clé de chiffrement asymétrique :

from Crypto.PublicKey import RSA
asym_key = RSA.generate(2048)
private_key = asym_key.exportKey('DER', pkcs=8)
public_key = asym_key.publickey().exportKey('DER')

Chiffrer la clé asymétrique

La clé asymétrique est chiffrée non pas à partir du mot de passe et de l'adresse courriel, mais à partir de la clé symétrique. Si on change de mot de passe, il n'est ainsi nécessaire que de re-chiffrer la clé symétrique.

La clé symétrique est coupée en deux :

enc=token[:32]
mac=token[32:]

On génère un vecteur d'initialisation :

iv = token_bytes(16)

On ajoute des caractères pour arriver à un multiple de 16 :

pad_len = 16 - len(private_key) % 16
padding = bytes([ pad_len ] * pad_len)
content = private_key + padding

Et on chiffre :

ct = AES.new(enc, AES.MODE_CBC, iv).encrypt(content)
cmac = hmac_new(mac, iv + ct, sha256)

On stocke dans une chaine les informations :

type = 2
b64_iv = b64encode(iv).decode()
b64_ct = b64encode(ct).decode()
b64_digest = b64encode(cmac.digest()).decode()

encoded_asym_key = f'{type}.{b64_iv}|{b64_ct}|{b64_digest}'

Création du compte

Il nous manque une information pour créer le compte, le hash du mot de passe.

Ce hash servira à Bitwarden de valider la connexion de l'utilisateur.

Pour créer le hash :

hash_password = b64encode(pbkdf2_hmac('sha256', master_key, password.encode(), 1)).decode()

Nous pouvons ainsi construire le payload de la fonction de création du compte :

data = {'name': 'Mon nom',
              'email': email,
              'masterPasswordHash': hash_password,
              'masterPasswordHint': None,
              'key': encoded_sym_key,
              'kdf': 0,
              'kdfIterations': iterations,
              'referenceId': None,
              'keys': {
                  'publicKey': public_key,
                  'encryptedPrivateKey': encoded_asym_key
                  }
              }

Il faut faire un POST avec ce payload sur l'URL https://localhost:8001/api/accounts/register pour créer l'utilisateur.

Se connecter au compte

Pour se connecter au compte nous avons besoin :

  1. de l'adresse courriel
  2. du hash du mot de passe (voir au-dessus)
  3. d'un identifiant de client

L'identifiant n'est qu'un UUID, il devra être conservé dans la configuration du client. Sinon, à chaque nouvelle connexion un courriel sera envoyé pour prévenir qu'un nouveau client se connecte à notre compte.

Pour générer un UUID, rien de plus simple :

from uuid import uuid4
uuid = uuid4()

Nous avons toutes les informations pour créer notre payload :

data = {'grant_type': 'password',
              'username': email,
              'password': hash_password,
              'scope': 'api offline_access',
              'client_id': 'desktop',
              'device_type': 7,
              'device_identifier': uuid,
              'device_name': 'my_client',
             }

Il faut faire un POST avec ce payload sur l'URL ''https://localhost:8001/identity/connect/token' pour se connecter à l'utilisateur.

Il faut conserver les informations de connexion. Nous verrons plus tard à quoi cela servira.

Valider le compte

Un compte est valide quelques jours. Il faut donc rapidement valider le compte.

Pour valider un compte il faut soit :

  1. cliquer sur le lien envoyé par mail
  2. créer un JWT valide

Attention, pour créer un JWT valide, il faut avoir accès à la clé privée de Bitwarden_rs.

Pour valider le compte il nous faut l'ID utilisateur. Pour cela nous allons récupérer la clé "access_token" retourné lors de la connexion de l'utilisateur.

Ce "access_token" est un JWT.

from jwt import decode as jwt_decode
user_id = jwt_decode(login['access_token'], algorithm="RS256", verify=False)['sub']

Nous pouvons créer le payload :

from time import time
now = int(time())
data = {'nbf': now, 'exp': now + 432000, 'iss': 'https://localhost:8001|verifyemail', 'sub': user_id}

Il faut générer le JWT à partir de ce payload :

with open('/var/lib/bitwarden_rs/rsa_key.der', 'rb') as private_key_fh:
    private_key = RSA.importKey(private_key_fh.read()).exportKey('PEM')
jwt = jwt_encode(data, private_key, algorithm="RS256").decode()

Enfin nous pouvons faire le payload de validation :

data = {'userId': user_id, 'token': jwt}

Il faut faire un POST avec ce payload sur l'URL ''https://localhost:8001/api/accounts/verify-email-token' pour valider l'utilisateur. Dans l'entête il faut rajouter les informations d'authentification :

{'Authorization': f'Bearer {login["access_token"]}'}

La suite

Nous verrons par la suite comment créer un "identifiant", une "organisation" et une "collection".

samedi, septembre 20 2014

Corriger les fichiers GPX et les coordonnées GPS d'une photographie avec Viking

Depuis de nombreuses années, j'utilise le logiciel libre viking pour modifier mes fichiers GPX.

En effet très souvent le GPS se désynchronise (passage sous un pont, montagne, ...) et ma trace GPX ne ressemble plus à rien. Sans parler du début de la trace qui parfois est très fantaisiste.

Depuis que je fais des photographies géotaggés, je corrige (ou rajoute) aussi les coordonnées GPS via viking.

Ce post vise à présenter très rapidement comment j'effectue mes corrections. Ce n'est évidement pas un manuel complet. Il existe d'ailleurs un manuel officel dans l'espace de téléchargement du projet si vous voulez plus d'informations.

Corriger une trace GPX

Le première cas traité est assez simple. Avant que le GPS ne se synchronise complètement il peux y avoir quelques points incohérents.

gpx_debut.png

Il me suffit de supprimer ces points.

Avant tout il faut ouvrir le fichier GPX. Pour cela rien de plus simple "Fichier/Ouvrir" et sélectionnez votre fichier GPX.

Dans le panneau des calques, je sélectionne mon fichier et dans la barre d'icône de sélectionne "Éditer un point de trace".

Il suffit ensuite de cliquer sur un des points et de supprimer tous les points en trop.

gpx_debut_correction.png

Pour corriger des points en milieu de trace c'est un peu le même principe.

gpx_milieu.png

Il est possible de supprimer/déplacer/ajouter des points.

Enfin, il faut enregistrer les modifications. Il suffit de sélection le calque de la trace (VIKING_TR001dans la capture au dessus) et de cliquer droit dessus. Dans le menu choisir "Export Track as GPX" et choisir un nom de fichier.

Corriger les coordonnées GPS d'un photographie

Avant de commencer, je n'ai jamais réussi à géotaggé une image qui n'était pas géotaggé au préalable. Si une photographie n'est pas géotaggé, je commence alors par mettre des coordonnées fictives via la commande exiv2 :

exiv2 -M"set  Exif.GPSInfo.GPSLatitudeRef N" -M"set Exif.GPSInfo.GPSLatitude 0/0 0/0 0/0" -M"set  Exif.GPSInfo.GPSLongitudeRef W" -M"set Exif.GPSInfo.GPSLongitude 0/0 0/0 0/0" nom_fichier.jpg

Je me rend dans la zone où je veux placer ma photographie et j'ajoute un nouveau calque de type "TrackWaypoint" (menu Calques/Nouvelle couche TrackWaypoint). Sur ce calque je clique droit pour ajouter un "Waypoint" (Nouveau/New Waypoint...). Dans la fenêtre qui s'ouvre, j'ajouter le chemin de mon "Image". Cette méthode permet de ne pas voir ma photographie à la coordonnée que j'ai forcé au dessus mais qu'elle apparaisse au centre de ma carte courante.

Il suffit ensuite de sélectionner la couche de la photographie et de choisir le bouton "Éditer un Waypoint". Le positionnement de la photographie se fait alors à la souris.

photo_gps.png

Une fois placer, cliquez droit sur la couche de la photographie et sélectionnez le menu "Update Geotag on Image/Update".

Le principe est le même pour une photographie géotaggée mais nécessitant des corrections. Seule la méthode pour ajouter la couche diffère. Il faut ouvrir le (ou les) photographie(s) via le menu "Fichier/Récupérer/Depuis Images Géoréferencées...".

Je peux ensuite uploader mes traces et mes photographies sur Piwigo.

samedi, septembre 13 2014

Raconter son circuit touriste avec Piwigo

Je pars bientôt visiter un pays étranger pendant deux semaines. Les enfants resteront en france, donc je voulais mettre en place un site permettant de diffuser des photographies et nos impressions.

Voilà mes besoins :

  • tout doit être privé donc accessible uniquement par mot de passe ;
  • le site est centré sur les photographies ;
  • le site doit être simple à utiliser (juste ce qu'il faut d'option et de menu, pas plus) ;
  • l'appareil photo ajoutant les données GPS, je veux localiser ces photographies ;
  • je prévois de récupérer les tracés GPS au format GPX, je veux pouvoir ajouter mes GPX sur les cartes ;
  • je veux avoir la possibilité de rajouter des tags et une description des albums photo.

J'ai donc choisi de mettre en place un Piwigo.

Installation de Piwigo

L'installation de Piwigo est simple :

Télécharger la dernière version de Piwigo.

Désarchiver Piwigo avec la commande "unzip".

Les droits par défaut ne me plaisent pas spécialement, nous allons donc changer cela. Mais il deviendra impossible d'installer des plugins et faire des mises à jour via l'interface de Piwigo.

Voici les droits que je mets :

chown -R root:www-data piwigo
chmod -R 640 piwigo
find piwigo -type d -exec chmod 750 {} \;
chmod -R 770 piwigo/_data
chmod -R 770 piwigo/upload

Maintenant créons la base (évidement personnaliser votre mot de passe) :

mysql -uroot -pmotdepassemysql
> CREATE DATABASE piwigo;
> GRANT ALL PRIVILEGES ON `piwigo`.* TO 'piwigo'@'localhost' IDENTIFIED BY 'mot_de_passe_terrible';
> FLUSH PRIVILEGES;

Enfin passons à la phase de configuration de base de l'application en se rendant avec un navigateur web sur http://xxxxxxxxxxxx/piwigo/.

La page de configuration est suffisamment simple pour ne pas l'expliquer ici.

Attention, il faut donner des droits temporaires de modification de la configuration.

Pour cela faire :

chmod 770 piwigo/local/config

Une fois la configuration enregistrer, faire :

chmod 750 piwigo/local/config
chmod 640 piwigo/local/config/database.inc.php

Installation des plugins

gdThumb

J'ai installé le plugin gdThumb pour avoir une vue centrée sur les photographies. Ce plugin permet d'avoir une vue des albums à la Masonry. J'avais testé le plugin GThumb+. L'avantage de gdThumb c'est qu'il gère les catégories.

GdThumb propose de mettre la première photo plus grosse que les autres.

album.png

Par contre il n'est pas possible de différencier les catégories des albums. La photo du premier album est donc plus gros que les autres. Le développeur semble prêt à différencier le paramétrage de l'album et de la catégorie. En attendant j'ai fait une modification crade dans mon installation :)

categories.png

FCKEditor

J'ai installé FCKEditor mais je suis plutôt déçu de l'intégration de ce plugin. Je suis en train d'y travailler mais j'y reviendrais dans un autre billet.

fckeditor.png

piwigo-openstreetmap

C'est le plugin le plus important que j'ai installé. C'est ce plugin qui permet à Piwigo de répondre à une grosse partie de mes besoins. Par contre j'ai du faire des modifications importantes dans le code. J'ai proposé mes modifications au développeur principal. J'espère qu'elles seront intégrées.

photo.png

Un bouton permet d'accéder à une carte en plein écran.

carte.png

En attendant vous pouvez récupérer ma version en faisant :

# git clone https://github.com/GnunuX/piwigo-openstreetmap.git

Par contre piwigo-openstreetmap a besoin de créé le fichier piwigo/osmap.php. Avec les droits que j'ai mis le plugin n'a pas le droit de créé ce fichier. Il faut donc autorisé temporairement l'écriture du fichier :

chmod 770 piwigo

N'oubliez pas de supprimer ces droits une fois le plugin activer :

chmod 750 piwigo

Configuration de l'application

Dans l'espace d'administration :

Configuration/Option/Général

  • il faut changer le "Titre de la galerie" ;
  • personnellement je supprime tout le texte de "Bannière des pages" pour gagner de la plage en haut de la page ;
  • pour simplifier l'interface utilisateur, je décoches toutes les permissions.

Configuration/Option/Affichage

  • je décoche tout "Page principale" sauf "Activer l'icône "Diaporama"" ;
  • je passe "Nombre d'albums par page" à 40 ;
  • pour "Page de la photo" je coche uniquement "Activer l'icône "Diaporama"", "Activer l'icône "Télécharger ce fichier"", "Activer la barre de navigation" et "Activer les miniatures de navigation" ;
  • dans "Propriétés de la photo" je laisse "Créée le", "Tags", "Qui peut voir cette photo ? (disponible uniquement pour les administrateurs)".

Configuration/Option/Commentaires

Je décoche "Activer les commentaires".

Configuration/Menus

Masqué : "Tags liés", "Spéciales", "Menu" et "Identifications".

Plugins/OpenStreetMap/Configuration

  • pour afficher la carte à côté de la photographie, il faut "Ajouter l'information avant" "Créée le" (puisque les autres informations ne sont pas affiché) ;
  • "Nom du titre" j'ai mis "Carte" ;
  • je préfère la carte dans le menu : passer à "non" "Description de la catégorie" et passer à "oui" "Menu principal" ;
  • "World map menu name" : j'ai mis le titre + " - La carte" ;
  • "Hauteur de la carte" à 300 ;
  • pour limiter les affichages sous la carte, je décoche "Affiche 'Powered by Leaflet'", "Affiche le style de carte" et "Affiche le nom de l'auteur".

Plugins/gdThumb

  • "Marge entre les miniatures px" : 1 ;
  • "Redimensionner les miniatures" : "Redimensionner".

Configuration avancée

Comme je le disais au début, je veux une galerie privée. Dans le fichier piwigo/local/config/config.inc.php je force les options suivantes :

//new category are private
$conf['newcat_default_status'] = 'private';
//and herite group
$conf['inheritance_by_default'] = true;
//no guest access
$conf['guest_access'] = false;

Je supprime le support des exifs (moi d'information inutile à l'affichage) :

$conf['show_exif'] = false;

Je force la taille à large :

$conf['derivative_default_size'] = 'large';

Changement CSS

J'ai du modifié également l'apparence dans le fichier piwigo/local/css/elegant-rules.css :

J'ai augmenté la taille du menu à 300px (parce que la carte est maintenant dans le menu) :

#menubar {
  width: 300px;
}
#the_page #content.menushown, #the_page > .content.menushown, .contentWithMenu {
  margin-left: 310px;
}

menu.png

Le texte des catégories est en centré. Je n'aime pas trop le texte centré, je l'ai donc mis en justifié par défaut :

.content .additional_info, TEXTAREA.description {
  text-align: justify;
}

Je reviendrais sur piwigo bientôt.

samedi, mai 19 2012

Piratons la démocratie

Le parti pirate présente un candidat dans la 2eme circonsccription de Côte d'Or. Une réunion d'information est prévu le mercredi 23 mai 2012.

Voici l'annonce :

Le bar l'Antre II Mondes de Dijon nous a proposé d'animer une réunion de présentation du Parti Pirate le mercredi 23 mai prochain à 18h30.

Antre II Mondes 21, rue d'Ahuy 21000 Dijon

Voici l'annonce :

Le Parti Pirate présente cette année 102 candidats aux élections législatives. "Son programme se développe sur la base de la protection des droits et libertés fondamentales, aussi bien dans le domaine numérique qu'en dehors. Les thèmes de campagnes pour les élections législatives de 2012 sont la légalisation du partage hors marché, la lutte contre le fichage abusif, l'indépendance de la justice, la transparence de la vie politique et l'ouverture des données publiques." (Wikipedia)

Si le sujet vous intéresse, si vous souhaitez en savoir plus sur ce nouveau visage de la scène politique française, nous vous proposons de venir en discuter mercredi 23 Mai, à partir de 18h30 avec Gérald Schwartzmann, candidat sur la 2eme circonscription de Côté d'Or et Agathe Hernandez-Bonnin sa suppléante.

Merci de diffuser l'information!

lundi, octobre 17 2011

Edenwall est mort ... vive Cadoles

Comme je disais il y a un peu plus de 3 ans, je ne parle pas facilement de mon activité professionnelle (1) sur ce site. A l'époque je rejoignais l'entreprise INL (devenu ensuite EdenWall) (2).

Durant ces 3 ans 1/2 j'ai travaillé sur le projet libre EOLE de l'Éducation Nationale (3). EOLE est un ensemble de modules répondant à différent besoins, au départ, de l'Éducation Nationale. En voici quelques-un :

  • Amon : module de contrôle des accès Internet (firewall, Proxy filtrant, ...) ;
  • Scribe : serveur pédagogique (partage de fichier, courriel, ...) ;
  • Eclair : serveur de client léger diffusant des bureaux libres.

L'ensemble du projet est libre et ouvert.

J'ai beaucoup apprécié de travailler sur ce projet. Il est nécessaire d'avoir une variété de compétences et l'ambiance de travail est agréable.

Edenwall vient d'être liquidé et à ce titre ... j'ai été licencié.

Dijon n'est pas forcement le meilleur endroit pour trouver un travail intéressant. Nous avons donc décider de monter une boîte pour proposer notre expertise EOLE. J'espère également pouvoir faire des offres autour de la solution libre Gaspacho (4).

Cette boîte est une SCOP à responsabilité limité dont je suis le gérant.

Donc si vous voulez une prestation EOLE, une formation, du Gaspacho ou du logiciels libres à Dijon ou ailleurs ... il y a Cadoles !

  1. http://www.gnunux.info/dotclear2/index.php?post/2008/01/31/249
  2. http://www.gnunux.info/dotclear2/index.php?post/2008/02/10/250
  3. http://eole.orion.education.fr
  4. http://www.gaspacho-project.net

lundi, juillet 18 2011

Présentation d'EOLE au RMLL 2011

J'ai présenté EOLE au RMLL 2011.

Je mets à disposition le support de présentation.

http://gnunux.info/dotclear2/public/eole.pdf

Présentation de Gaspacho au RMLL 2011

J'ai présenté Gaspacho au RMLL 2011.

Je mets à disposition le support de présentation. Le support est au format SVG. Il faut l'ouvrir avec un lecteur SVG capable d'interpréter le javascript (comme Firefox par exemple). Attention, il faut attendre un peu le chargement du document.

http://gnunux.info/dotclear2/public/gaspacho/gaspacho.svg

samedi, juillet 2 2011

Mécanisme de "clef obligatoire" par utilisateur avec dconf (GNOME 3)

Contrairement à GNOME 2, GNOME 3 n'utilise plus GConf pour gérer les éléments de configuration.

Maintenant c'est Gsettings. Gsettings est en réalité une API de configuration. Le stockage des configurations se fait par un backend.

Sous GNU/Linux, le backend est dconf.

Avec GConf il était facile d'avoir des clefs obligatoires avec le mécanisme des mandatories. Avec dconf c'est un peu plus compliqué.

La configuration de dconf est séparée en deux parties :

  • les profiles ;
  • les bases de données.

Les profiles

Les profiles servent a mettre en relation des configurations et les bases de données. Le profile par défaut est user.

Par défaut, les profiles sont dans le répertoire /etc/dconf/profile/. Ce sont des fichiers de la forme :

database1
database2

La valeur database1 correspond au nom de la base de données utilisateur (généralement dans ~/.config/dconf/). La valeur database2 correspond au nom de la base de données système (généralement dans /etc/dconf/db/). La base de données utilisateur sera prioritaire.

La base de données utilisateur

Pour modifier la base de données utilisateur, le plus simple est d'utiliser la commande dconf :

# dconf write path value

Pour lire la valeur :

# dconf read path

Pour lister les valeurs :

# dconf list path

Par exemple :

# dconf write /org/gnome/gnome-screenshot/delay 16
# dconf read /org/gnome/gnome-screenshot/delay
# dconf list /org/gnome/gnome-screenshot/

La base de données système

Pour modifier la base de données système, le plus simple est de faire des fichiers plats (type INI).

Pour cela, il faut faire une fichier du nom de la base de données dans le répertoire /etc/dconf/db/ avec l'extension .d.

Dans notre cas, nous ferons le répertoire /etc/dconf/db/database2.d/. À l'intérieur nous ferons des fichiers avec l'ensemble des paramètres :

[path]
key=value

Les clefs obligatoires

Dans le répertoire de la base de données système, il faut faire un répertoire locks avec une série de fichiers contenant le chemin des clefs obligatoires de la forme :

path

Clefs obligatoires par utilisateur

Il est envisageable d'avoir des clefs obligatoires par utilisateur si nous créons un profile et une base par utilisateur. Ce profile sera associé à l'utilisateur au démarrage de la session.

Pour cela, il faut ajouter dans le fichier de configuration de bash quelque chose comme cela :

readonly DCONF_PROFILE=nomprofile
export DCONF_PROFILE

Par contre, utiliser le nom d'utilisateur comme nom de profile n'est pas forcement une bonne idée, en effet il y a des restrictions importantes dans le nom du profile : il doit être de type alphanumérique ou "_".

Exemple d'utilisation

Dans /etc/bashrc :

if [ -e /etc/dconf/profile/$UID ]; then
    readonly DCONF_PROFILE=$UID
    export DCONF_PROFILE
fi

Création du fichier : /etc/dconf/profile/500 (pour l'utilisateur avec l'uid 500) :

user
500

Le fichier /etc/dconf/db/500.d/delay contient :

[org/gnome/gnome-screenshot]
delay=16

Le fichier /etc/dconf/db/500.d/locks/delay contient le chemin :

/org/gnome/gnome-screenshot/delay

lundi, mai 16 2011

Copier n'est pas voler

"Copier n'est pas voler" est le titre d'un documentaire monté par l'association COAGUL (1).

Tout part d'une réunion de préparation des 10 ans de l'association. Au moment de lister les possibilités d'événement on a ressorti une ancienne idée : pourquoi pas faire une projection/débat à cinéma d'art et essai l'Eldorado (2) ?

Puis vint le problème de la projection ... quoi projeter ? "Nom de code : linux" (3) ? Bof, ancien, trop technique. Les films d'animation de la fondation Blender (4) ou "Sita Sings The Blues" (5) ? Bof, intéressant du côté technique mais n'apportent pas d'élément au débat. ...

Rien de bien adapté à nos besoins. Vient alors l'inévitable ... nous prenons la décision de monter notre propre documentaire. Et ca sera sur le thème "Copier n'est pas voler" (cool, le générique de début est tout trouvé ... la "Copyright Song" (6)).

Dans la tradition du logiciel libre (ne pas réinventer la roue) nous partons à la recherche de séquences vidéos. Le montage débute à partir du documentaire "The Revolution Will Be Animated" de Marine Lormant Sebag (7), auquelle nous ajoutons un grands nombres d'intervention.

L'ensemble du montage se fera, évidement, avec des logiciels libres.

Dans la tradition du logiciel libre, vous pouvez le télécharger.

  1. http://www.coagul.org/
  2. http://cinema-eldorado.fr/
  3. http://fr.wikipedia.org/wiki/Nom_de_code_:_Linux
  4. http://www.blender.org/blenderorg/blender-foundation/
  5. http://gnunux.info/dotclear2/index.php?post/2010/11/13/Sita-Sings-The-Blues-en-VOST-avec-mplayer
  6. http://www.framablog.org/index.php/post/2009/03/22/the-copyright-song-nina-paley
  7. http://vimeo.com/8768785

samedi, janvier 1 2011

Gamine 1.1 - Happy new year

Voici donc une nouvelle version de Gamine, la version 1.1 (autrement appelé "Happy new year"). Pour rappel, Gamine est une application simple pour que l'enfant puisse appréhender l'usage de la souris et l'usage du clavier. L'idée de départ était de développer une application reprenant les concepts de l'ardoise magique.

Une ensemble de modifications ont été apportées à l'application;

Première modification, il est possible de traduire les messages et le "menu" de Gamine. Pour l'instant, seuls l'anglais et le français sont pris en charge. Si quelqu'un veut soumettre d'autres traductions. Ne pas hésiter.

Il y avait un bug assez gênant sur la version 1.0. Si l'enfant appuyait longtemps sur une touche du clavier, une succession de sons et de lettres colorées apparaissaient. Cela produisait rapidement une charge système importante. J'ai désactivé la répétition du clavier dans Gamine.

Le curseur de la souris est maintenant modifié. Une crayon apparaît à la place du curseur configuré par défaut.

Enfin, j'ai essayé de prévenir le changement de bureaux, le changement d'applications (alt-tab), ... le plus possible. Si votre enfant arrive encore à changer d'application (en dehors de la touche Échappe) merci de le signaler.

Il est possible se sauvegarder une image en tapant la touche "Impression d'écran" du clavier. Les images sont créées dans le répertoire $HOME/gamine de l'utilisateur avec comme nom la date et l'heure.

Il faut ajouter à cela une grosse réoganisation du code et quelques corrections de bugs.

Un fichier .spec et un répertoire debian/ ont été ajoutés pour pouvoir construire des paquets RPM ou DEB.

La prochaine version aura pour but de passer à GTK 3 et Gsettings. Si vous avez d'autres suggestions ne pas hésiter à laisser un commentaire.

Pour télécharger Gamine : http://gnunux.info/projets/gamine/.

Bon, maintenant est temps de laisser la place à votre enfant sur l'ordinateur !

vendredi, novembre 26 2010

OpenStreetMap et Wikipédia

Cela faisait un bon moment que l'annonce avait été faite. Wikipédia met en avant les cartes OpenStreetMap !

C'est une excellente nouvelle.

Les articles correctement géo-taggés auront un lien "Carte" en haut à droite de l'article.

C'est le cas, notamment, de l'article de Dijon : http://fr.wikipedia.org/wiki/Dijon.

Plus d'informations : http://www.ecrans.fr/Wikipedia-tire-ses-cartes,11412.html

samedi, novembre 13 2010

Sita Sings The Blues en VOST avec mplayer

Sita Sings The Blues ?

Écrit et réalisé par Nina Paley, Sita Sings The Blues est un film d'animation américain de 1h22mn. Le film remporte le Cristal du long métrage (le premier prix) au Festival international du film d’animation d’Annecy en 2008.

Entièrement réalisé, scénarisé, animé et monté par Nina Paley, Sita Sings The Blues mélange quatre styles différents et des techniques d’animation différentes (dessins, papiers découpés, ordinateur 2D, utilisation d’images libres de droits…).

De plus, le film mélange deux histoires différentes :

Film d'animation libre

Sita Sings The Blues est un film d'animation distribué sous une licence Creative Commons By-Sa. Nina Paley renforce cette licence en interdisant explicitement l'usage de système Digital Restrictions Management (DRM).

Sauf que ... le film est aussi une comédie musicale avec des chansons de l'interprète de jazz Annette Hanshaw. Ces chansons datent de la fin des années… 1920. Nina Paley pensa légitimement qu’elles étaient désormais dans le domaine public. Mais c’était sans compter sur des subtilités juridiques. Les enregistrements sont bien dans le domaine public mais ce n’est pas le cas de la composition, paroles et musiques (partitions).

Plus d'informations :

Film et sous-titrage avec mplayer

  1. Téléchargement de la vidéo
  2. téléchargement du sous-titre français
  3. pour que le sous-titre fonctionne avec mplayer il faut que le fichier srt ait le même nom que le fichier vidéo. J'ai eu un soucis d'encodage, résolu en faisant : iconv -f iso8859-1 -t utf8 Sita_Sings_The_Blues_FRENCH.srt -o Sita_Sings_the_Blues_640x360_XviD.srt
  4. lancement de mplayer avec la police Libération (plus sympa que la police par défaut) : mplayer Sita_Sings_the_Blues_640x360_XviD.avi -font 'Liberation Serif:style=Bold' -utf8

Dernière version RC de Gaspacho avant la version 0.1

Je viens de mettre en ligne la dernière version RC de Gaspacho 0.1.

Gaspacho est une application libre (GNU/GPL v3) offrant à l'administrateur la possibilité de gérer, de façon centralisée, la configuration de l'environnement de travail des utilisateurs d'une entité.

J'encourage tout le monde à tester cette version pour permettre la meilleure version stable possible.

Tester veux dire :

  • installer le projet et faire de retour sur le sujet ;
  • tester l'interface web ;
  • lire la documentation en ligne.

C'est aussi l'occasion de préparer l'avenir en faisant des suggestions d'améliorations, de nouvelles fonctionnalités, ...

Plus d'informations sur Gaspacho sur le site du projet : http://www.gaspacho-project.net/.

N'hésitez pas à laisser des commentaires pour poser des questions, remarques, ...

Je cherche également une forge de développement supportant git. Si vous avez des idées ...

mardi, octobre 5 2010

"Celle-ci sera centrée sur Ubuntu, afin de ne pas faire doublon avec la COAGUL"

CE TEXTE NE REPRÉSENTE QUE CELUI QUI L'A ÉCRIT

Voici la justification principale lors de la réunion de création de l'association Ubuntu-Dijon (1) : "Celle-ci sera centrée sur Ubuntu, afin de ne pas faire doublon avec la COAGUL".

En effet, j'avais essayé de convaincre les autres participants de cette réunion d'organisation du premier LibrexpOS de ne pas créer un second groupe d'utilisateur de logiciel libre à Dijon.

Peine perdu, le second GULL Dijonnais était né.

Ce qui pouvait être considéré comme un "pacte de non agression" a bien évidement volé en éclat rapidement.

On m'a souvent sorti l'argument "nous avons une autre façon de présenter le libre". Encore une fois, cet argument ne tiens au vu des faits.

En effet, lorsque je lis l'interview des membres d'Ubuntu-Dijon (2), je ne vois aucune différence de discours ! Nous sommes loin du "pragmatisme" affiché :

"Il s'agit aussi de s'extraire d'une logique mercantile, où tout va être breveté, vers un retour de l'échange et du partage avec le pouvoir de redistribuer à la communauté ce qu'elle nous a apporté".

"L'idée la plus forte est la liberté de choix de l'utilisateur, concept qui est assez opposé à celui de marques comme Apple ou Microsoft, qui font tout pour "guider" les utilisateurs dans leurs choix".

"Nous sommes dans la logique du logiciel propriétaire étendu aux matériels."

Encore une fois, je trouve ahurissant qu'une ville de 151 543 habitants (3) se trouve avec deux GULL. Loin d'être bénéfique, cette situation apporte confusion, éparpillement des forces et baisse la crédibilité général des deux groupes.

Conclusion : c'est le problème de tous les doublons ... tout le monde y perd. Mais nous ne sommes pas à l'origine de cette situation, nous la subissons et c'est grotesque !

  1. http://wiki.ubuntu-dijon.org/doku.php?id=reunion:reu080201cr#vi_divers
  2. http://www.dijonscope.com/007977-les-logiciels-libres-a-l-assaut-d-apple-et-microsoft
  3. http://fr.wikipedia.org/wiki/Dijon

vendredi, septembre 24 2010

Les choix Gaspacho

Le choix est l'élément central de Gaspacho. Sans choix ... il n'y a aucun intérêt de l'utiliser.

Le choix est le lien entre la règle (1 et 2) et le groupe (3).

Le choix

Le choix est donc la configuration particulière d'une règle pour un groupe ou un template (et éventuellement le groupe d'utilisateur).

Pour un groupe ou un template il est possible de définir des choix pour les règles machines et les règles utilisateurs. Par contre, pour un groupe d'utilisateur, seul les règles utilisateurs sont paramétrables.

Si le règle n'est pas de type booléen, une valeur devra être définit en plus du choix.

Les choix

En réalité, il n'y pas un choix possible par règle mais trois :

  1. choix libre : c'est l'utilisateur qui choisit le paramétrage de cette option (c'est la valeur par défaut) ;
  2. choix imposé désactivé : c'est l'administrateur qui choisit le paramétrage en la désactivant ;
  3. choix imposé activé : c'est l'administrateur qui choisit le paramétrage en l'activant ;

La valeur de la règle ne sera utile que lorsque le choix est imposé et activé.

Exemple avec l'activation du proxy :

  1. choix libre : l'utilisateur active ou désactive le proxy à sa convenance ;
  2. choix imposé désactivé : l'administrateur impose la désactivation du proxy ;
  3. choix imposé activé : l'administrateur impose l'activation du proxy et le configure suivant le paramétrage prédéfini.

Le choix et l'héritage

Lorsqu'on parle d'héritage, cela concerne bien évidement uniquement les choix. Le premier choix détecté dans l'héritage sera appliqué à l'utilisateur.

Donc pour un groupe il y deux états pour la règle :

  1. l'administrateur a spécifié un choix : il s'applique ;
  2. l'administrateur n'a pas spécifié de choix : c'est le choix hérité qui s'applique ;

Si l'administrateur n'a pas spécifié de choix pour les groupes hérités ou les templates hérités, c'est le choix par défaut, choix libre, qui s'applique.

Liens :

  1. http://gnunux.info/dotclear2/index.php?post/2010/09/17/Les-regles-dans-Gaspacho
  2. http://gnunux.info/dotclear2/index.php?post/2010/09/18/Proprietes-des-regles-Gaspacho
  3. http://gnunux.info/dotclear2/index.php?post/2010/09/18/Les-groupes-Gaspacho

samedi, septembre 18 2010

Les groupes Gaspacho

Après avoir présenté les règles Gaspacho (1 et 2), il faut s'attarder sur la notion de groupe.

Si l'administrateur ne devrait pas avoir besoin de gérer lui même les règles (sauf si la règle dont il a besoin n'existe pas encore), il devra créer les groupes.

Un groupe est un ensemble de machines disposant des mêmes configurations. Il est possible d'associer des utilisateurs pour différencier les configurations suivant le profile de la personne qui se connecte à la machine.

Les groupes

Un groupe est d'abord un libellé. Il est directement visible dans l'interface de configuration.

Pour limiter le nombre de règles disponible, ce groupe peut être lié à un ou plusieurs systèmes ou un ou plusieurs logiciels. Dans ce cas, seuls les règles concernant ces logiciels ou systèmes seront proposées.

Enfin, pour classer les groupes, un niveau est associé à ce groupe. En effet, le première groupe qui comprends aux critères de la machine se connectant sera le groupe de la machine. Il est alors important de pouvoir les classer.

Les groupes de machine

Une fois défini, le groupe est lié à un ensemble de machines. Un machine est décrite soit par son adresse IP, soit par son nom DNS. Dans le nom DNS ou l'IP il est possible d'utiliser les motifs inspirés du shell Unix :

*        remplace tout
?        remplace un seul caractère
[seq]    remplace tous caractères dans "seq"
[!seq]   remplace tous caractères en dehors de "seq"

Les utilisateurs ou groupes d'utilisateurs

Le groupe peut également être lié à un ensemble d'utilisateurs. Il est possible de définir des utilisateurs ou des groupes d'utilisateurs. Le nom de l'utilisateur primant sur son groupe primaire.

Si l'utilisateur n'est pas définit ou n'appartient pas aux groupes, il récupèrera les paramétrages du groupe directement

Les templates

En plus des groupes, il existe les templates. Les templates ont les mêmes propriétés qu'un groupe sauf qu'il n'est pas possible de lui associer des groupes de machine. Les templates sont utiles dans le cadre de l'héritage. Les templates peuvent être associés à des groupes différents.

L'héritage des groupes

Le mécanisme d'héritage permet mettre en commun des réglages pour différents groupes.

Exemple d'héritage :

default (None, user1, user2)
   |
   '--group1 (None, user1, user2)
         |
         |--group2 (None, user1, user2)
         |
         template1 (None, user1, user2)

Si l'utilisateur user1 se connecte à group2, le parcours de l'héritage se fera de la manière suivante :

  1. user1 sur group2 ;
  2. group2
  3. user1 sur group1 ;
  4. group1
  5. user1 sur template1 ;
  6. template1 ;
  7. user1 sur default ;
  8. default

Si l'utilisateur n'est pas user1 ni user2 :

  1. group2
  2. group1
  3. template1
  4. default

Le concept de template prend tout son sens. Les groupes ne peuvent hériter que de ses parents alors qu'un template peut concerner plusieurs groupes avec des parents complètement différents.

Liens :

  1. http://gnunux.info/dotclear2/index.php?post/2010/09/17/Les-regles-dans-Gaspacho
  2. http://gnunux.info/dotclear2/index.php?post/2010/09/18/Proprietes-des-regles-Gaspacho

Propriétés des règles Gaspacho

Comme indiqué dans un précédent poste (1), une règle Gaspacho est d'abord un intitulé.

Mais évidement, ce n'est pas que cela.

Les niveaux de règles

Il existe déjà deux niveaux de règles différentes :

  • les règles dites "machines", appliquées au démarrage de la machine quelque soit l'utilisateur s'y connectant ;
  • les règles dites "utilisateurs" qui concernent un utilisateur particulier ou un groupe d'utilisateurs. Elles sont appliquées au démarrage de la session.

Par exemple :

  1. "Autoriser l'arrêt de la machine depuis la fenêtre d'ouverture de session" est une règle machine ;
  2. "Configuration du proxy" est une règle utilisateur.

Les types

Les types de règle

Une fois que le niveau de règle est défini (machine ou utilisateur), il faut choisir son type.

Les types possible sont composés de deux catégories :

  • sans valeur : "boolean"
  • avec valeur : "unicode" (un texte libre), "integer" (un chiffre), "enum" (une liste de choix prédéfinies) et "list" (une liste de choix libres).

Les types sans valeurs sont les plus simple. Par exemple cette règle n'attend aucune valeur particulière :

"Vérifier que Firefox est le navigateur par défaut"

Alors que celle-ci attend une adresse IP :

"Configuration du serveur proxy manuelle"

Il existe un autre type ("multi") qui permet de mêler plusieurs types. Je n'entrerais pas dans les détails dans ce billet.

Il s'agit bien de définir ici le type de la règle (et uniquement de la règle).

Les types de variables

Le type de la règle n'agit en rien sur les types des variables associées à la règle.

Par exemple, la configuration du proxy (type unicode) sous GNOME configure trois variables de types différents :

  1. /system/http_proxy/use_http_proxy de type boolean ;
  2. /system/http_proxy/host de type unicode ;
  3. /system/http_proxy/port de type integer.

Les valeurs

Valeurs par défaut des règles

Chaque règle avec valeur peut contenir une valeur par défaut. Celle-ci sera proposée à l'activation de la règle. Si cette valeur ne lui convient pas, il aura bien évidement le loisir de la modifier.

Les valeurs "activées" et "désactivées" des variables

Je présenterais en temps voulu la notion de "activé" et "désactivé" d'une variable. Il faut juste savoir que l'on peut associer une valeur fixe à une variable.

Par exemple, lors de l'activation du proxy sous GNOME, la variable "/system/http_proxy/use_http_proxy" aura comme valeur "True". L'utilisateur n'interagit pas directement sur cette valeur.

En cas de règle avec valeur, il est possible qu'une variable ne récupère par la valeur défini par l'utilisateur (comme le montre l'exemple juste avant). Si la variable doit récupérer la valeur, il suffit de ne pas spécifier de valeur pour la variable en question.

  1. http://gnunux.info/dotclear2/index.php?post/2010/09/17/Les-regles-dans-Gaspacho

vendredi, septembre 17 2010

Les règles dans Gaspacho ?

Une règle, dans Gaspacho, est simplement (pour schématiser) un libellé.

Par exemple "Configuration du serveur proxy manuelle" est une règle.

Évidement, la règle en elle même ne sert a rien. Il faut lui associer des éléments de configuration.

Avant d'expliquer comment cela fonctionne, voici des exemples de configuration du proxy. On peut voir qu'il existe une variété de formats de fichiers de configuration.

  • Configuration du proxy sous Windows avec des clefs de registre :
  1. activation du proxy : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyEnable : 1 ;
  2. configuration du proxy : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyServer : 192.168.1.1:3128 :
  3. mise en place d'une restriction sur la modification du paramétrage du proxy : HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel\Proxy : 1.
  • Configuration du proxy sous Mozilla Firefox avec un fichier javascript utilisateur.js (1) :
  1. activation du proxy : lockPerf("network.proxy.type", "1"); ;
  2. configuration de l'IP du proxy : lockPerf("network.proxy.http", "192.168.1.1"); ;
  3. configuration du port du proxy : lockPerf("network.proxy.http_port", "3128");.
  • Configuration du proxy sous GNOME avec des clefs gconf :
  1. activation du proxy : /system/http_proxy/use_http_proxy True ;
  2. configuration de l'IP du proxy : /system/http_proxy/host "192.168.1.1" ;
  3. configuration du port du proxy : /system/http_proxy/port 3128.
  • Configuration du proxy sous OpenOffice.org avec le fichier XML ~/.ooo3/user/registry/data/org/openoffice/Inet.xcu :
<?xml version="1.0" encoding="UTF-8"?>
<oor:component-data xmlns:oor="http://openoffice.org/2001/registry" xmlns:xs="http://www.w3.org/2001/XMLSchema" oor:name="Inet" oor:package="org.openoffice">
 <node oor:name="Settings">
  <prop oor:name="ooInetProxyType" oor:type="xs:int">
   <value>2</value>
  </prop>
  <prop oor:name="ooInetHTTPProxyName" oor:type="xs:string">
   <value>192.168.10.1</value>
  </prop>
  <prop oor:name="ooInetHTTPProxyPort" oor:type="xs:int">
   <value>8080</value>
  </prop>
 </node>
</oor:component-data>

Gaspacho devra supporter l'ensemble des formats de fichiers de configuration. De plus, il devra gérer les versions des logiciels et les distributions/systèmes d'exploitation.

Pour cela, chaque élément de configuration sera divisé en deux : la variable et la plateforme. La plateforme comprendra le chemin et le système.

Par exemple, nous aurons :

  • variable : ProxyEnable avec la valeur 1 ;
  • plateforme : chemin : HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ et système : Windows XP.

Autre exemple pour OpenOffice.org :

  • variable : ooInetProxyType dans la section Inet/Settings avec la valeur 2 ;
  • plateforme : chemin : ~/.ooo3/user/registry/data/org/openoffice/Inet.xcu et système : Mandriva 2010 + OpenOffice.org 3.2.

Enfin, ces règles sont classés dans des "tags" eux-mêmes classés dans des "catégories".

Ici, cette règle sera dans la catégorie "Réseau" et dans le tag "Configuration du proxy".

  1. http://gnunux.info/dotclear2/index.php?post/2010/08/30/Mecanisme-de-clef-obligatoire-par-utilisateur-sous-Mozilla-Firefox

- page 1 de 16