Completed
Pull Request — master (#12)
by Camille
04:33
created

UserViewSet.update()   B

Complexity

Conditions 6

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 6
dl 0
loc 11
rs 8
1
import random
2
import string
3
4
from django.core.mail import send_mail
5
from django.http import Http404
6
7
from rest_framework import viewsets, decorators, status
8
from rest_framework.response import Response
9
from dry_rest_permissions.generics import DRYPermissions
10
11
from sigma_core.models.user import User
12
from sigma_core.serializers.user import UserSerializer
13
14
15
reset_mail = {
16
    'from_email': '[email protected]',
17
    'subject': 'Mot de passe Sigma',
18
    'message': u"""
19
Bonjour,
20
Ton mot de passe Sigma a été réinitialisé.
21
C'est maintenant "{password}".
22
Cordialement,
23
L'équipe Sigma.
24
"""
25
}
26
27
28
class UserViewSet(viewsets.ModelViewSet):
29
    permission_classes = (DRYPermissions, )
30
    queryset = User.objects.all()
31
    serializer_class = UserSerializer
32
33
    def update(self, request, pk=None):
34
        try:
35
            user = User.objects.get(pk=pk)
36
        except User.DoesNotExist:
37
            return Http404()
38
39
        if ((request.data['lastname'] != user.lastname or request.data['firstname'] != user.firstname)) and not (request.user.is_staff or request.user.is_superuser):
40
            return Response('You cannot change your lastname or firstname', status=status.HTTP_400_BAD_REQUEST)
41
42
        return super(UserViewSet, self).update(request, pk)
43
44
    @decorators.list_route(methods=['get'])
45
    def me(self, request):
46
        """
47
        Give the data of the current user.
48
        """
49
        if request.user.__class__.__name__ == 'AnonymousUser':
50
            return Response(status=status.HTTP_401_UNAUTHORIZED)
51
        else:
52
            serializer = self.get_serializer_class()(request.user, context={'request': request})
53
            return Response(serializer.data)
54
55
    @decorators.list_route(methods=['put'])
56
    def change_password(self, request):
57
        """
58
        Allow current user to change his password.
59
        ---
60
        omit_serializer: true
61
        parameters_strategy:
62
            form: replace
63
        parameters:
64
            - name: old_password
65
              type: string
66
            - name: password
67
              type: string
68
        """
69
        PASSWORD_MIN_LENGTH = 8
70
71
        if request.user.__class__.__name__ == 'AnonymousUser':
72
            return Response(status=status.HTTP_401_UNAUTHORIZED)
73
74
        user = request.user
75
        data = request.data
76
        if not user.check_password(data['old_password']):
77
            return Response("Wrong password", status=status.HTTP_403_FORBIDDEN)
78
        if len(data['password']) < PASSWORD_MIN_LENGTH:
79
            return Response("'password' must be at least %d characters long" % PASSWORD_MIN_LENGTH, status=status.HTTP_400_BAD_REQUEST)
80
81
        user.set_password(data['password'])
82
        user.save()
83
        return Response('Password successfully changed', status=status.HTTP_200_OK)
84
85
    @decorators.list_route(methods=['post'])
86
    def reset_password(self, request):
87
        """
88
        Reset current user's password and send him an email with the new one.
89
        ---
90
        omit_serializer: true
91
        parameters_strategy:
92
            form: replace
93
        parameters:
94
            - name: email
95
              type: string
96
        """
97
        email = request.data.get('email')
98
        if email == '':
99
            return Response("'email' field cannot be empty", status=status.HTTP_400_BAD_REQUEST)
100
101
        try:
102
            user = User.objects.get(email=email)
103
        except User.DoesNotExist:
104
            return Response('No user found with this email', status=status.HTTP_404_NOT_FOUND)
105
106
        password = ''.join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for _ in range(10))
107
108
        mail = reset_mail.copy()
109
        mail['recipient_list'] = [user.email]
110
        mail['message'] = mail['message'].format(email=user.email, password=password, name=user.get_full_name())
111
        send_mail(**mail)
112
113
        user.set_password(password)
114
        user.save()
115
116
        return Response('Password reset', status=status.HTTP_200_OK)
117