summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authort3jasKharat2024-06-06 10:23:17 +0530
committert3jasKharat2024-06-12 15:35:09 +0530
commit095415cec26711945eceda0e3e5a74250c8fba3c (patch)
treeab324ea7e5232f4ffc2a8d638c17411ede94942f
parente273a3245f9a52475dba75be909752d0e800c719 (diff)
downloadCommon-Interface-Project-095415cec26711945eceda0e3e5a74250c8fba3c.tar.gz
Common-Interface-Project-095415cec26711945eceda0e3e5a74250c8fba3c.tar.bz2
Common-Interface-Project-095415cec26711945eceda0e3e5a74250c8fba3c.zip
Login with github feature added
-rw-r--r--blocks/authAPI/templates/github_callback.html20
-rw-r--r--blocks/authAPI/urls.py4
-rw-r--r--blocks/authAPI/views.py64
-rw-r--r--blocks/blocks/settings.py15
-rw-r--r--blocks/eda-frontend/src/pages/Login.js22
-rw-r--r--blocks/eda-frontend/src/pages/signUp.js22
-rw-r--r--blocks/eda-frontend/src/redux/actions/authActions.js23
-rw-r--r--blocks/eda-frontend/src/static/github-mark.pngbin0 -> 6393 bytes
8 files changed, 154 insertions, 16 deletions
diff --git a/blocks/authAPI/templates/github_callback.html b/blocks/authAPI/templates/github_callback.html
new file mode 100644
index 00000000..97efd1b2
--- /dev/null
+++ b/blocks/authAPI/templates/github_callback.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Redirecting to the destination...</title>
+ <script>
+ window.localStorage.setItem('Xcos_token', '{{ token }}');
+ var redirect_to = window.localStorage.getItem('ard_redurl');
+ if (redirect_to) {
+ window.localStorage.removeItem('ard_redurl');
+ window.open(redirect_to, '_self')
+ } else {
+ window.open('{{ url }}', '_self')
+ }
+ </script>
+</head>
+<body></body>
+</html>
diff --git a/blocks/authAPI/urls.py b/blocks/authAPI/urls.py
index e38fb710..d9b6c00c 100644
--- a/blocks/authAPI/urls.py
+++ b/blocks/authAPI/urls.py
@@ -3,6 +3,10 @@ from authAPI import views as authAPI_views
urlpatterns = [
+
+ # GitHub OAuth2 callback
+ url(r'^github-callback', authAPI_views.GitHubOAuth2, name='github-callback'),
+
url(r'^google-callback', authAPI_views.GoogleOAuth2),
url(r'^users/activate/(?P<uid>[\w-]+)/(?P<token>[\w-]+)/$',
authAPI_views.activate_user),
diff --git a/blocks/authAPI/views.py b/blocks/authAPI/views.py
index 7213775b..b782ecbb 100644
--- a/blocks/authAPI/views.py
+++ b/blocks/authAPI/views.py
@@ -1,10 +1,10 @@
+import logging
from rest_framework import generics, status, permissions
from rest_framework.response import Response
from django.conf import settings
from requests_oauthlib import OAuth2Session
from django.contrib.auth import get_user_model
from djoser.conf import settings as djoser_settings
-from random import randint
from django.shortcuts import render
from django.http import HttpResponseNotFound
from djoser import utils
@@ -14,6 +14,8 @@ from blocks.settings import DOMAIN
Token = djoser_settings.TOKEN_MODEL
+# Set up logging
+logger = logging.getLogger(__name__)
def activate_user(request, uid, token):
"""
@@ -61,7 +63,6 @@ def GoogleOAuth2(request):
user, created = get_user_model().objects.get_or_create(
email=user_info['email'])
if created:
- # If User was created, set name to email
user.username = user_info['email']
user.save()
if not user.is_active:
@@ -79,6 +80,61 @@ def GoogleOAuth2(request):
})
+def GitHubOAuth2(request):
+ state = request.GET.get('state', None)
+ code = request.GET.get('code', None)
+
+ if state is None or state == '' or code is None or code == '':
+ return HttpResponseNotFound("<h1>Page Not Found</h1>")
+
+ client_id = settings.SOCIAL_AUTH_GITHUB_KEY
+ client_secret = settings.SOCIAL_AUTH_GITHUB_SECRET
+
+ github = OAuth2Session(
+ client_id,
+ redirect_uri=settings.GITHUB_OAUTH_REDIRECT_URI,
+ state=state
+ )
+ try:
+ github.fetch_token(
+ 'https://github.com/login/oauth/access_token',
+ client_secret=client_secret,
+ code=code
+ )
+ except Exception as e:
+ logger.error(f"Failed to fetch token from GitHub: {e}")
+ return HttpResponseNotFound("<h1>Failed to authenticate with GitHub</h1>")
+
+ try:
+ user_info = github.get('https://api.github.com/user').json()
+ except Exception as e:
+ logger.error(f"Failed to get user info from GitHub: {e}")
+ return HttpResponseNotFound("<h1>Failed to get user info from GitHub</h1>")
+
+ primary_email = f"{user_info['id']}+{user_info['login']}@users.noreply.github.com"
+
+ if primary_email:
+ user, created = get_user_model().objects.get_or_create(email=primary_email)
+ if created:
+ user.username = primary_email
+ user.save()
+ if not user.is_active:
+ user.is_active = True
+ user.save()
+ token, created = Token.objects.get_or_create(user=user)
+
+ protocol = 'https://' if request.is_secure() else 'http://'
+ web_url = protocol + DOMAIN + '/#/dashboard'
+
+ return render(request, 'github_callback.html', {
+ "token": token.key,
+ "url": web_url
+ })
+ else:
+ logger.error("Primary email not found for GitHub user")
+ return HttpResponseNotFound("<h1>Email not found</h1>")
+
+
class CustomTokenCreateView(utils.ActionViewMixin, generics.GenericAPIView):
"""
Use this endpoint to obtain user authentication token.
@@ -94,6 +150,4 @@ class CustomTokenCreateView(utils.ActionViewMixin, generics.GenericAPIView):
'auth_token': token_serializer_class(token).data["auth_token"],
'user_id': serializer.user.id
}
- return Response(
- data=data, status=status.HTTP_200_OK
- )
+ return Response(data=data, status=status.HTTP_200_OK)
diff --git a/blocks/blocks/settings.py b/blocks/blocks/settings.py
index c799a88a..e8147235 100644
--- a/blocks/blocks/settings.py
+++ b/blocks/blocks/settings.py
@@ -20,7 +20,6 @@ load_dotenv()
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent
-
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
@@ -97,7 +96,6 @@ WSGI_APPLICATION = 'blocks.wsgi.application'
AUTH_USER_MODEL = 'authAPI.User'
-
# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
@@ -108,7 +106,6 @@ DATABASES = {
}
}
-
# Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
@@ -127,7 +124,6 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
-
# Mail server config
# use this for console emails
@@ -144,6 +140,9 @@ SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.environ.get('SOCIAL_AUTH_GOOGLE_OAUTH2_KEY',
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.environ.get('SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET', '')
GOOGLE_OAUTH_REDIRECT_URI = os.environ.get('GOOGLE_OAUTH_REDIRECT_URI',
'http://localhost/api/auth/google-callback')
+SOCIAL_AUTH_GITHUB_KEY = os.environ.get('SOCIAL_AUTH_GITHUB_KEY', '')
+SOCIAL_AUTH_GITHUB_SECRET = os.environ.get('SOCIAL_AUTH_GITHUB_SECRET', '')
+GITHUB_OAUTH_REDIRECT_URI = os.environ.get('GITHUB_OAUTH_REDIRECT_URI', 'http://localhost/api/auth/github-callback')
POST_ACTIVATE_REDIRECT_URL = os.environ.get('POST_ACTIVATE_REDIRECT_URL',
'http://localhost/')
DOMAIN = os.environ.get('EMAIL_DOMAIN', 'localhost')
@@ -160,7 +159,10 @@ DJOSER = {
'ACTIVATION_URL': 'api/auth/users/activate/{uid}/{token}/',
'SEND_ACTIVATION_EMAIL': True,
'SOCIAL_AUTH_TOKEN_STRATEGY': 'authAPI.token.TokenStrategy',
- 'SOCIAL_AUTH_ALLOWED_REDIRECT_URIS': [GOOGLE_OAUTH_REDIRECT_URI],
+ 'SOCIAL_AUTH_ALLOWED_REDIRECT_URIS': [
+ GOOGLE_OAUTH_REDIRECT_URI,
+ GITHUB_OAUTH_REDIRECT_URI,
+ ],
'SERIALIZERS': {
'user_create': 'authAPI.serializers.UserCreateSerializer',
'user': 'authAPI.serializers.UserCreateSerializer',
@@ -178,6 +180,7 @@ REST_FRAMEWORK = {
AUTHENTICATION_BACKENDS = (
'social_core.backends.google.GoogleOAuth2',
+ 'social_core.backends.github.GithubOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
@@ -194,7 +197,6 @@ USE_L10N = True
USE_TZ = True
-
# Allow CORS for Public API
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOWED_ORIGINS = [i for i in os.environ.get('CORS_ALLOWED_ORIGINS', '').split(',') if i != '']
@@ -219,7 +221,6 @@ CELERY_IMPORTS = (
'simulationAPI.tasks',
)
-
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
diff --git a/blocks/eda-frontend/src/pages/Login.js b/blocks/eda-frontend/src/pages/Login.js
index 1c081616..e14b26fb 100644
--- a/blocks/eda-frontend/src/pages/Login.js
+++ b/blocks/eda-frontend/src/pages/Login.js
@@ -22,8 +22,9 @@ import Visibility from '@material-ui/icons/Visibility'
import VisibilityOff from '@material-ui/icons/VisibilityOff'
import { Link as RouterLink } from 'react-router-dom'
import { useSelector, useDispatch } from 'react-redux'
-import { login, authDefault, googleLogin } from '../redux/actions/index'
+import { login, authDefault, googleLogin, githubLogin } from '../redux/actions/index'
import google from '../static/google.png'
+import github from '../static/github-mark.png'
const useStyles = makeStyles((theme) => ({
paper: {
@@ -84,6 +85,13 @@ export default function SignIn (props) {
dispatch(googleLogin(host))
}
+ // Function call for github login.
+ const handleGithubLogin = () => {
+ const host = window.location.origin
+ const toUrl = '' // Add any redirect URL logic if needed
+ dispatch(githubLogin(host, toUrl))
+ }
+
return (
<Container component='main' maxWidth='xs'>
<Card className={classes.paper}>
@@ -177,7 +185,17 @@ export default function SignIn (props) {
onClick={handleGoogleLogin}
className={classes.submit}
>
- <img alt='G' src={google} height='20' />&emsp; Login With Google
+ <img alt='Google' src={google} height='20' />&emsp; Login With Google
+ </Button>
+ {/* Github Sign Up option */}
+ <Button
+ fullWidth
+ variant='outlined'
+ color='primary'
+ onClick={handleGithubLogin}
+ className={classes.submit}
+ >
+ <img alt='GitHub' src={github} height='20' />&emsp; Login With GitHub
</Button>
</Card>
<Button
diff --git a/blocks/eda-frontend/src/pages/signUp.js b/blocks/eda-frontend/src/pages/signUp.js
index b60da8dc..38fd7ea0 100644
--- a/blocks/eda-frontend/src/pages/signUp.js
+++ b/blocks/eda-frontend/src/pages/signUp.js
@@ -20,8 +20,9 @@ import Visibility from '@material-ui/icons/Visibility'
import VisibilityOff from '@material-ui/icons/VisibilityOff'
import { Link as RouterLink, useHistory } from 'react-router-dom'
import { useSelector, useDispatch } from 'react-redux'
-import { signUp, authDefault, googleLogin } from '../redux/actions/index'
+import { signUp, authDefault, googleLogin, githubLogin } from '../redux/actions/index'
import google from '../static/google.png'
+import github from '../static/github-mark.png'
const useStyles = makeStyles((theme) => ({
paper: {
@@ -76,6 +77,13 @@ export default function SignUp () {
dispatch(googleLogin(host))
}
+ // Function call for github sign up.
+ const handleGithubLogin = () => {
+ const host = window.location.origin
+ const toUrl = '' // Add any redirect URL logic if needed
+ dispatch(githubLogin(host, toUrl))
+ }
+
return (
<Container component='main' maxWidth='xs'>
<Card className={classes.paper}>
@@ -185,7 +193,17 @@ export default function SignUp () {
onClick={handleGoogleSignup}
className={classes.submit}
>
- <img alt='G' src={google} height='20' />&emsp; Sign Up With Google
+ <img alt='Google' src={google} height='20' />&emsp; Sign Up With Google
+ </Button>
+ {/* Github Sign Up option */}
+ <Button
+ fullWidth
+ variant='outlined'
+ color='primary'
+ onClick={handleGithubLogin}
+ className={classes.submit}
+ >
+ <img alt='GitHub' src={github} height='20' />&emsp; Sign Up With GitHub
</Button>
</form>
diff --git a/blocks/eda-frontend/src/redux/actions/authActions.js b/blocks/eda-frontend/src/redux/actions/authActions.js
index dd2677d9..7fff2eb9 100644
--- a/blocks/eda-frontend/src/redux/actions/authActions.js
+++ b/blocks/eda-frontend/src/redux/actions/authActions.js
@@ -251,3 +251,26 @@ export const googleLogin = (host, toUrl) => {
})
}
}
+
+// Api call for GitHub OAuth login or sign up
+export const githubLogin = (host, toUrl) => {
+ return function (dispatch) {
+ api.get('auth/o/github/?redirect_uri=' + host + '/api/auth/github-callback')
+ .then((res) => {
+ if (res.status === 200) {
+ // Open GitHub login page
+ window.open(res.data.authorization_url, '_self')
+ } else {
+ dispatch(loginFailed('Something went wrong! Login Failed'))
+ }
+ })
+ .catch((err) => {
+ const res = err.response
+ if (res && (res.status === 400 || res.status === 403 || res.status === 401)) {
+ dispatch(loginError('Incorrect Username or Password.'))
+ } else {
+ dispatch(loginError('Something went wrong! Login Failed'))
+ }
+ })
+ }
+}
diff --git a/blocks/eda-frontend/src/static/github-mark.png b/blocks/eda-frontend/src/static/github-mark.png
new file mode 100644
index 00000000..6cb3b705
--- /dev/null
+++ b/blocks/eda-frontend/src/static/github-mark.png
Binary files differ