Ajout de l’authentification One-Time-Password à taiga.io

La nouvelle version de taiga.io avec docker inclus un installateur bien simplifié.

Il me parait utile d’y ajouter simplement l’authentification OTP qui permet d’accepter le mot de passe ajouté avec 6 chiffres calculé par l’horloge à partir d’un code. Vous trouverez des explications sur ce processus dans cet article: https://en.wikipedia.org/wiki/One-time_password

Le seul fichier à éditer pour inclure l’OTP dans taiga est le fichier /taiga-back/taiga/users/services.py dans le containeur taiga-docker_taiga-back_1.

En premier lieu, il faut ajouter au containeur taiga-docker_taiga-back_1 le module pyotp:

docker exec -it taiga-docker_taiga-back_1 pip install pyotp

Ensuite on peut copier sur la machine hôte le fichier services.py pour y ajouter l’OTP:

docker cp taiga-docker_taiga-back_1:/taiga-back/taiga/users/services.py  services.py 

Nous pouvons donc éditer le fichier services.py pour y adjoindre et modifier le programme, en premier lieu en important le module pyotp avant toutes les fonctions:

import pyotp

Puis on va chercher la fonction get_and_validate_user qui a cette forme:

def get_and_validate_user(*, username: str, password: str) -> bool:
    """
    Check if user with username/email exists and specified
    password matchs well with existing user password.

    if user is valid,  user is returned else, corresponding
    exception is raised.
    """

    user = get_user_by_username_or_email(username)


    if not user.check_password(password) or not user.is_active or user.is_system:
        raise exc.WrongArguments(_("Username or password does not matches user."))

    return user

Nous allons ajouter l’extraction des 6 derniers symboles du mot de passe pour trouver le code PIN à valider par OTP avec le code fourni en paramètre. Donc la nouvelle version de la fonction get_and_validate_user

def get_and_validate_user(*, username: str, password: str) -> bool:
    """
    Check if user with username/email exists and specified
    password matchs well with existing user password.

    if user is valid,  user is returned else, corresponding
    exception is raised.
    """

    user = get_user_by_username_or_email(username)

    """
    PJE   verification OTP
    """
    totp = pyotp.TOTP("base32secret3232")
    passwordPIN = password
    password = passwordPIN[:-6]
    pin = totp.verify( passwordPIN[-6:] , valid_window=2 )
    if pin is False:
        raise exc.WrongArguments(_("Username or password does not matches user PIN."))

    """
    / PJE   verification OTP
    """


    if not user.check_password(password) or not user.is_active or user.is_system:
        raise exc.WrongArguments(_("Username or password does not matches user."))

    return user

En incluant dans la fonction d’authentification, l’extraction des 6 derniers symboles fournis par l’utilisateur, on peut ajouter une authentification avec code OTP. On note une nouvelle exception envoyé par le serveur en cas d’erreur sur le code PIN.

NOTA: je pensais avoir un problème de Timezone dans le containeur mais au final, je pense que c’est valide comme installation. J’ai testé quelques solutions de changement dans le containeur de timezone mais finalement je pense que je peux aussi m’appuyer sur l’argument for_time de la fonction verify : https://pyauth.github.io/pyotp/_modules/pyotp/totp.html#TOTP.verify

A propos Pierre Jean

Ingénieur de Recherche CERIS Centre d'Enseignement et de Recherche en Informatique et Systèmes IMT Mines Alès UMR Euromov DHM Plus de détails sur Pierre JEAN
Ce contenu a été publié dans Développement. Vous pouvez le mettre en favoris avec ce permalien.