Fakultas Ilmu Komputer UI

Commit 2dbb635b authored by Kefas Satrio Bangkit Solidedantyo's avatar Kefas Satrio Bangkit Solidedantyo
Browse files

User roles

parent 6bf91940
from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.models import Group
from django.utils.translation import ugettext_lazy as _
......@@ -17,6 +18,8 @@ class CustomUserManager(BaseUserManager):
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
client_role, _created = Group.objects.get_or_create(name='client')
user.groups.add(client_role)
return user
def create_superuser(self, email, password, **extra_fields):
......
......@@ -26,4 +26,4 @@ class CustomUser(AbstractBaseUser, PermissionsMixin):
objects = CustomUserManager()
def __str__(self):
return self.email
return str(self.email)
from rest_framework import serializers
from rest_framework import serializers, exceptions
from dj_rest_auth.serializers import LoginSerializer
from .models import CustomUser
class CustomUserDetailsSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
result = super().to_representation(instance)
if instance.groups.exists():
result['role'] = instance.groups.first().name
return result
class Meta:
model = CustomUser
fields = ('id', 'name', 'email',)
read_only_fields = ('id', 'email',)
class CustomLoginSerializer(LoginSerializer):
def validate_auth_user_status(self, user):
request = self.context.get('request')
if not request.data.get('role'):
msg = 'Role is missing from the payload.'
raise exceptions.ValidationError(msg)
if not user.groups.filter(name=request.data.get('role')).exists():
msg = 'Invalid role for the user.'
raise exceptions.ValidationError(msg)
def create(self, validated_data):
pass
def update(self, instance, validated_data):
pass
......@@ -6,6 +6,7 @@ from django.test import TestCase
from django.http import JsonResponse
from dietela_quiz.models import DietProfile
from .models import CustomUser
from .serializers import CustomLoginSerializer
from .google_utils import validate_google_token
class UserModelTests(APITestCase):
......@@ -60,6 +61,10 @@ class UserModelTests(APITestCase):
cls.custom_user_2 = CustomUser.objects.create_user(name='tes', email='email2@gmail.com', password='abc')
cls.inactive_user = CustomUser.objects.create_user(name='inactive', email='inactive@gmail.com', password='abc')
cls.inactive_user.is_active = False
cls.inactive_user.save()
cls.num_of_diet_profile = DietProfile.objects.count()
cls.num_of_custom_user = CustomUser.objects.count()
......@@ -68,6 +73,7 @@ class UserModelTests(APITestCase):
password='tes', diet_profile=self.diet_profile_1,)
self.assertEqual(str(user), 'email2@email.com')
self.assertEqual(user.email, 'email2@email.com')
self.assertTrue(user.groups.filter(name='client').exists())
self.assertTrue(user.is_active)
self.assertFalse(user.is_staff)
self.assertFalse(user.is_superuser)
......@@ -188,14 +194,16 @@ class UserModelTests(APITestCase):
data = {
'email': 'email@email.com',
'password': 'abc',
'role': 'client',
}
response = self.client.post('/auth/login/', data, format='json')
response = self.client.post('/auth/user-login/', data, format='json')
json_response = json.loads(response.content)
self.assertIn('access_token', json_response)
self.assertIn('refresh_token', json_response)
self.assertIn('user', json_response)
self.assertTrue('id' in json_response.get('user'))
self.assertIn('id', json_response.get('user'))
self.assertIn('role', json_response.get('user'))
self.assertEquals(json_response.get('user').get('name'), 'tes')
self.assertEqual(response.status_code, status.HTTP_200_OK)
......@@ -203,18 +211,30 @@ class UserModelTests(APITestCase):
data = {
'email': 'email123123123@email.com',
'password': 'abc',
'role': 'client'
}
response = self.client.post('/auth/login/', data, format='json')
response = self.client.post('/auth/user-login/', data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_post_login_user_failed_because_invalid_role(self):
data = {
'email': 'email@email.com',
'password': 'abc',
'role': 'artist'
}
response = self.client.post('/auth/user-login/', data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_post_login_user_failed_because_invalid_email_format(self):
data = {
'email': 'email123123123@email',
'password': 'abc',
'role': 'client'
}
response = self.client.post('/auth/login/', data, format='json')
response = self.client.post('/auth/user-login/', data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
......@@ -222,11 +242,37 @@ class UserModelTests(APITestCase):
data = {
'email': 'email@email.com',
'password': 'abc1234',
'role': 'client'
}
response = self.client.post('/auth/user-login/', data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_post_login_user_failed_because_inactive_account(self):
data = {
'email': 'inactive@gmail.com',
'password': 'abc',
'role': 'client'
}
response = self.client.post('/auth/user-login/', data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
response = self.client.post('/auth/login/', data, format='json')
def test_post_login_user_failed_because_no_role_in_payload(self):
data = {
'email': 'email@email.com',
'password': 'abc',
}
response = self.client.post('/auth/user-login/', data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
def test_create_login_serializer_to_do_nothing(self):
serializer = CustomLoginSerializer()
self.assertEqual(serializer.create({}), None)
def test_update_login_serializer_to_do_nothing(self):
serializer = CustomLoginSerializer()
self.assertEqual(serializer.update(None, {}), None)
@patch('authentication.google_utils.requests.get')
@patch('authentication.google_utils.json.loads')
class TestValidateGoogleToken(TestCase):
......
from rest_framework import routers
from django.urls import path, include
from .views import LinkUserAndDietProfileViewSet, GoogleView
from .views import LinkUserAndDietProfileViewSet, GoogleView, CustomLoginView
router = routers.SimpleRouter()
router.register('auth/link-user-and-diet-profile', LinkUserAndDietProfileViewSet, \
......@@ -9,6 +9,7 @@ router.register('auth/link-user-and-diet-profile', LinkUserAndDietProfileViewSet
urlpatterns = [
path('auth/registration/', include('dj_rest_auth.registration.urls')),
path('auth/', include('dj_rest_auth.urls')),
path('auth/user-login/', CustomLoginView.as_view(), name='custom_user_login'),
path('auth/google/', GoogleView.as_view(), name='google'),
]
......
......@@ -2,14 +2,18 @@ from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken
from dj_rest_auth.views import LoginView
from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.hashers import make_password
from dietela_quiz.models import DietProfile
from dietela_quiz.serializers import DietProfileSerializer
from .models import CustomUser
from .serializers import CustomUserDetailsSerializer
from .serializers import CustomUserDetailsSerializer, CustomLoginSerializer
from .google_utils import validate_google_token
class CustomLoginView(LoginView):
serializer_class = CustomLoginSerializer
class LinkUserAndDietProfileViewSet(viewsets.ViewSet):
......
......@@ -24,6 +24,7 @@ coverage==4.5.4
# linter
pylint==2.7.2
pylint-django==2.4.2
astroid==2.5.1
#auth
dj-rest-auth==2.1.4
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment