Marta Miranda

Agregue cambiar contrasenia

@@ -7,7 +7,7 @@ from rest_framework.permissions import IsAuthenticated, AllowAny @@ -7,7 +7,7 @@ from rest_framework.permissions import IsAuthenticated, AllowAny
7 from rest_framework.response import Response 7 from rest_framework.response import Response
8 8
9 from usuario.models import Usuario 9 from usuario.models import Usuario
10 -from usuario.serializers import UsuarioSerializer 10 +from usuario.serializers import UsuarioSerializer, CambiarClaveSecretaSerializer
11 11
12 12
13 class UsuarioViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet): 13 class UsuarioViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
@@ -22,70 +22,15 @@ class UsuarioViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewset @@ -22,70 +22,15 @@ class UsuarioViewSet(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, viewset
22 22
23 return user 23 return user
24 24
25 - # @action(  
26 - # methods=('GET',),  
27 - # detail=True,  
28 - # url_path=r'activar-cuenta/(?P<token>[^/.]+)',  
29 - # permission_classes=(AllowAny,)  
30 - # )  
31 - # def activar_cuenta(self, request, pk, token=None):  
32 - # usuario = self.get_object(base_method=True)  
33 - # # Controlamos si el token es correcto.  
34 - # if usuario.is_active:  
35 - # return Response(data={'mensaje': 'La cuenta del usuario ya está activa'}, status=status.HTTP_200_OK)  
36 - #  
37 - # if not default_token_generator.check_token(usuario, token):  
38 - # password = generar_password_aleatorio(usuario)  
39 - # enviar_correo_electronico_activar_cuenta(usuario, password)  
40 - # raise ValidationError('Se venció token, revise nuevamente su correo electrónico')  
41 - #  
42 - # # Activamos la cuenta.  
43 - # usuario.is_active = True  
44 - # usuario.save(update_fields=('is_active',))  
45 - # data = self.get_serializer(instance=usuario).data  
46 - # return Response(data=data, status=status.HTTP_200_OK)  
47 - #  
48 - # @action(  
49 - # methods=('POST',),  
50 - # detail=False,  
51 - # url_path='recuperar-cuenta',  
52 - # permission_classes=(AllowAny,),  
53 - # parser_classes=(JSONParser,)  
54 - # )  
55 - # def recuperar_cuenta(self, request):  
56 - # if 'correo_electronico' not in request.data:  
57 - # raise ValidationError('Debe ingresar un correo electrónico')  
58 - #  
59 - # correo_electronico = request.data.get('correo_electronico')  
60 - # try:  
61 - # usuario = Usuario.objects.get(email=correo_electronico)  
62 - # enviar_correo_electronico_recuperar_cuenta(usuario)  
63 - # return Response(status=status.HTTP_200_OK)  
64 - # except Usuario.DoesNotExist as error:  
65 - # raise ValidationError(f'No existe un usuario con el correo electrónico: {correo_electronico}')  
66 - #  
67 - # @action(  
68 - # methods=('patch',),  
69 - # detail=False,  
70 - # url_path='cambiar-clave-secreta',  
71 - # parser_classes=(JSONParser,),  
72 - # serializer_class=CambiarClaveSecretaSerializer  
73 - # )  
74 - # def cambiar_clave_secreta(self, request):  
75 - # serializer = self.get_serializer(data=request.data)  
76 - # serializer.is_valid(raise_exception=True)  
77 - # serializer.save()  
78 - # return Response(status=status.HTTP_200_OK)  
79 - #  
80 - # @action(  
81 - # methods=('get',),  
82 - # detail=False,  
83 - # url_path=r'obtener-usuarios-por-tarea/(?P<tarea>[^/.]+)'  
84 - # )  
85 - # def obtener_usuarios_por_tarea(self, request, tarea=None):  
86 - # queryset = super().get_queryset()  
87 - #  
88 - # usuarios = queryset.filter(tipo_tarea_certificado=tarea, is_active=True).exclude(id=request.user.id)  
89 - # serializer = self.get_serializer(usuarios, many=True)  
90 - #  
91 - # return Response(serializer.data) 25 + @action(
  26 + methods=('patch',),
  27 + detail=False,
  28 + url_path='cambiar-clave-secreta',
  29 + parser_classes=(JSONParser,),
  30 + serializer_class=CambiarClaveSecretaSerializer
  31 + )
  32 + def cambiar_clave_secreta(self, request):
  33 + serializer = self.get_serializer(data=request.data)
  34 + serializer.is_valid(raise_exception=True)
  35 + serializer.save()
  36 + return Response(status=status.HTTP_200_OK)
@@ -26,3 +26,27 @@ class UsuarioSerializer(serializers.ModelSerializer): @@ -26,3 +26,27 @@ class UsuarioSerializer(serializers.ModelSerializer):
26 'organismo': 'organismo.serializers.OrganismoSerializer', 26 'organismo': 'organismo.serializers.OrganismoSerializer',
27 } 27 }
28 28
  29 +
  30 +class CambiarClaveSecretaSerializer(DRFSerializer):
  31 + clave = serializers.CharField(max_length=128, write_only=True, required=True)
  32 + clave_nueva = serializers.CharField(max_length=128, write_only=True, required=True)
  33 + clave_nueva_2 = serializers.CharField(max_length=128, write_only=True, required=True)
  34 +
  35 + def validate_clave(self, value):
  36 + user = self.context['request'].user
  37 + if not user.check_password(value):
  38 + raise serializers.ValidationError("La contraseña anterior no es válida. ¡Intentalo nuevamente!")
  39 + return value
  40 +
  41 + def validate(self, data):
  42 + if data['clave_nueva'] != data['clave_nueva_2']:
  43 + raise serializers.ValidationError({'clave_nueva_2': "Los nuevos campos de contraseñas no coinciden"})
  44 + password_validation.validate_password(data['clave_nueva'], self.context['request'].user)
  45 + return data
  46 +
  47 + def save(self, **kwargs):
  48 + clave = self.validated_data['clave_nueva']
  49 + usuario = self.context['request'].user
  50 + usuario.set_password(clave)
  51 + usuario.save()
  52 + return usuario
  1 +import pytest
  2 +from django.contrib.auth import get_user_model
  3 +
  4 +from core.tests.fixtures import create_user, CONTENT_TYPE_JSON
  5 +from core.tests.utils import post, get, JSON_CONTENT_TYPE, patch
  6 +
  7 +
  8 +@pytest.mark.django_db
  9 +def test_usuario_cambio_password_satisfactoriamente():
  10 + usuario_autenticado = create_user(username='mbarrera')
  11 + usuario_autenticado.set_password('ultima_contraseña')
  12 +
  13 + data = {
  14 + "clave": "ultima_contraseña",
  15 + "clave_nueva": "nueva_contraseña",
  16 + "clave_nueva_2": "nueva_contraseña"
  17 + }
  18 +
  19 + endpoint = "/api/v1/usuario/cambiar-clave-secreta/"
  20 + response = patch(endpoint, data=data, content_type=CONTENT_TYPE_JSON, user_logged=usuario_autenticado)
  21 +
  22 + assert response.status_code == 200
  23 +
  24 + debianitram = get_user_model().objects.get(username='mbarrera')
  25 + assert debianitram.check_password('nueva_contraseña')
  26 +
  27 +
  28 +@pytest.mark.django_db
  29 +def test_usuario_cambio_password_falla_con_clave():
  30 + usuario_autenticado = create_user(username='mbarrera')
  31 + usuario_autenticado.set_password('ultima_contraseña')
  32 +
  33 + data = {
  34 + "clave": "ultima.-.",
  35 + "clave_nueva": "nueva_contraseña",
  36 + "clave_nueva_2": "nueva_contraseña"
  37 + }
  38 +
  39 + endpoint = "/api/v1/usuario/cambiar-clave-secreta/"
  40 + response = patch(endpoint, data=data, content_type=CONTENT_TYPE_JSON, user_logged=usuario_autenticado)
  41 +
  42 + assert response.status_code == 400
  43 + errors = response.json()['errors']
  44 + assert errors[0]['detail'] == 'La contraseña anterior no es válida. ¡Intentalo nuevamente!'
  45 +
  46 +
  47 +@pytest.mark.django_db
  48 +def test_usuario_cambio_password_falla_no_coinciden_nuevas_password():
  49 + usuario_autenticado = create_user(username='mbarrera')
  50 + usuario_autenticado.set_password('ultima_contraseña')
  51 +
  52 + data = {
  53 + "clave": "ultima_contraseña",
  54 + "clave_nueva": "NuevaContraseña",
  55 + "clave_nueva_2": "nueva_contraseña"
  56 + }
  57 +
  58 + endpoint = "/api/v1/usuario/cambiar-clave-secreta/"
  59 + response = patch(endpoint, data=data, content_type=CONTENT_TYPE_JSON, user_logged=usuario_autenticado)
  60 +
  61 + assert response.status_code == 400
  62 + errors = response.json()['errors']
  63 + assert errors[0]['detail'] == 'Los nuevos campos de contraseñas no coinciden'
  64 +