Skip to content

Commit

Permalink
Merge branch 'null-open-security-community:main' into Resume-Function…
Browse files Browse the repository at this point in the history
…ality-Updation---I
  • Loading branch information
Parth858 authored Jan 15, 2024
2 parents 9300bde + e6fe66e commit 6db443d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 70 deletions.
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ EMAIL_FROM='your-email'

# Google auth Credentials
GOOGLE_OAUTH_CLIENT_ID='google client id'
GOOGLE_OAUTH_SECRET='google secret'
GOOGLE_OAUTH_SECRET='google secret key'
GOOGLE_REDIRECT_URI='http://localhost:8000/google/login/callback/'

2 changes: 2 additions & 0 deletions apps/accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ class User(AbstractBaseUser):
otp_secret = models.CharField(max_length=200, null=True)
dummy_password = models.CharField(max_length=200, null=True)
user_type = models.CharField(max_length=12, choices=USER_TYPE, null=False)
last_verified_identity = models.DateTimeField(auto_now=False, auto_now_add=False, null=True)
login_method = models.CharField(max_length=50, null=True)

objects = UserManager()

Expand Down
109 changes: 58 additions & 51 deletions apps/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
# from django.urls import reverse
import urllib.parse

import secrets
import requests
import logging
from django.conf import settings
from django.contrib.auth import authenticate
from rest_framework import status
Expand All @@ -28,6 +30,8 @@
# from dj_rest_auth.registration.views import SocialLoginView


logger = logging.getLogger(__name__)

# Generate token Manually
class TokenUtility:
@staticmethod
Expand Down Expand Up @@ -344,48 +348,63 @@ def post(self, request, format=None):
)


# Hit on that url to get the callback
# https://accounts.google.com/o/oauth2/v2/auth?client_id=<google-client-id>&response_type=code&scope=https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile&access_type=offline&redirect_uri=http://localhost:8000/api/user/google/login/callback/


class GoogleHandle(APIView):
renderer_classes = [UserRenderer]

def get(self, request):
client_id = os.environ.get("GOOGLE_OAUTH_CLIENT_ID")
response_type = "code"
scope = f"https://www.googleapis.com/auth/userinfo.email "
scope += f"https://www.googleapis.com/auth/userinfo.profile"
access_type = "offline"
redirect_uri = settings.GOOGLE_REDIRECT_URI

google_redirect_url = "https://accounts.google.com/o/oauth2/v2/auth"
google_redirect_url += f"?client_id={urllib.parse.quote(client_id)}"
google_redirect_url += f"&response_type={urllib.parse.quote(response_type)}"
google_redirect_url += f"&scope={urllib.parse.quote(scope)}"
google_redirect_url += f"&access_type={urllib.parse.quote(access_type)}"
google_redirect_url += f"&redirect_uri={urllib.parse.quote(redirect_uri)}"
def get(self, request):
# creating a random state
state = secrets.token_urlsafe(32)

# defining the sessions params
params = {
"redirect_uri": settings.GOOGLE_REDIRECT_URI,
"scope": "openid email profile",
"state": state,
"client_id": settings.GOOGLE_CLIENT_ID,
"response_type": "code",
}
request_url = "{}?{}".format(
"https://accounts.google.com/o/oauth2/v2/auth",
urllib.parse.urlencode(params)
)

# setting the state in sessions
request.session["oauth_token"] = state

return Response(
{"google_redirect_url": google_redirect_url}, status=status.HTTP_200_OK
{"google_redirect_url": request_url},
status=status.HTTP_200_OK
)


class CallbackHandleView(APIView):
renderer_classes = [UserRenderer]

def get(self, request):
# verify the state on this request
state = request.query_params.get("state")
if request.session["oauth_token"] != state:
return Response(
{"msg": "Invalid request"},
status=status.HTTP_403_FORBIDDEN
)

# using the code to get the tokens
# and eventually the user profile
code = request.query_params.get("code")
data = {
"code": code,
"client_id": os.environ.get("GOOGLE_OAUTH_CLIENT_ID"),
"client_secret": os.environ.get("GOOGLE_OAUTH_SECRET"),
"client_id": settings.GOOGLE_CLIENT_ID,
"client_secret": settings.GOOGLE_SECRET_KEY,
"redirect_uri": settings.GOOGLE_REDIRECT_URI,
"grant_type": "authorization_code",
}

token_response = requests.post("https://oauth2.googleapis.com/token", data=data)
token_data = token_response.json()
logger.debug(token_data)

# if the token data has error
if "error" in token_data:
return Response(
{"error": "Failed to get access token from Google."},
Expand All @@ -394,7 +413,6 @@ def get(self, request):

# Get the access token from the response
access_token = token_data.get("access_token", None)
# print(access_token)
if not access_token:
return Response(
{"error": "Failed to get access token from Google response."},
Expand All @@ -406,48 +424,37 @@ def get(self, request):
f"https://www.googleapis.com/oauth2/v2/userinfo?access_token={access_token}"
)
user_info = user_info_response.json()
# print(user_info)

# Extract the email and name from the user information
email = user_info.get("email", None)
name = user_info.get("name", None)
if not email:
return Response(
{"error": "Failed to get email from Google user info."},
status=status.HTTP_400_BAD_REQUEST,
)
if not name:
if not email or not name:
return Response(
{"error": "Failed to get name from Google user info."},
{"error": "Failed to get data from Google user info."},
status=status.HTTP_400_BAD_REQUEST,
)

try:
# Login the user
user = User.objects.get(email=email)
user, created = User.objects.get_or_create(email=email, defaults={
"name": name,
"login_method": "google_login",
"last_verified_identity": datetime.datetime.now()
})

if not created:
user.last_verified_identity = datetime.datetime.now()
user.save()

jwt_token = TokenUtility.get_tokens_for_user(user)
return Response(
{"token": jwt_token, "msg": "Login Success"}, status=status.HTTP_200_OK
{"token": jwt_token, "msg": "Success"}, status=status.HTTP_200_OK
)

except User.DoesNotExist:
userdata = {"email": email, "name": name}
serializer = GoogleAuthSerializer(
data=request.data, context={"userdata": userdata}
)
serializer.is_valid(raise_exception=True)
user = serializer.save()
user.provider = "google"
user.is_verified = True
user.save()
token = TokenUtility.get_tokens_for_user(user)
return Response(
{"msg": "Registration Completed", "token": token},
status=status.HTTP_201_CREATED,
)

except:
except Exception as e:
print(e)
return Response(
{"errors": "Invalid user"}, status=status.HTTP_400_BAD_REQUEST
{"msg": "There was an error authenticating the user"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)


Expand Down
22 changes: 4 additions & 18 deletions null_jobs_backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,30 +121,16 @@
# User Model
AUTH_USER_MODEL = "accounts.User"

# google auth configuration
SOCIALACCOUNT_PROVIDERS = {
"google": {
"APP": {
"client_id": os.environ.get("GOOGLE_OAUTH_CLIENT_ID"),
"secret": os.environ.get("GOOGLE_OAUTH_SECRET"),
},
"SCOPE": [
"profile",
"email",
],
"AUTH_PARAMS": {
"access_type": "online",
},
}
}

# google auth settings
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
GOOGLE_REDIRECT_URI = "http://localhost:8000/google/login/callback/"

GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_OAUTH_CLIENT_ID")
GOOGLE_SECRET_KEY = os.environ.get("GOOGLE_OAUTH_SECRET")
GOOGLE_REDIRECT_URI = os.environ.get("GOOGLE_REDIRECT_URI")

# dj-rest-auth setting
JWT_AUTH_SECURE = True
Expand Down

0 comments on commit 6db443d

Please sign in to comment.