diff --git a/.gitignore b/.gitignore index 445be84..3fba3fc 100644 --- a/.gitignore +++ b/.gitignore @@ -140,3 +140,4 @@ dmypy.json .idea *.pyc dev.env +.vscode/settings.json diff --git a/CDC_Backend/APIs/constants.py b/CDC_Backend/APIs/constants.py index bf5b7e8..a25eba5 100644 --- a/CDC_Backend/APIs/constants.py +++ b/CDC_Backend/APIs/constants.py @@ -49,6 +49,9 @@ CDC_MAIl_ADDRESS = 'cdc@iitdh.ac.in' # To be Configured Properly CLIENT_ID = os.environ.get('GOOGLE_OAUTH_CLIENT_ID') # Google Login Client ID +CLIENT_SECRET = os.environ.get('GOOGLE_OAUTH_CLIENT_SECRET') # Google Login Client Secret +REDIRECT_URI = 'postmessage' # Google Login Redirect URI +OAUTH2_API_ENDPOINT = 'https://oauth2.googleapis.com/token' # Google Login OAUTH2 URL # To be Configured Properly PLACEMENT_OPENING_URL = "https://cdc.iitdh.ac.in/portal/student/dashboard/placements/{id}" # On frontend, this is the URL to be opened @@ -58,6 +61,9 @@ LINK_TO_APPLICATIONS_CSV = "https://cdc.iitdh.ac.in/storage/Application_CSV/" LINK_TO_EMAIl_VERIFICATION_API = "https://cdc.iitdh.ac.in/portal/company/verifyEmail?token={token}" PDF_FILES_SERVING_ENDPOINT = 'https://cdc.iitdh.ac.in/storage/Company_Attachments/' # TODO: Change this to actual URL +AUTH_CODE = "code" +ID_TOKEN = "id_token" +REFRESH_TOKEN = "refresh_token" EMAIL = "email" STUDENT = 'student' diff --git a/CDC_Backend/APIs/studentViews.py b/CDC_Backend/APIs/studentViews.py index c68d846..b595dd8 100644 --- a/CDC_Backend/APIs/studentViews.py +++ b/CDC_Backend/APIs/studentViews.py @@ -7,15 +7,42 @@ logger = logging.getLogger('db') @api_view(['POST']) +@precheck(required_data=[AUTH_CODE]) +@get_token() @isAuthorized(allowed_users='*') -def login(request, id, email, user_type): +def login(request, id, email, user_type, token, refresh_token): try: - return Response({'action': "Login", 'message': "Verified", "user_type": user_type}, + return Response({'action': "Login", 'message': "Verified", "user_type": user_type, "id_token": token, "refresh_token": refresh_token}, status=status.HTTP_200_OK) except: return Response({'action': "Login", 'message': "Something Went Wrong"}, status=status.HTTP_400_BAD_REQUEST) +@api_view(['POST']) +@precheck(required_data=[REFRESH_TOKEN]) +def refresh(request): + refresh_token = request.data[REFRESH_TOKEN] + data = { + 'refresh_token': refresh_token, + 'client_id': CLIENT_ID, + 'client_secret': CLIENT_SECRET, + 'redirect_uri': REDIRECT_URI, + 'grant_type': 'refresh_token' + } + response = rq.post(OAUTH2_API_ENDPOINT, data=data) + if response.status_code == 200: + id_info = id_token.verify_oauth2_token(response.json()['id_token'], requests.Request(), CLIENT_ID) + if id_info['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: + raise ValueError('Wrong issuer.') + user_types = User.objects.filter(email=id_info['email']).values_list('user_type', flat=True) + return Response({'action': "Refresh Token", 'message': "Token Refreshed", "id_token": response.json()['id_token'], "user_type": user_types[0]}, + status=status.HTTP_200_OK) + else: + logger.error("refresh_token"+str(response)) + return Response({'action': "Refresh Token", 'message': "Something Went Wrong"}, + status=status.HTTP_400_BAD_REQUEST) + + @api_view(['GET']) @isAuthorized(allowed_users=[STUDENT]) diff --git a/CDC_Backend/APIs/urls.py b/CDC_Backend/APIs/urls.py index 36f929e..af80640 100644 --- a/CDC_Backend/APIs/urls.py +++ b/CDC_Backend/APIs/urls.py @@ -4,6 +4,7 @@ from . import studentViews, studentUrls, companyUrls, adminUrls urlpatterns = [ path('login/', studentViews.login, name="Login"), + path('refresh_token/', studentViews.refresh, name="Refresh Token"), path('student/', include(studentUrls)), path('company/', include(companyUrls)), path('admin/', include(adminUrls)), diff --git a/CDC_Backend/APIs/utils.py b/CDC_Backend/APIs/utils.py index 3d64768..63f2729 100644 --- a/CDC_Backend/APIs/utils.py +++ b/CDC_Backend/APIs/utils.py @@ -33,6 +33,38 @@ from .models import User, PrePlacementOffer, PlacementApplication, Placement, St logger = logging.getLogger('db') +def get_token(): + def decorator(view_func): + def wrapper_func(request, *args, **kwargs): + try: + authcode = request.data[AUTH_CODE] + data = { + 'code': authcode, + 'client_id': CLIENT_ID, + 'client_secret': CLIENT_SECRET, + 'redirect_uri': REDIRECT_URI, + 'grant_type': 'authorization_code' + } + r = rq.post(OAUTH2_API_ENDPOINT, data=data) + if r.status_code == 200: + response = r.json() + token = response[ID_TOKEN] + refresh_token = response[REFRESH_TOKEN] + request.META["HTTP_AUTHORIZATION"] = "Bearer " + token + request.META["MODIFIED"] = "True" + kwargs['refresh_token'] = refresh_token + return view_func(request, *args, **kwargs) + else: + return Response({'action': "Get Token", 'message': "Invalid Auth Code"}, + status=status.HTTP_400_BAD_REQUEST) + except Exception as e: + logger.warning("Get Token: " + str(sys.exc_info())) + return Response({'action': "Get Token", 'message': str(e)}, + status=status.HTTP_400_BAD_REQUEST) + return wrapper_func + return decorator + + def precheck(required_data=None): if required_data is None: required_data = [] @@ -84,7 +116,10 @@ def isAuthorized(allowed_users=None): user.last_login_time = timezone.now() user.save() if len(set(user.user_type).intersection(set(allowed_users))) or allowed_users == '*': - return view_func(request, user.id, user.email, user.user_type, *args, **kwargs) + if "MODIFIED" in headers: + return view_func(request, user.id, user.email, user.user_type, token_id, *args, **kwargs) + else: + return view_func(request, user.id, user.email, user.user_type, *args, **kwargs) else: raise PermissionError("Access Denied. You are not allowed to use this service") else: