Perles de Mongueurs - Conversion de dates

Magazine
Marque
GNU/Linux Magazine
Numéro
123
Mois de parution
janvier 2010


Résumé
Depuis le numéro 59, les Mongueurs de Perl vous proposent tous les mois de découvrir les scripts jetables qu’ils ont pu coder ou découvrir dans leur utilisation quotidienne de Perl. Bref, des choses trop courtes pour en faire un article, mais suffisamment intéressantes pour mériter d’être publiées. Ce sont les perles de Mongueurs.

Body

1. Conversion de dates

Le système des shadow passwords (cf shadow(5)) permet de renforcer la sécurité d'un système Unix en séparant les informations sensibles des comptes utilisateurs, c'est-à-dire les mots de passe, des informations publiques telles que les identifiants numériques (UID) ou les répertoires personnels (home directory). Ce système permet également de gérer le renouvellement du mot de passe, ainsi que son expiration, entraînant de fait l'invalidation du compte associé. Ceci permet de mettre facilement en place une politique d'attribution de comptes informatiques pour une durée limitée, par exemple celui du séjour d'un étudiant au sein d'un laboratoire de recherche.

Néanmoins, et aussi bizarre que cela paraisse, tout le monde ne compte pas couramment les dates à partir du premier janvier 1970, et les demandes d'ouverture de compte expriment assez rarement cette durée de validité sous cette forme, qui est pourtant celle attendue par la spécification des shadow passwords... Il s'ensuit donc des besoins de conversion assez récurrents, qui m'ont poussé à écrire un script dédié.

1.1 Le choix du module

Comme pour d'autres domaines, il existe de multiples modules dédiés à la gestion des dates et des durées dans le monde Perl :

- Date::Calc ;

- Date::Manip ;

- Class::Date ;

- etc.

Trop même, puisque cette floraison ne facilite ni la maintenance, ni le choix de l'utilisateur. Le projet DateTime vise donc à réunifier l'ensemble des fonctionnalités au sein d'un nombre réduit de modules à l'interface cohérente. C'est donc l'approche recommandée aujourd'hui pour ce type de besoins.

1.2 L'idée originale...

À l'énoncé de la spécification, la première idée consiste à vouloir considérer ce nombre de jours comme une durée, et donc d'utiliser la classe DateTime::Format::Duration pour la représenter. C'est très simple à faire, effectivement. Malheureusement, le bât blesse au moment de la conversion de cette durée, exprimée dans une unité quelconque, en nombre de jours. En effet, si le nombre d'heures dans une journée est constant, ceci n'est pas vrai pour le nombre de jours dans un mois. Il n'est donc pas possible de convertir une durée comme « un an » en un nombre de jours. Il faut donc faire autrement, et passer par l'approche bas niveau classique : toute date dans le monde Unix est un nombre de secondes écoulées depuis le 1er janvier 1970.

1.3 Et le programme qui marche

On commence par la documentation, ce qui permet d'une part de ne pas l'oublier, d'autre part de spécifier l'interface de l'outil.

    #!/usr/bin/perl

    =head1 NAME

    compute-expiration

    =head1 SYNOPSIS

compute-expiration <format> <date>

    format can be either:

    =over

    =item B<duration>: account duration from now (days/months/years)

    =item B<date>: account expiration date (day/month/year)

    =item B<count>: account expiration date (days count since epoch)

=back

    =cut

On passe ensuite au chargement des modules nécessaires, ainsi que par la définition d'une constante correspondant au nombre de secondes dans une journée.

    use strict;

    use constant SECONDS_BY_DAY => 60 * 60 * 24;

    use feature 'switch';

    use DateTime;

    use DateTime::Format::Duration;

    use DateTime::Format::Strptime;

    use Pod::Usage;

use 5.010;

L'analyse des arguments est triviale, et renvoie à la documentation si ceux-ci sont manquants, grâce à Pod::Usage. On passe ensuite à la partie principale du programme, sous la forme d'une directive given, une des nouveautés de Perl 5.10, permettant de traiter chacun des formats d'entrée.

    my $format = $ARGV[0] || pod2usage("No format given, aborting");

    my $date   = $ARGV[1] || pod2usage("No date given, aborting");

    my ($future, $count);

given($format) {

Dans le premier cas, la date d'expiration est définie par une durée à partir de la date actuelle. La chaîne donnée en entrée, sous la forme « jours/mois/années », est convertie en une instance de la classe DateTime::Format::Duration. La date actuelle, elle, est une instance de la classe DateTime. L'addition des deux, possible grâce à la surcharge de l'opérateur +, fournit une nouvelle instance de la classe DateTime correspondant à la date d'expiration. À défaut de méthode dédiée dans la classe, il suffit alors de convertir cette date en nombre de secondes depuis le 1er janvier 1970, puis de diviser par le nombre de secondes par jour.

En cas d'erreur d'analyse, le programme s'arrête avec un message d'erreur. Celui-ci se termine par un retour chariot, pour éviter l'ajout automatique par la fonction die() de la ligne du programme à laquelle l'erreur se produit. Autant ce genre d'information est intéressante pour un développeur, autant elle concerne peu l'utilisateur final.

        when ('duration') {

            my $now      = DateTime->now();

            my $pattern = DateTime::Format::Duration->new(pattern => '%d/%m/%Y');

            my $duration = $pattern->parse_duration($date);

            die "Unrecognized date pattern $date\n" unless $duration;

            $future = $now + $duration;

            $count = int($future->epoch() / SECONDS_BY_DAY);

}

Dans le second cas, la date d'expiration est donnée directement. Il suffit alors d'analyser la chaîne fournie, grâce à la classe DateTime::Format::Strptime, pour se retrouver dans le cas précédent.

        when ('date') {

            my $pattern = DateTime::Format::Strptime->new(pattern => '%d/%m/%Y');

            $future = $pattern->parse_datetime($date);

            die "Unrecognized date pattern $date\n" unless $future;

            $count = int($future->epoch() / SECONDS_BY_DAY);

}

Enfin, le dernier cas correspond à la traduction du nombre de jours en date. Il suffit d'appliquer l'opération inverse, c'est-à-dire de convertir ce nombre en secondes d'abord, pour obtenir la date ensuite.

        when ('count') {

            $future = DateTime->from_epoch(epoch => $date * SECONDS_BY_DAY);

$count = $date;

        }

Il reste encore à traiter le cas de l'argument incorrect, ne correspondant à aucune des valeurs précédentes, puis à afficher les valeurs calculées précédemment.

        default {

            die "Unknown format $format\n";

        }

    }

    printf "expiration date: %s\n", $future->strftime('%d/%m/%Y');

    printf "days since 1970: %s\n", $count;

Au final, 62 lignes de code (documentation comprise) permettent donc de convertir des dates, exprimées dans des formats différents, sans sacrifier la lisibilité du code, grâce à l'utilisation de modules issus du projet DateTime.

À vous !

Envoyez vos perles à perles@mongueurs.net, elles seront peut-être publiées dans un prochain numéro de Linux Magazine.




Article rédigé par

Par le(s) même(s) auteur(s)

Kerberos, le SSO universel : 1- Présentation et déploiement

Magazine
Marque
GNU/Linux Magazine
Numéro
143
Mois de parution
novembre 2011
Résumé

Kerberos est un protocole d'authentification réseau, qui présente la particularité d'allier à la fois sécurité et confort d'utilisation, puisqu'il s'agit d'un système d'authentification unique (SSO, Single Sign On). À l'heure où fleurissent les articles vantant les mérites des systèmes de type CAS, assurant un service similaire, mais limité aux seules applications web, il paraît intéressant de présenter cette technologie quelque peu méconnue.

Kerberos, le SSO universel : 4- Relation de confiance entre royaumes

Magazine
Marque
GNU/Linux Magazine
Numéro
143
Mois de parution
novembre 2011
Résumé

Jusqu'ici, les exemples présentés concernaient l'accès à des ressources appartenant au même royaume Kerberos que l'utilisateur. Or, ceci n'est pas toujours le cas dans la réalité, lorsqu'il existe plusieurs royaumes Kerberos différents au sein d'une même entité. Cette situation peut être volontaire, les différents royaumes jouant une fonction de cloisonnement, ou non, typiquement lorsqu'un domaine Active Directory est mis en place pour gérer un parc de machines Windows et qu'il vient avec son propre royaume Kerberos.

Kerberos, le SSO universel : 2- Intégration des applications

Magazine
Marque
GNU/Linux Magazine
Numéro
143
Mois de parution
novembre 2011
Résumé

L'intégration des applications à une infrastructure Kerberos, ou kerberisation, peut se faire de deux manières différentes. La première, l'authentification Kerberos à proprement parler, consiste à utiliser le mécanisme décrit précédemment, à base de tickets, entre le client et le serveur (figure 1). Il faut bien évidemment un support explicite pour ce mécanisme au niveau du client et du serveur, mais également dans le protocole utilisé.

Les derniers articles Premiums

Les derniers articles Premium

Stubby : protection de votre vie privée via le chiffrement des requêtes DNS

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Depuis les révélations d’Edward Snowden sur l’espionnage de masse des communications sur Internet par la NSA, un effort massif a été fait pour protéger la vie en ligne des internautes. Cet effort s’est principalement concentré sur les outils de communication avec la généralisation de l’usage du chiffrement sur le web (désormais, plus de 90 % des échanges se font en HTTPS) et l’adoption en masse des messageries utilisant des protocoles de chiffrement de bout en bout. Cependant, toutes ces communications, bien que chiffrées, utilisent un protocole qui, lui, n’est pas chiffré par défaut, loin de là : le DNS. Voyons ensemble quels sont les risques que cela induit pour les internautes et comment nous pouvons améliorer la situation.

Surveillez la consommation énergétique de votre code

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Être en mesure de surveiller la consommation énergétique de nos applications est une idée attrayante, qui n'est que trop souvent mise à la marge aujourd'hui. C'est d'ailleurs paradoxal, quand on pense que de plus en plus de voitures permettent de connaître la consommation instantanée et la consommation moyenne du véhicule, mais que nos chers ordinateurs, fleurons de la technologie, ne le permettent pas pour nos applications... Mais c'est aussi une tendance qui s'affirme petit à petit et à laquelle à terme, il devrait être difficile d'échapper. Car même si ce n'est qu'un effet de bord, elle nous amène à créer des programmes plus efficaces, qui sont également moins chers à exécuter.

Donnez une autre dimension à vos logs avec Vector

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Avoir des informations précises et détaillées sur ce qu’il se passe dans une infrastructure, et sur les applications qu'elle héberge est un enjeu critique pour votre business. Cependant, ça demande du temps, temps qu'on préfère parfois se réserver pour d'autres tâches jugées plus prioritaires. Mais qu'un système plante, qu'une application perde les pédales ou qu'une faille de sécurité soit découverte et c'est la panique à bord ! Alors je vous le demande, qui voudrait rester aveugle quand l'observabilité a tout à vous offrir ?

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous