Implémentation de la 2FA

#1

J’ouvre ce ticket pour discuter de l’implémentation de la 2FA dans Kresus. J’ai commencé à produire du
code pour:

  • récupérer la session depuis Weboob
  • attraper la bonne erreur levée par Weboob (incluant les champs à remplir)
  • la transmettre à Kresus.

Pour les gens que ça interéresse, c’est là que ça se passe: https://framagit.org/ZeHiro/kresus/tree/storage-example
Même si l’API entre Kresus et Weboob devra être discutée et analysée j’ai du code qui fonctionne.

Reste à Kresus d’en faire bon usage, et c’est là que tout se complique :slight_smile:

Je commence donc ce fil pour lister les besoins et ouvrir la discussion sur les usages et l’implémentation.

Usage

L’implémentation doit gérer les cas suivants :

  • Création d’un accès lorsqu’aucun accès n’existe (Kresus neuf)
  • Création d’un accès lorsque d’autres accès existent
  • L’utilisateur demande de récupérer les comptes (via le panneau Paramètres)
  • L’utilisateur demande de récupérer les opération (via le panneau Rapports)
  • L’utilisateur demande de synchroniser le solde d’un compte (via le panneau Paramètres)

Pour chacune des ces situations, l’application devra gérer les sous cas suivants :

  • Le succès de l’action
  • L’échec de l’action
  • L’interruption de l’action.

Par interruption, je veux dire :

  • L’utilisateur n’a pas saisi l’OTP dans les temps.
  • L’utilisateur a rechargé la page avant de saisir l’OTP (ça peut arriver)
  • Le client web (ou le serveur) a planté avant la saisie de l’OTP (ça peut aussi arriver)

Pour l’interruption, j’anticipe de réels problèmes d’implémentation que pour les cas de création de compte (notamment pour la sauvegarde/suppression de l’accès en cours de création). En effet, pour tout ce qui a trait à la mise à jour des accès, l’interruption ne devrait pas poser de problème d’état (il y a des comptes bancaires associés à l’accès: le client Kresus sait gérer cette situation).

Implémentation

Weboob

Weboob lève une exception BrowserQuestion associé à une liste de champs à compléter par l’utilisateur. Dans le cas des modules bancaires, il n’est question que du code OTP.
Le script main.py retourne à Kresus l’erreur levée par Weboob ainsi que les champs à renseigner. L’état du navigateur (incluant les cookies par exemple) est aussi retourné à Kresus.

Serveur Kresus

Cas sans OTP

Actuellement, sans OTP, si une erreur est levée lors de la création d’un compte ou lors de la première récupération des comptes ou opération (mauvais MDP par exemple), le serveur supprime l’accès.

Avec OTP

Le temps que l’utilisateur saisisse l’OTP, il est nécessaire de garder trace de :

  • données de connexion (banque, login, MDP, éventuels autres champs saisi par l’utilisateur)
  • les données de navigation (données de session, cookies etc)

Ceci est nécessaire pour les retransmettre à weboob lors de la saisie de l’OTP (les modules ont besoin de toutes ces données pour s’authentifier correctement).

La politique actuelle est de ne jamais retransmettre les mot de passe au client. Les données de session ne devraient non plus pas lui être transmises, pour des raison évidente de sécurité (réutilisation du cookie directement dans le navigateur). Le maintient dans la base de donnée de l’accès (sans comptes bancaires) est donc nécessaire. Se pose alors la question de quand supprimer l’accès en cas d’interruption.
Je propose les conditions suivantes :

  • suppression de l’accès en cas d’erreur différente de BrowserQuestion et aucun compte bancaire attaché.
  • suppression de l’accès lorsque la requête /all est appelée, et que l’accès n’a aucun compte bancaire attaché (ces deux informations sont disponibles lors de l’exécution de la requête /all).

Le poll automatique (chaque nuit) devra être désactivé pour les comptes levant BrowserQuestion.

Client Kresus

Sans OTP

Gestion des accès sans compte.

Si aucun compte bancaire (il me semble qu’il peut y avoir un accès sans compte) n’est présent dans le client, la page de démarrage est proposée à l’utilisateur.
S’il y a au moins un compte bancaire dans l’état, je ne sais pas comment se comporte le client avec les accès sans compte bancaire.

Saisie de l’OTP

Non applicable.

Avec OTP

Gestion des accès sans compte.

Lors de la création de l’accès, le client devra, au moins temporairement, accepter un accès sans compte, le temps de la saisie de l’OTP par l’utilisateur.

Saisie de l’OTP

A la réception d’une erreur BROWSER_QUESTION et une liste de champ à saisir, le client doit demander à l’utilisateur de saisir d’OTP.
S’il n’y a pas encore de compte bancaire dans le système, via une nouvelle page (/init/new-bank/enter-new-fields.
S’il y a déjà des comptes bancaires dans l’état total du client, via une modale. Ceci est valable pour la création d’un accès ou pour le rafraichissement des opérations ou des comptes.
Cliquer sur annuler ou cacher la modale doit interrompre le processus et supprimer l’accès côté client et côté serveur.

Interface client/serveur

Les endpoints actuels :

  • /accesses/:accessId/fetch/accounts
  • /accesses/:accessId/fetch/operations
  • /accounts/:accountId/resync-balance

doivent pouvoir accepter des paramètres depuis le client (le code OTP dans ce cas), a priori via une requête PUT.
La saisie de l’OTP lors de la création d’un accès doit transiter par l’endpoint /accesses/:accessId/fetch/accounts, vu qu’il permet de récupérer à la fois les comptes et les opérations.
Pour les autres cas d’usage, le même endpoint est à utiliser (par rapport au cas sans OTP)