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
PPL Sosial
bisago
bisago-be
Commits
fa3c33d2
Commit
fa3c33d2
authored
Mar 20, 2021
by
Muhammad Rafif Elfazri
Committed by
Fakhira Devina
Mar 20, 2021
Browse files
Fix Security flaws on google oauth and create test for oauth modules
parent
200593b8
Changes
3
Hide whitespace changes
Inline
Side-by-side
oauth/tests.py
View file @
fa3c33d2
from
django.test
import
TestCase
import
json
from
unittest.mock
import
patch
from
django.test
import
Client
from
registrasi.models
import
BisaGoUser
from
django.contrib.auth.models
import
User
import
time
# Create your tests here.
class
TestOauth
(
TestCase
):
def
setUp
(
self
):
email
=
'mock_user@email.com'
password
=
'pass12345'
name
=
'name'
user
=
User
.
objects
.
create_user
(
username
=
email
,
email
=
email
,
password
=
password
,
last_name
=
name
)
user
.
is_active
=
True
user
.
save
()
BisaGoUser
.
objects
.
create
(
user
=
user
,
phone_number
=
'089892234567'
,
tanggal_lahir
=
'1990-05-05'
,
pekerjaan
=
'Mahasiswa'
,
alamat
=
'Alamat Palsu'
)
email
=
'mock_user12@email.com'
name
=
'name12323'
user
=
User
.
objects
.
create_user
(
username
=
email
,
email
=
email
,
password
=
password
,
last_name
=
name
)
user
.
is_active
=
False
user
.
save
()
BisaGoUser
.
objects
.
create
(
user
=
user
,
phone_number
=
'089832234567'
,
tanggal_lahir
=
'1990-05-05'
,
pekerjaan
=
'Mahasiswa'
,
alamat
=
'Alamat Palsu'
)
def
test_request_token_email_exist_active
(
self
):
email
=
'mock_user@email.com'
passcode
=
'pass12345'
response
=
Client
().
post
(
'/api-token-auth/'
,
{
'username'
:
email
,
'name'
:
'name'
,
"access_token"
:
"sankdsanlk"
,
'password'
:
passcode
})
json_response
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
200
,
response
.
status_code
)
self
.
assertEqual
(
'mock_user@email.com'
,
json_response
.
get
(
"username"
))
def
test_request_token_email_not_exists
(
self
):
email
=
'mock_user1212@email.com'
passcode
=
'pass12345'
response
=
Client
().
post
(
'/api-token-auth/'
,
{
'username'
:
email
,
'name'
:
'name'
,
"access_token"
:
"sankdsanlk"
,
'password'
:
passcode
})
json_response
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
404
,
response
.
status_code
)
self
.
assertEqual
(
json_response
[
'response'
],
"User not exist"
)
def
test_request_token_not_active
(
self
):
email
=
'mock_user12@email.com'
password
=
'pass12345'
response
=
Client
().
post
(
'/api-token-auth/'
,
{
'username'
:
email
,
'name'
:
'name12323'
,
"access_token"
:
"sankdsanlk"
,
'password'
:
password
})
json_response
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
400
,
response
.
status_code
)
self
.
assertEqual
(
json_response
[
'response'
],
"Please activate your account"
)
def
test_user_wrong_password
(
self
):
email
=
'mock_user12@email.com'
password
=
'pass123456'
response
=
Client
().
post
(
'/api-token-auth/'
,
{
'username'
:
email
,
'name'
:
'name'
,
"access_token"
:
"sankdsanlk"
,
'password'
:
password
})
json_response
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
400
,
response
.
status_code
)
self
.
assertEqual
(
json_response
[
'response'
],
"Wrong password"
)
@
patch
(
'oauth.views.json.loads'
)
def
test_google_login_exist
(
self
,
mock_json_loads
):
email
=
'mock_user@email.com'
passcode
=
'pass12345'
mock_json_loads
.
return_value
=
{
"email"
:
'mock_user@email.com'
}
response
=
Client
().
post
(
'/api-token-auth/'
,
{
'username'
:
email
,
'name'
:
'name'
,
"access_token"
:
"sankdsanlk"
,
'password'
:
passcode
,
'google'
:
True
,
})
json_response
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
200
,
response
.
status_code
)
self
.
assertEqual
(
'mock_user@email.com'
,
json_response
.
get
(
"username"
))
time
.
sleep
(
1
)
@
patch
(
'oauth.views.json.loads'
)
def
test_google_login_not_exist
(
self
,
mock_json_loads
):
email
=
'mock_user4545@email.com'
passcode
=
'pass1234567'
mock_json_loads
.
return_value
=
{
"email"
:
'mock_user4545@email.com'
}
response
=
Client
().
post
(
'/api-token-auth/'
,
{
'username'
:
email
,
'name'
:
'name'
,
"access_token"
:
"sankdsanlk"
,
'password'
:
passcode
,
'google'
:
True
,
})
json_response
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
200
,
response
.
status_code
)
self
.
assertEqual
(
'mock_user4545@email.com'
,
json_response
.
get
(
"username"
))
time
.
sleep
(
1
)
@
patch
(
'oauth.views.json.loads'
)
def
test_google_login_error
(
self
,
mock_json_loads
):
email
=
'mock_user4545@email.com'
passcode
=
'pass1234567'
mock_json_loads
.
return_value
=
{
"error"
:
'error'
}
response
=
Client
().
post
(
'/api-token-auth/'
,
{
'username'
:
email
,
'name'
:
'name'
,
"access_token"
:
"sankdsanlk"
,
'password'
:
passcode
,
'google'
:
True
,
})
json_response
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
404
,
response
.
status_code
)
self
.
assertTrue
(
"message"
in
json_response
)
time
.
sleep
(
1
)
oauth/views.py
View file @
fa3c33d2
import
requests
import
random
from
urllib.parse
import
parse_qs
,
urlparse
from
rest_framework.utils
import
json
from
rest_framework.views
import
APIView
from
rest_framework.response
import
Response
from
rest_framework_simplejwt.tokens
import
RefreshToken
from
rest_framework.permissions
import
IsAuthenticated
from
rest_framework.authtoken.models
import
Token
from
django.views.decorators.csrf
import
csrf_exempt
from
django.http
import
JsonResponse
,
HttpResponse
from
django.http
import
JsonResponse
from
django.contrib.auth
import
authenticate
from
django.contrib.auth.base_user
import
BaseUserManager
from
django.contrib.auth.hashers
import
make_password
from
django.contrib.auth.models
import
User
from
pplbackend.settings
import
GOOGLE_OAUTH2_CLIENT_ID
,
GOOGLE_OAUTH2_CLIENT_SECRET
from
django.conf
import
settings
from
registrasi.models
import
BisaGoUser
...
...
@@ -27,30 +19,32 @@ def request_token(request):
password
=
request
.
POST
[
"password"
]
google
=
request
.
POST
.
get
(
"google"
,
False
)
response
=
{}
status
=
200
if
google
:
access_token
=
request
.
POST
[
"access_token"
]
name
=
request
.
POST
[
"name"
]
try
:
user
=
User
.
objects
.
get
(
email
=
email
)
result_code
,
result_email
=
validate_google_token
(
access_token
)
if
result_code
:
user
=
User
.
objects
.
get
(
email
=
result_email
)
email
=
result_email
else
:
return
result_email
except
User
.
DoesNotExist
:
user
,
status
=
_re
quest_token_from
_google
(
email
,
access_token
,
name
)
user
=
_
c
re
ate
_google
_user
(
email
,
name
)
else
:
try
:
user
=
authenticate
(
request
,
username
=
email
,
password
=
password
)
if
user
is
None
:
User
.
objects
.
get
(
email
=
email
)
except
User
.
DoesNotExist
:
response
[
"response"
]
=
"User not exist"
return
JsonResponse
(
response
,
status
=
404
)
if
status
!=
200
:
return
response
if
user
is
not
None
:
if
user
.
is_active
:
#print("user active")
token
,
create
=
Token
.
objects
.
get_or_create
(
user
=
user
)
response
=
{}
response
[
'username'
]
=
user
.
username
response
[
'token'
]
=
token
.
key
response
[
'token_type'
]
=
"token"
response
=
{
'username'
:
user
.
username
,
'token'
:
token
.
key
,
'token_type'
:
"token"
}
return
JsonResponse
(
response
,
status
=
200
)
else
:
response
[
"response"
]
=
"Please activate your account"
...
...
@@ -58,15 +52,9 @@ def request_token(request):
else
:
response
[
"response"
]
=
"Wrong password"
return
JsonResponse
(
response
,
status
=
400
)
@
csrf_exempt
def
_request_token_from_google
(
email
,
access_token
,
name
):
payload
=
{
'access_token'
:
access_token
}
# validate the token
req
=
requests
.
get
(
'https://www.googleapis.com/oauth2/v2/userinfo'
,
params
=
payload
)
data
=
json
.
loads
(
req
.
text
)
if
'error'
in
data
:
content
=
{
'message'
:
'wrong google token / this google token is already expired.'
}
return
None
,
JsonResponse
(
content
,
status
=
404
)
def
_create_google_user
(
email
,
name
):
user
=
User
()
user
.
username
=
email
# provider random default password
...
...
@@ -77,18 +65,18 @@ def _request_token_from_google(email, access_token, name):
user
.
save
()
random_generated_phone_number
=
'x'
.
join
([
str
(
random
.
randint
(
0
,
9
))
for
i
in
range
(
8
)])
BisaGoUser
.
objects
.
create
(
user
=
user
,
phone_number
=
random_generated_phone_number
)
return
user
,
200
return
user
@
csrf_exempt
def
validate_google_token
(
email
,
access_token
):
def
validate_google_token
(
access_token
):
payload
=
{
'access_token'
:
access_token
}
# validate the token
req
=
requests
.
get
(
'https://www.googleapis.com/oauth2/v2/userinfo'
,
params
=
payload
)
req
=
requests
.
get
(
'https://www.googleapis.com/oauth2/v2/userinfo'
,
params
=
payload
,
proxies
=
settings
.
PROXIES
)
data
=
json
.
loads
(
req
.
text
)
if
'error'
in
data
:
if
'error'
in
data
or
'email'
not
in
data
:
content
=
{
'message'
:
'wrong google token / this google token is already expired.'
}
return
Non
e
,
JsonResponse
(
content
,
status
=
404
)
return
User
.
objects
.
get
(
email
=
email
)
return
Fals
e
,
JsonResponse
(
content
,
status
=
404
)
return
True
,
data
.
get
(
"
email
"
)
...
...
pplbackend/settings.py
View file @
fa3c33d2
...
...
@@ -26,7 +26,7 @@ SECRET_KEY = os.getenv("SECRET_KEY", 'akua')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG
=
FALSE
DEBUG
=
True
ALLOWED_HOSTS
=
[
'localhost'
,
'127.0.0.1'
,
'10.119.105.26'
,
'bisago.cs.ui.ac.id'
]
...
...
@@ -167,7 +167,8 @@ SITE_ID = 1
AUTHENTICATION_BACKENDS
=
[
# Default backend -- used to login by username in Django admin
"django.contrib.auth.backends.ModelBackend"
,
# This allow inactive user to authenticate
'django.contrib.auth.backends.AllowAllUsersModelBackend'
,
# `allauth` specific authentication methods, such as login by e-mail
"allauth.account.auth_backends.AuthenticationBackend"
,
]
...
...
@@ -221,3 +222,11 @@ SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME'
:
timedelta
(
days
=
1
),
'REFRESH_TOKEN_LIFETIME'
:
timedelta
(
days
=
90
),
}
http_proxy
=
os
.
environ
.
get
(
'http_proxy'
,
''
)
https_proxy
=
os
.
environ
.
get
(
'https_proxy'
,
''
)
PROXIES
=
{
"http"
:
http_proxy
,
"https"
:
https_proxy
}
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