Skip to content

introduce API with devise_token_auth for absence creation

Vincent Agnano requested to merge feature/api-absences into master

Created by: adipasquale

https://trello.com/c/HT5A8XUE/1086-api-entrante-pour-les-absences

La doc allant avec cette nouvelle API a été rédigée et publiée en avance de phase sur https://doc.rdv-solidarites.fr/technique/api . Mieux vaut parcourir cette doc avant de review cette PR

Choix

  • utilise https://github.com/lynndylanhurley/devise_token_auth qui semble être populaire et à peu près maintenue, mais pas parfaite, voir plus bas. La doc (https://devise-token-auth.gitbook.io/devise-token-auth) est bien rédigée mais pas très complète
  • le Gemfile pointe vers le github de la gem pour recuperer la version 1.1.4 de cette gem qui retire la dépendance à sprockets
  • par défaut la gem rafraîchit l'access-token à chaque requête. Les clients utilisant l'API doivent donc coder cette logique pour utiliser l'access-token de la réponse précédente. Par souci de simplification pour l'instant, j'ai désactivé ce rafraîchissement automatique.
  • Pour balancer cette baisse de la sécurité, j'ai par contre diminué le temps de validité d'un token. Par défaut il est à 2 semaines, je l'ai réduit à 1 jour. Cela signifie que les clients devront récupérer un nouveau token d'accès via la route /api/v1/auth/sign_in toutes les 24h . cela me parait acceptable, surtout pour les premiers usages qui seront des imports ponctuels d'absences
  • Je m'appuie sur les policies existantes, ce qui me semble la meilleure option pour maintenir la cohérence des droits d'accès entre l'interface web et l'API. J'ai du "améliorer" un peu AbsencePolicy pour supporter l'absence d'organisation dans les contextes pundit, je trouve ça plus clair et agréable que la route /api/v1/absences ne soit pas nécessairement scopée par orga, mais que ça soit un param de filtrage optionnel

Concern DeviseTokenAuth::Concerns::User

Le concern DeviseTokenAuth::Concerns::User à ajouter sur le modèle de la gem fait beaucoup de choses et override des comportements de devise. Je n'arrivais pas à tout faire fonctionner en l'incluant directement dans Agent. Entre autres, ca demandait de renommer les routes agent_registration_path qui faisaient des conflits, et d'autres soucis divers.

Pour éviter que ça ne casse des comportements de devise sur le modèle existant, j'ai créé un modèle distinct class AgentWithTokenAuth < Agent dans lequel j'inclus ce concern.

Je dois tout de même inclure deux concerns dans Agent :

include DeviseTokenAuth::Concerns::ConfirmableSupport
include DeviseTokenAuth::Concerns::UserOmniauthCallbacks

Le deuxième est important car c'est lui qui s'assure que uid reste synchronisé avec l'email des agents.

Points d'inquiétudes / défauts

  • on est obligés d'ajouter 4 champs sur les agents et on ne peut pas modifier les noms qui ne sont pas très explicites : provider, uid, tokens, allow_password_change`
  • la gem n'a pas l'air complètement compatible avec Rails 6 cf issue https://github.com/lynndylanhurley/devise_token_auth/issues/1425
  • La gem modifie le callback path d'omniauth et je n'arrive pas a reprendre la main dessus. pour verifier que la super admin fonctionne toujours, j'ai du modifier le callback path sur l'app de dev (temporairement) : https://github.com/organizations/rdv-solidarites/settings/applications , de http://localhost:5000/super_admins/auth/github/callback vers http://localhost:5000/omniauth/github/callback

Outils utiles

Pour review avec httpie sur la demo app

# sign_in and get header values
http --json POST 'https://demo-rdv-solidarites-pr946.osc-secnum-fr1.scalingo.io/api/v1/auth/sign_in' \
  email='martine@demo.rdv-solidarites.fr' password='123456'

# list absences
http 'https://demo-rdv-solidarites-pr946.osc-secnum-fr1.scalingo.io/api/v1/absences' \
  uid:martine@demo.rdv-solidarites.fr access-token:XXXXX client:XXX 

# create absence
http --json POST 'https://demo-rdv-solidarites-pr946.osc-secnum-fr1.scalingo.io' \
  access-token:XXXXX client:XXX uid:'martine@demo.rdv-solidarites.fr' \
  organisation_id=1 agent_id=1 title="Congé parental" \
  first_day="2020-11-20" start_time="08:00" \
  end_day="2020-11-20" end_time="18:00"

Merge request reports