Merge /users/ API into /accounts/

This commit is contained in:
Antoine Nguyen
2016-03-29 11:04:07 +02:00
parent c76e47be98
commit b8742cdfd4
7 changed files with 71 additions and 78 deletions
+19 -2
View File
@@ -1,9 +1,11 @@
"""Admin API."""
from django import http
from django.contrib.contenttypes.models import ContentType
from rest_framework import viewsets
from rest_framework.decorators import list_route
from rest_framework import status, viewsets
from rest_framework.decorators import detail_route, list_route
from rest_framework.exceptions import ParseError
from rest_framework.permissions import IsAuthenticated, DjangoModelPermissions
from rest_framework.response import Response
@@ -71,6 +73,21 @@ class AccountViewSet(viewsets.ModelViewSet):
"""Add custom args to delete call."""
instance.delete(self.request.user)
@detail_route(methods=["put"])
def password(self, request, pk=None):
"""Change account password."""
try:
user = core_models.User.objects.get(pk=pk)
except core_models.User.DoesNotExist:
raise http.Http404
serializer = serializers.AccountPasswordSerializer(
user, data=request.data)
if serializer.is_valid():
serializer.save()
return Response()
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@list_route()
def exists(self, request):
"""Check if account exists."""
+33
View File
@@ -88,6 +88,39 @@ class AccountExistsSerializer(serializers.Serializer):
exists = serializers.BooleanField()
class AccountPasswordSerializer(serializers.ModelSerializer):
"""A serializer used to change a user password."""
new_password = serializers.CharField()
class Meta:
model = core_models.User
fields = (
"password", "new_password", )
def validate_password(self, value):
"""Check password."""
if not self.instance.check_password(value):
raise serializers.ValidationError("Password not correct")
return value
def validate_new_password(self, value):
"""Check new password."""
try:
validators.validate_length(value)
validators.complexity(value)
except ValidationError as exc:
raise serializers.ValidationError(exc.messages[0])
return value
def update(self, instance, validated_data):
"""Set new password."""
instance.set_password(validated_data["new_password"])
instance.save()
return instance
class WritableAccountSerializer(AccountSerializer):
"""Serializer to create account."""
+18
View File
@@ -368,6 +368,24 @@ class AccountAPITestCase(ModoAPITestCase):
response = self.client.get(url)
self.assertEqual(response.status_code, 400)
def test_change_password(self):
"""Check the change password service."""
account = core_models.User.objects.get(username="user@test.com")
url = reverse(
"external_api:account-password", args=[account.pk])
response = self.client.put(
url, {"password": "toto", "new_password": "pass"},
format="json")
# must fail because password is too weak
self.assertEqual(response.status_code, 400)
response = self.client.put(
url, {"password": "toto", "new_password": "Toto1234"},
format="json")
self.assertEqual(response.status_code, 200)
account.refresh_from_db()
self.assertTrue(account.check_password("Toto1234"))
class AliasAPITestCase(ModoAPITestCase):
"""Check Alias API."""
-29
View File
@@ -1,29 +0,0 @@
"""Modoboa core viewsets."""
from django.http import Http404
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from . import models
from . import serializers
class UserPasswordChangeAPIView(APIView):
"""A view to update password for user instances."""
def put(self, request, pk, format=None):
"""PUT method hander."""
try:
user = models.User.objects.get(username=pk)
except models.User.DoesNotExist:
raise Http404
serializer = serializers.UserPasswordSerializer(
user, data=request.data)
if serializer.is_valid():
serializer.save()
return Response()
return Response(
serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+1 -32
View File
@@ -2,7 +2,7 @@
from django.core.urlresolvers import reverse
from modoboa.lib.tests import ModoTestCase, ModoAPITestCase
from modoboa.lib.tests import ModoTestCase
from . import factories
from . import models
@@ -113,34 +113,3 @@ class APIAccessFormTestCase(ModoTestCase):
self.ajax_post(url, {"enable_api_access": False})
user = models.User.objects.get(username="admin")
self.assertFalse(hasattr(user, "auth_token"))
class APITestCase(ModoAPITestCase):
"""Check API."""
@classmethod
def setUpTestData(cls):
"""Create test data."""
super(APITestCase, cls).setUpTestData()
cls.account = factories.UserFactory(
username="user@test.com", groups=('SimpleUsers', )
)
def test_change_password(self):
"""Check the change password service."""
url = reverse(
"external_api:user_password_change", args=["user@test.com"])
response = self.client.put(
url, {"password": "toto", "new_password": "pass"},
format="json")
# must fail because password is too weak
self.assertEqual(response.status_code, 400)
response = self.client.put(
url, {"password": "toto", "new_password": "Toto1234"},
format="json")
self.assertEqual(response.status_code, 200)
self.assertTrue(
models.User.objects.get(
pk=self.account.pk).check_password("Toto1234"))
-14
View File
@@ -1,14 +0,0 @@
"""Core API urls."""
from django.conf.urls import patterns, url
from . import api
urlpatterns = patterns(
"",
url("^users/(?P<pk>.+)/password/$",
api.UserPasswordChangeAPIView.as_view(),
name="user_password_change"),
)
-1
View File
@@ -6,6 +6,5 @@ from django.conf.urls import patterns, include
urlpatterns = patterns(
"",
("", include("modoboa.core.urls_api")),
("", include("modoboa.admin.urls_api")),
)