fixed password update not working
This commit is contained in:
17
README.md
17
README.md
@@ -40,6 +40,23 @@ To load initial location data use: `python manage.py addgeo`
|
|||||||
## Endpoints
|
## Endpoints
|
||||||
|
|
||||||
|
|
||||||
|
### Authentication
|
||||||
|
|
||||||
|
Implemented using `djangorestframework-simplejwt`
|
||||||
|
|
||||||
|
|
||||||
|
New token pair endpoint: `/api/v1/token/`
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTYxMjI3MTcwNSwianRpIjoiZDU4YTgzYzFkYzFkNDI5MTljMGQ0NzcxNzljNzUxYTQiLCJ1c2VyX2lkIjo4fQ.yln80W5lONSyHwwqF4qBBHteqLuRfdLLWuaQANr_vxc",
|
||||||
|
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjEyMTg4OTA1LCJqdGkiOiIzNGIxMzM3NmU4MWI0OWY5YjU3ZmUxM2M5NThmZWZkYiIsInVzZXJfaWQiOjh9.aRDCUvKj7LCvixjPLC9ghy0h7rfRwR6Lo3A7HX4kSHE"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Refresh expired token endpoint: `/api/v1/token/refresh/`
|
||||||
|
|
||||||
|
|
||||||
### Users
|
### Users
|
||||||
|
|
||||||
Endpoint url: `/api/v1/users/`
|
Endpoint url: `/api/v1/users/`
|
||||||
|
|||||||
@@ -27,6 +27,5 @@ urlpatterns = [
|
|||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('api/v1/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
path('api/v1/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||||
path('api/v1/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
path('api/v1/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||||
path('api/v1/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
|
|
||||||
path('api/v1/', include(router.urls)),
|
path('api/v1/', include(router.urls)),
|
||||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|||||||
@@ -26,12 +26,8 @@ class CustomUserViewSetTest(APITestCase):
|
|||||||
self.endpoint = '/api/v1/users/'
|
self.endpoint = '/api/v1/users/'
|
||||||
self.factory = factories.CustomUserFactory
|
self.factory = factories.CustomUserFactory
|
||||||
self.model = models.CustomUser
|
self.model = models.CustomUser
|
||||||
# create admin user
|
|
||||||
self.admin_email = f"admin_user@mail.com"
|
|
||||||
self.password = ''.join(random.choices(string.ascii_uppercase, k = 10))
|
|
||||||
self.user = self.factory(email=self.admin_email, password=self.password, is_active=True)
|
|
||||||
# create regular user
|
# create regular user
|
||||||
self.reg_email = f"regular_user@mail.com"
|
self.reg_email = f"user@mail.com"
|
||||||
self.password = ''.join(random.choices(string.ascii_uppercase, k = 10))
|
self.password = ''.join(random.choices(string.ascii_uppercase, k = 10))
|
||||||
self.user = self.factory(email=self.reg_email, password=self.password, is_active=True)
|
self.user = self.factory(email=self.reg_email, password=self.password, is_active=True)
|
||||||
|
|
||||||
@@ -129,7 +125,20 @@ class CustomUserViewSetTest(APITestCase):
|
|||||||
response = self.client.put(url, data=data, format='json')
|
response = self.client.put(url, data=data, format='json')
|
||||||
|
|
||||||
# Assert forbidden code
|
# Assert forbidden code
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
|
|
||||||
|
# assert new password hash properly updated
|
||||||
|
# assert fields exist, and data matches
|
||||||
|
updated_user = self.model.objects.get(pk=self.user.id)
|
||||||
|
stored_value = updated_user.__dict__['password']
|
||||||
|
hash_type, iteration, salt, stored_password_hash = stored_value.split('$')
|
||||||
|
new_password_hash = hashlib.pbkdf2_hmac(
|
||||||
|
hash_name='sha256',
|
||||||
|
password=data['password'].encode(),
|
||||||
|
salt=salt.encode(),
|
||||||
|
iterations=int(iteration),
|
||||||
|
)
|
||||||
|
self.assertEqual(stored_password_hash, base64.b64encode(new_password_hash).decode())
|
||||||
|
|
||||||
def test_regular_user_cannot_modify_existing_instance(self):
|
def test_regular_user_cannot_modify_existing_instance(self):
|
||||||
"""Regular user cannot modify existing instance
|
"""Regular user cannot modify existing instance
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from django.shortcuts import render, get_object_or_404
|
from django.shortcuts import render, get_object_or_404
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
@@ -12,13 +13,17 @@ from . import serializers
|
|||||||
from back_latienda.permissions import CustomUserPermissions
|
from back_latienda.permissions import CustomUserPermissions
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
||||||
class CustomUserViewSet(viewsets.ModelViewSet):
|
class CustomUserViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
model = models.CustomUser
|
model = User
|
||||||
serializer_class = serializers.CustomUserReadSerializer
|
serializer_class = serializers.CustomUserReadSerializer
|
||||||
write_serializer_class =serializers.CustomUserWriteSerializer
|
write_serializer_class =serializers.CustomUserWriteSerializer
|
||||||
model_name = 'custom_user'
|
model_name = 'custom_user'
|
||||||
queryset = models.CustomUser.objects.all()
|
queryset = User.objects.all()
|
||||||
permission_classes = [CustomUserPermissions,]
|
permission_classes = [CustomUserPermissions,]
|
||||||
|
|
||||||
def create(self, request):
|
def create(self, request):
|
||||||
@@ -45,6 +50,34 @@ class CustomUserViewSet(viewsets.ModelViewSet):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return Response(str(e), status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
return Response(str(e), status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|
||||||
|
def update(self, request, pk):
|
||||||
|
"""
|
||||||
|
Update CustomUser Instance
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
serializer = self.write_serializer_class(
|
||||||
|
data=request.data,
|
||||||
|
)
|
||||||
|
if serializer.is_valid():
|
||||||
|
# save model instance data
|
||||||
|
password = serializer.validated_data.pop('password')
|
||||||
|
instance = get_object_or_404(User, pk=pk)
|
||||||
|
|
||||||
|
for key, value in serializer.validated_data.items():
|
||||||
|
instance.__dict__[key] = value
|
||||||
|
|
||||||
|
instance.set_password(password)
|
||||||
|
instance.save()
|
||||||
|
|
||||||
|
return Response(self.serializer_class(
|
||||||
|
instance, many=False, context={'request': request}).data,
|
||||||
|
status=status.HTTP_201_CREATED)
|
||||||
|
else:
|
||||||
|
return Response(
|
||||||
|
serializer.errors, status=status.HTTP_406_NOT_ACCEPTABLE)
|
||||||
|
except Exception as e:
|
||||||
|
return Response(str(e), status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"])
|
obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"])
|
||||||
self.check_object_permissions(self.request, obj)
|
self.check_object_permissions(self.request, obj)
|
||||||
|
|||||||
Reference in New Issue
Block a user