Fakultas Ilmu Komputer UI
Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ppl-fasilkom-ui
2021
Kelas D
PT Gizi Sehat - Dietela
Dietela Backend
Commits
594ef580
Commit
594ef580
authored
Apr 22, 2021
by
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
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
authentication/google_utils.py
0 → 100644
View file @
594ef580
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'
)
authentication/tests.py
View file @
594ef580
import
json
from
rest_framework.test
import
APITestCase
from
unittest.mock
import
patch
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
.models
import
CustomUser
from
.google_utils
import
validate_google_token
class
UserModelTests
(
APITestCase
):
...
...
@@ -217,3 +221,48 @@ class UserModelTests(APITestCase):
response
=
self
.
client
.
post
(
'/auth/login/'
,
data
,
format
=
'json'
)
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
)
authentication/urls.py
View file @
594ef580
from
rest_framework
import
routers
from
django.urls
import
path
,
include
from
.views
import
LinkUserAndDietProfileViewSet
from
.views
import
LinkUserAndDietProfileViewSet
,
GoogleView
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/google/'
,
GoogleView
.
as_view
(),
name
=
'google'
),
]
urlpatterns
+=
router
.
urls
authentication/views.py
View file @
594ef580
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
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
.google_utils
import
validate_google_token
class
LinkUserAndDietProfileViewSet
(
viewsets
.
ViewSet
):
...
...
@@ -31,3 +36,27 @@ class LinkUserAndDietProfileViewSet(viewsets.ViewSet):
'user'
:
CustomUserDetailsSerializer
(
user
).
data
,
\
'diet_profile'
:
DietProfileSerializer
(
diet_profile
).
data
\
},
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
)
dietela_backend/settings.py
View file @
594ef580
...
...
@@ -70,7 +70,7 @@ INSTALLED_APPS = [
REST_FRAMEWORK
=
{
'DEFAULT_AUTHENTICATION_CLASSES'
:
[
'rest_framework.authentication.
Token
Authentication'
,
'rest_framework
_simplejwt
.authentication.
JWT
Authentication'
,
]
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment