Fakultas Ilmu Komputer UI

Commit b1cbe801 authored by Fakhira Devina's avatar Fakhira Devina
Browse files

Merge branch 'dev-rafif' into 'development'

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

See merge request !5
parents 200593b8 fa3c33d2
Pipeline #64613 failed with stages
in 18 minutes and 6 seconds
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"
......@@ -59,14 +53,8 @@ def request_token(request):
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