mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Merge /users/ API into /accounts/
This commit is contained in:
+19
-2
@@ -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."""
|
||||
|
||||
@@ -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."""
|
||||
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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
@@ -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"))
|
||||
|
||||
@@ -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"),
|
||||
|
||||
)
|
||||
@@ -6,6 +6,5 @@ from django.conf.urls import patterns, include
|
||||
urlpatterns = patterns(
|
||||
"",
|
||||
|
||||
("", include("modoboa.core.urls_api")),
|
||||
("", include("modoboa.admin.urls_api")),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user