Projet

Général

Profil

Development #35710

le mot de passe utilisateur n'est pas mis à jour avec l'API update_or_create

Ajouté par Nicolas Roche il y a plus de 4 ans. Mis à jour il y a plus de 4 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Catégorie:
-
Version cible:
-
Début:
30 août 2019
Echéance:
% réalisé:

0%

Temps estimé:
Patch proposed:
Oui
Planning:
Non

Description

A priori il s'agit d'une régression suite à #34950


Fichiers

Révisions associées

Révision aa584ad9 (diff)
Ajouté par Benjamin Dauvergne il y a plus de 4 ans

api: recreate get/update_or_create mixin at the view level (#35710)

Historique

#1

Mis à jour par Nicolas Roche il y a plus de 4 ans

Le pop() faisait que les données passées à update() ne contenaient pas le mot de passe.

#2

Mis à jour par Nicolas Roche il y a plus de 4 ans

  • Statut changé de Solution proposée à En cours

Problème dans les test (merci Thomas)

paylaod = {}

#3

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

Sans le pop ça ne va plus marcher, le password ne doit pas être passé à l'implémentation de base de ModelSerializer qui ne saura pas le gérer.

#4

Mis à jour par Nicolas Roche il y a plus de 4 ans

Peux-tu me donner une piste stp,
j'ai l'impression que tu surcharges les méthodes create et update de l'implémentation de base de ModelSerializer (rest_framework/serializer.py::ModelSerializer) dans api_mixins.py::GetOrCreateModelSerializer.
Je dis-ça parce que je peux rejouer l'ensemble des tests de test_api.py sans rentrer dans aucune de ces 2 fonctions.
(au passage pour moi les tests semblaient valider la solution ?!)

J'ai retiré le pop pour que le mot de passe arrive jusqu'à la méthode upgrade().
Le chemin pour y arriver est un peu alambiqué :
  • api_views.py::create()
  • api_mixins.py::create()
  • api_mixins.py::update_or_create()
  • api_views.py::update()

Voici la trace un peu plus complète :

...
  /home/nroche/src/authentic/tests/test_api.py(1183)test_api_users_get_or_create()
-> resp = app.post_json('/api/users/?update_or_create=email', params=payload, status=201)
...
-> serializer.save()
  /tmp/tox-nroche/authentic/py27-coverage-dj111-authentic-pg-/lib/python2.7/site-packages/rest_framework/serializers.py(192)save()
-> self.instance = self.create(validated_data)
  /home/nroche/src/authentic/src/authentic2/api_views.py(397)create()
-> instance = super(BaseUserSerializer, self).create(validated_data)
  /home/nroche/src/authentic/src/authentic2/api_mixins.py(101)create()
-> return self.update_or_create(keys, validated_data)
  /home/nroche/src/authentic/src/authentic2/api_mixins.py(84)update_or_create()
-> self.update(instance, validated_data)
> /home/nroche/src/authentic/src/authentic2/api_views.py(466)update()
-> instance.set_password(password)

#5

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

En fait ce n'était pas une bonne idée de me placer au niveau du serializer, j'ai refait la fonction get/update_or_create au niveau du ViewSet et c'est plus simple.

#6

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

Benjamin Dauvergne a écrit :

En fait ce n'était pas une bonne idée de me placer au niveau du serializer, j'ai refait la fonction get/update_or_create au niveau du ViewSet et c'est plus simple.

En bonus je gagne un code 200 sur get/update au lieu du 201.

#7

Mis à jour par Nicolas Roche il y a plus de 4 ans

  • Statut changé de Solution proposée à Solution validée
Je dois avouer que pour moi tout ça reste abstrait.
Mais dans les faits, moyennant un petit tours supplémentaire dans rest_framework, le parcours est bien plus direct :
  • api_mixins.py::create()
  • api_views.py::update()
  /home/nroche/src/authentic/tests/test_api.py(1185)test_api_users_get_or_create()
-> resp = app.post_json('/api/users/?update_or_create=email', params=payload, status=200)
...
  /home/nroche/src/authentic/src/authentic2/api_mixins.py(82)create()
-> return self.partial_update(request, *args, **kwargs)
  /tmp/tox-nroche/authentic/py27-coverage-dj111-authentic-pg-/lib/python2.7/site-packages/rest_framework/mixins.py(78)partial_update()
-> return self.update(request, *args, **kwargs)
  /tmp/tox-nroche/authentic/py27-coverage-dj111-authentic-pg-/lib/python2.7/site-packages/rest_framework/mixins.py(70)update()
-> self.perform_update(serializer)
  /tmp/tox-nroche/authentic/py27-coverage-dj111-authentic-pg-/lib/python2.7/site-packages/rest_framework/mixins.py(74)perform_update()
-> serializer.save()
  /tmp/tox-nroche/authentic/py27-coverage-dj111-authentic-pg-/lib/python2.7/site-packages/rest_framework/serializers.py(187)save()
-> self.instance = self.update(self.instance, validated_data)
> /home/nroche/src/authentic/src/authentic2/api_views.py(465)update()
-> instance.set_password(password)

Et par ailleurs la couverture du code reste complète.

#8

Mis à jour par Benjamin Dauvergne il y a plus de 4 ans

  • Statut changé de Solution validée à Résolu (à déployer)
commit aa584ad97d434cd8bc3e78444e93d5691ceba63e
Author: Benjamin Dauvergne <bdauvergne@entrouvert.com>
Date:   Mon Sep 2 14:34:34 2019 +0200

    api: recreate get/update_or_create mixin at the view level (#35710)
#9

Mis à jour par Frédéric Péters il y a plus de 4 ans

  • Statut changé de Résolu (à déployer) à Solution déployée

Formats disponibles : Atom PDF