diff --git a/.gitignore b/.gitignore
index c217378..5e6c943 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ __pycache__/
.env
.vscode/
.Pipfile.lock
+*client_secret.json*
diff --git a/backend/users/backend.py b/backend/users/backend.py
index 0b16017..0a6383c 100644
--- a/backend/users/backend.py
+++ b/backend/users/backend.py
@@ -1,17 +1,38 @@
+from django.conf import settings
from django.contrib.auth.backends import ModelBackend
+from google.auth.transport import requests
+from google.oauth2 import id_token
+from google_auth_oauthlib.flow import Flow
+from .mail import send_validation_mail
from .models import User
class OAuthAuthenticationBackend(ModelBackend):
"""
- Authentication backend to allow authenticating users against a
- Microsoft ADFS server with an authorization code.
+ Authentication backend to allow user use Google to login.
"""
def authenticate(self, request, username=None, password=None, **kwargs):
- if kwargs.get('id_info'):
- user = self.get_google_oauth_user(kwargs.get('id_info'))
+ state = kwargs.get('oauth_state')
+ flow = Flow.from_client_secrets_file(
+ f'{settings.ROOT_DIR}/backend/client_secret.json',
+ scopes=None,
+ redirect_uri=request.build_absolute_uri('/users/google-callback/'),
+ )
+
+ # Use the authorization response to get tokens
+ flow.fetch_token(authorization_response=request.build_absolute_uri(), state=state)
+
+ # Use the id_token to get user information
+ token = flow.credentials.id_token
+ request_google_oauth = requests.Request()
+ id_info = id_token.verify_oauth2_token(
+ token,
+ request_google_oauth,
+ )
+
+ user = self.get_google_oauth_user(id_info)
return user
def get_google_oauth_user(self, id_info):
@@ -24,5 +45,6 @@ def get_google_oauth_user(self, id_info):
user = User.objects.get(email=data['email'])
except User.DoesNotExist:
user = User.objects.create(**data)
+ send_validation_mail(email=data['email'])
return user
diff --git a/backend/users/mail.py b/backend/users/mail.py
index f34bd11..14b0f21 100644
--- a/backend/users/mail.py
+++ b/backend/users/mail.py
@@ -30,4 +30,5 @@ def send_validation_mail(email: str):
recipient_list,
html_message=f'{message}
{url}{token}',
)
+ print(f'Email sent successfully to {recipient_list} !')
return ({'title': 'Success', 'detail': 'Validation email sent.'},)
diff --git a/backend/users/views.py b/backend/users/views.py
index e653407..b065c47 100644
--- a/backend/users/views.py
+++ b/backend/users/views.py
@@ -5,8 +5,6 @@
from django.shortcuts import redirect
from django.utils import timezone
from django.utils.http import url_has_allowed_host_and_scheme
-from google.auth.transport import requests
-from google.oauth2 import id_token
from google_auth_oauthlib.flow import Flow
from rest_framework import generics, permissions, status
from rest_framework.decorators import action
@@ -26,11 +24,20 @@ class OAuthViewset(GenericViewSet):
@action(detail=False, methods=['get'], url_path='google-login')
def google_login(self, request):
# Set up the Google OAuth2.0 flow
- flow = Flow.from_client_secrets_file(
- f'{settings.ROOT_DIR}/backend/client_secret.json',
- scopes=['openid', 'profile', 'email'],
- redirect_uri=request.build_absolute_uri('/users/google-callback/'),
- )
+ try:
+ flow = Flow.from_client_secrets_file(
+ f'{settings.ROOT_DIR}/backend/client_secret.json',
+ scopes=['openid', 'profile', 'email'],
+ redirect_uri=request.build_absolute_uri('/users/google-callback/'),
+ )
+ except FileNotFoundError:
+ return Response(
+ {
+ 'title': 'Error',
+ 'Detail': 'Google login is currently disabled due'
+ + 'to missing client secrets on the host server.',
+ },
+ )
authorization_url, state = flow.authorization_url(prompt='consent')
# Store the state so the callback can verify the response.
@@ -42,25 +49,7 @@ def google_callback(self, request): # pragma: no cover
# Get the state from the session to verify the response.
state = request.session.get('oauth_state')
- flow = Flow.from_client_secrets_file(
- f'{settings.ROOT_DIR}/backend/client_secret.json',
- scopes=None,
- redirect_uri=request.build_absolute_uri('/users/google-callback/'),
- )
-
- # Use the authorization response to get tokens
- flow.fetch_token(authorization_response=request.build_absolute_uri(), state=state)
-
- # Use the id_token to get user information
- token = flow.credentials.id_token
- request_google_oauth = requests.Request()
- id_info = id_token.verify_oauth2_token(
- token,
- request_google_oauth,
- )
-
- user = authenticate(request=request, id_info=id_info)
-
+ user = authenticate(request=request, oauth_state=state)
if user:
if user.is_active:
login(request, user)