From 8d359cdb712c39a358502ae5c61576b89e1f44fa Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 4 Feb 2021 12:13:12 +0000 Subject: [PATCH] merged with diegos changes --- README.md | 5 ++-- back_latienda/urls.py | 4 +-- core/serializers.py | 14 +--------- core/tests.py | 59 +++++++++++++++++++++++++++++++++++-------- core/views.py | 9 +------ 5 files changed, 55 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index e072c58..ed0cec1 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ From inside the project's folder: - Make migrations: -``` +```bash python manage.py makemigrations core geo companies products history stats python manage.py migrate ``` @@ -69,7 +69,8 @@ Change password: ``` Update user profile: -- endpoint: api/v1/user/update// +- available for admin +- endpoint: api/v1/users// - method: PUT - payload: ```json diff --git a/back_latienda/urls.py b/back_latienda/urls.py index 2f63fdb..55a0691 100644 --- a/back_latienda/urls.py +++ b/back_latienda/urls.py @@ -18,7 +18,7 @@ from django.urls import path, include from django.conf.urls.static import static from django.conf import settings -from rest_framework_simplejwt.views import TokenRefreshView, TokenVerifyView +from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView, TokenVerifyView from core import views as core_views from products import views as product_views @@ -28,7 +28,7 @@ from .routers import router urlpatterns = [ path('admin/', admin.site.urls), - path('api/v1/token/', core_views.CustomTokenObtainPairView.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/verify/', TokenVerifyView.as_view(), name='token_verify'), path('api/v1/user/change_password//', core_views.ChangeUserPasswordView.as_view(), name="change-password"), diff --git a/core/serializers.py b/core/serializers.py index 5f82e1c..5f9ec8b 100644 --- a/core/serializers.py +++ b/core/serializers.py @@ -4,25 +4,13 @@ from rest_framework import serializers from . import models -class CustomTokenObtainPairSerializer(TokenObtainPairSerializer): - def validate(self, attrs): - # The default result (access/refresh tokens) - data = super(CustomTokenObtainPairSerializer, self).validate(attrs) - - # Add extra responses here - data['user'] = {} - data['user']['id'] = self.user.id - data['user']['email'] = self.user.email - data['user']['role'] = self.user.role - return data - - class CustomUserSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True, required=True, style={'input_type': 'password'}) class Meta: model = models.CustomUser fields = ('id', 'email', 'full_name', 'role', 'password', 'is_active', 'notify') + class CustomUserAdminSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True, required=False, style={'input_type': 'password'}) class Meta: diff --git a/core/tests.py b/core/tests.py index 66c7a5d..c743088 100644 --- a/core/tests.py +++ b/core/tests.py @@ -329,7 +329,7 @@ class UpdateUserViewTest(APITestCase): def setUp(self): """Tests setup """ - self.endpoint = '/api/v1/user/change_password/' + self.endpoint = '/api/v1/users/' self.factory = factories.CustomUserFactory self.model = models.CustomUser # create regular user @@ -338,6 +338,11 @@ class UpdateUserViewTest(APITestCase): self.user = self.factory(email=self.reg_email, is_active=True) self.user.set_password(self.password) self.user.save() + # create admin user + self.admin_email = f"admin_user@mail.com" + self.admin_user = self.factory(email=self.admin_email, is_staff=True, is_active=True) + self.admin_user.set_password(self.password) + self.admin_user.save() def test_auth_user_can_modify_own_instance(self): """Regular user can modify own instance @@ -355,32 +360,62 @@ class UpdateUserViewTest(APITestCase): self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}") # Query endpoint - url = f'/api/v1/user/update/{self.user.pk}/' + url = f'{self.endpoint}{self.user.pk}/' response = self.client.put(url, data=data, format='json') # Assert forbidden code self.assertEqual(response.status_code, status.HTTP_200_OK) def test_auth_user_cannot_modify_random_instance(self): - """Regular user can modify own instance + """Regular user cannot modify randnom instance """ # Create instance instance = self.factory() - data = { - "email": "new_email@mail.com", - "full_name": "New Full Name", - 'provider': 'PROVIDER', - } # Authenticate token = get_tokens_for_user(self.user) self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}") # Query endpoint - url = f'/api/v1/user/update/{instance.pk}/' - response = self.client.put(url, data=data, format='json') + url = f'{self.endpoint}{instance.pk}/' + response = self.client.put(url, data={}, format='json') # Assert forbidden code self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + def test_anon_user_cannot_modify_random_instance(self): + """anon user cannot modify instance + """ + # Create instance + instance = self.factory() + + # Query endpoint + url = f'{self.endpoint}{instance.pk}/' + response = self.client.put(url, data={}, format='json') + # Assert forbidden code + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + + def test_admin_user_can_modify_random_instance(self): + """Regular user cannot modify randnom instance + """ + # Create instance + instance = self.factory() + + # Authenticate + token = get_tokens_for_user(self.admin_user) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}") + + data = { + "email": "new_email@mail.com", + "full_name": "New Full Name", + 'provider': 'PROVIDER', + 'notify': True, + } + + # Query endpoint + url = f'{self.endpoint}{instance.pk}/' + response = self.client.put(url, data=data, format='json') + # Assert forbidden code + self.assertEqual(response.status_code, status.HTTP_200_OK) + class LoadCoopManagerTestCase(APITestCase): @@ -394,7 +429,9 @@ class LoadCoopManagerTestCase(APITestCase): # create admin user self.admin_email = f"admin_user@mail.com" self.password = ''.join(random.choices(string.ascii_uppercase, k = 10)) - self.admin_user = self.user_factory(email=self.admin_email, password=self.password, is_staff=True, is_active=True) + self.admin_user = self.user_factory(email=self.admin_email, is_staff=True, is_active=True) + self.admin_user.set_password(self.password) + self.admin_user.save() # create regular user self.reg_email = f"user@mail.com" self.user = self.user_factory(email=self.reg_email, is_active=True) diff --git a/core/views.py b/core/views.py index c79ce18..4176ce6 100644 --- a/core/views.py +++ b/core/views.py @@ -15,7 +15,6 @@ from rest_framework.response import Response from rest_framework.permissions import IsAdminUser, IsAuthenticated from rest_framework.generics import UpdateAPIView from rest_framework.decorators import api_view, permission_classes -from rest_framework_simplejwt.views import TokenObtainPairView from companies.models import Company from history.models import HistorySync @@ -38,12 +37,6 @@ logging.basicConfig( ) - - -class CustomTokenObtainPairView(TokenObtainPairView): - serializer_class = core_serializers.CustomTokenObtainPairSerializer - - class CustomUserViewSet(viewsets.ModelViewSet): model = models.CustomUser @@ -60,7 +53,7 @@ class CustomUserViewSet(viewsets.ModelViewSet): def get_permissions(self): if self.action in ['retrieve', 'update', 'partial_update', 'destroy'] and self.request.user.is_anonymous is False: - return [YourOwnUserPermissions(), ] + return [YourOwnUserPermissions(), ] return super(CustomUserViewSet, self).get_permissions() def create(self, request):