Fakultas Ilmu Komputer UI

Commit 594ef580 authored by Kefas Satrio Bangkit Solidedantyo's avatar Kefas Satrio Bangkit Solidedantyo
Browse files

Merge branch 'google-auth' into 'staging'

Google Auth

See merge request !39
parents 221de8b7 63c86a02
Pipeline #71382 passed with stages
in 8 minutes and 3 seconds
import json
import requests
from django.http import JsonResponse
from rest_framework import status
def validate_google_token(access_token):
payload = {'access_token': access_token}
response = requests.get('https://www.googleapis.com/oauth2/v2/userinfo', params=payload)
data = json.loads(response.text)
if 'error' in data:
content = {'message': 'wrong google token / this google token is already expired.'}
return False, JsonResponse(content, status=status.HTTP_400_BAD_REQUEST)
return True, data.get('email')
import json import json
from rest_framework.test import APITestCase from unittest.mock import patch
from rest_framework import status from rest_framework import status
from rest_framework.test import APITestCase
from django.test import TestCase
from django.http import JsonResponse
from dietela_quiz.models import DietProfile from dietela_quiz.models import DietProfile
from .models import CustomUser from .models import CustomUser
from .google_utils import validate_google_token
class UserModelTests(APITestCase): class UserModelTests(APITestCase):
...@@ -217,3 +221,48 @@ class UserModelTests(APITestCase): ...@@ -217,3 +221,48 @@ class UserModelTests(APITestCase):
response = self.client.post('/auth/login/', data, format='json') response = self.client.post('/auth/login/', data, format='json')
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
@patch('authentication.google_utils.requests.get')
@patch('authentication.google_utils.json.loads')
class TestValidateGoogleToken(TestCase):
def test_validate_access_token_succeed(self, mock_json_loads, mock_get):
mock_get.return_value.text = "ABCDEFGH"
mock_json_loads.return_value = {"email": 'mock_user@email.com'}
success, google_data = validate_google_token("ABCDEFGH")
self.assertTrue(success)
self.assertEqual('mock_user@email.com', google_data)
def test_validate_access_token_failed(self, mock_json_loads, mock_get):
mock_get.return_value.text = "123123123"
mock_json_loads.return_value = {
'error': 'invalid_token',
'message': 'wrong google token / this google token is already expired.'
}
success, google_data = validate_google_token("123123123")
self.assertFalse(success)
self.assertEqual(google_data.status_code, status.HTTP_400_BAD_REQUEST)
@patch('authentication.views.validate_google_token')
class TestGoogleLogin(TestCase):
def test_google_login_succeed(self, mock_validate_google_token):
mock_validate_google_token.return_value = True, 'email@email.com'
data = {'access_token': 'QWERTY'}
response = self.client.post('/auth/google/', 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.assertEqual(response.status_code, status.HTTP_200_OK)
def test_google_login_failed(self, mock_validate_google_token):
content = {'message': 'wrong google token / this google token is already expired.'}
mock_validate_google_token.return_value = False, JsonResponse(content,
status=status.HTTP_400_BAD_REQUEST)
data = {'access_token': 'sdasdasdad'}
response = self.client.post('/auth/google/', data, format='json')
json_response = json.loads(response.content)
self.assertIn('message', json_response)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
from rest_framework import routers from rest_framework import routers
from django.urls import path, include from django.urls import path, include
from .views import LinkUserAndDietProfileViewSet from .views import LinkUserAndDietProfileViewSet, GoogleView
router = routers.SimpleRouter() router = routers.SimpleRouter()
router.register('auth/link-user-and-diet-profile', LinkUserAndDietProfileViewSet, \ router.register('auth/link-user-and-diet-profile', LinkUserAndDietProfileViewSet, \
...@@ -9,6 +9,7 @@ router.register('auth/link-user-and-diet-profile', LinkUserAndDietProfileViewSet ...@@ -9,6 +9,7 @@ router.register('auth/link-user-and-diet-profile', LinkUserAndDietProfileViewSet
urlpatterns = [ urlpatterns = [
path('auth/registration/', include('dj_rest_auth.registration.urls')), path('auth/registration/', include('dj_rest_auth.registration.urls')),
path('auth/', include('dj_rest_auth.urls')), path('auth/', include('dj_rest_auth.urls')),
path('auth/google/', GoogleView.as_view(), name='google'),
] ]
urlpatterns += router.urls urlpatterns += router.urls
from rest_framework import viewsets, status from rest_framework import viewsets, status
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken
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.models import DietProfile
from dietela_quiz.serializers import DietProfileSerializer from dietela_quiz.serializers import DietProfileSerializer
from .models import CustomUser from .models import CustomUser
from .serializers import CustomUserDetailsSerializer from .serializers import CustomUserDetailsSerializer
from .google_utils import validate_google_token
class LinkUserAndDietProfileViewSet(viewsets.ViewSet): class LinkUserAndDietProfileViewSet(viewsets.ViewSet):
...@@ -31,3 +36,27 @@ class LinkUserAndDietProfileViewSet(viewsets.ViewSet): ...@@ -31,3 +36,27 @@ class LinkUserAndDietProfileViewSet(viewsets.ViewSet):
'user': CustomUserDetailsSerializer(user).data,\ 'user': CustomUserDetailsSerializer(user).data,\
'diet_profile': DietProfileSerializer(diet_profile).data\ 'diet_profile': DietProfileSerializer(diet_profile).data\
}, status=status.HTTP_200_OK) }, status=status.HTTP_200_OK)
class GoogleView(APIView):
def post(self, request):
success, google_data = validate_google_token(request.data.get('access_token'))
if not success:
return google_data
try:
user = CustomUser.objects.get(email=
google_data
)
except CustomUser.DoesNotExist:
user = CustomUser()
# random default password
user.password = make_password(BaseUserManager().make_random_password())
user.email = google_data
user.save()
token = RefreshToken.for_user(user) # generate token
response = {}
response['user'] = CustomUserDetailsSerializer(user).data
response['access_token'] = str(token.access_token)
response['refresh_token'] = str(token)
return Response(response)
...@@ -70,7 +70,7 @@ INSTALLED_APPS = [ ...@@ -70,7 +70,7 @@ INSTALLED_APPS = [
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [ 'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication', 'rest_framework_simplejwt.authentication.JWTAuthentication',
] ]
} }
......
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