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 django.shortcuts import render from django.http import HttpResponseNotFound from djoser import utils from djoser.serializers import TokenSerializer from authAPI.serializers import TokenCreateSerializer from blocks.settings import DOMAIN Token = djoser_settings.TOKEN_MODEL # Set up logging logger = logging.getLogger(__name__) def activate_user(request, uid, token): """ Used to activate accounts, sends POST request to /api/auth/users/activation/ route internally to activate account. Link to this route is sent via email to user for verification """ protocol = 'https://' if request.is_secure() else 'http://' web_url = protocol + request.get_host() + '/api/auth/users/activation/' # URL comes from Djoser library return render(request, 'activate_user.html', {'uid': uid, 'token': token, 'activation_url': web_url, 'redirect_url': settings.POST_ACTIVATE_REDIRECT_URL }) def get_social_user(email, request, callback, service): if not email: logger.error(f'Email not found for {service} user') return HttpResponseNotFound('

Email not found

') user, created = get_user_model().objects.get_or_create(email=email) if created: user.username = 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, callback, {'token': token, 'url': web_url }) def GoogleOAuth2(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('

Page Not Found

') client_id = settings.SOCIAL_AUTH_GOOGLE_OAUTH2_KEY client_secret = settings.SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET google = OAuth2Session( client_id, redirect_uri=settings.GOOGLE_OAUTH_REDIRECT_URI, state=state ) google.fetch_token( 'https://accounts.google.com/o/oauth2/token', client_secret=client_secret, code=code ) user_info = google.get( 'https://www.googleapis.com/oauth2/v1/userinfo').json() return get_social_user(user_info['email'], request, 'google_callback.html', 'google') 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('

Page Not Found

') 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('

Failed to authenticate with GitHub

') 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('

Failed to get user info from GitHub

') primary_email = f"{user_info['id']}+{user_info['login']}@users.noreply.github.com" return get_social_user(primary_email, request, 'github_callback.html', 'github') class CustomTokenCreateView(utils.ActionViewMixin, generics.GenericAPIView): """ Use this endpoint to obtain user authentication token. """ serializer_class = TokenCreateSerializer permission_classes = [permissions.AllowAny] def _action(self, serializer): token = utils.login_user(self.request, serializer.user) token_serializer_class = TokenSerializer data = { 'auth_token': token_serializer_class(token).data['auth_token'], 'user_id': serializer.user.id } return Response(data=data, status=status.HTTP_200_OK)