Fakultas Ilmu Komputer UI

Commit fa3c33d2 authored by Muhammad Rafif Elfazri's avatar Muhammad Rafif Elfazri Committed by Fakhira Devina
Browse files

Fix Security flaws on google oauth and create test for oauth modules

parent 200593b8
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)
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 = _request_token_from_google(email, access_token, name)
user = _create_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 None, JsonResponse(content, status=404)
return User.objects.get(email=email)
return False, JsonResponse(content, status=404)
return True, data.get("email")
......
......@@ -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
}
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