Added Verify Email Functionality

This commit is contained in:
Gowtham Sai 2021-12-17 17:15:56 +05:30
parent cb52e1a475
commit 4dbd4a65c8
11 changed files with 89 additions and 21 deletions

View File

@ -16,7 +16,7 @@ def markStatus(request, id, email, user_type):
# Getting all application from db for this opening
applications = PlacementApplication.objects.filter(placement_id=data[OPENING_ID])
for i in data[STUDENT_LIST]:
application = applications.filter(student_id=i[STUDENT_ID]) # Filtering student's application
application = applications.filter(student__roll_no=i[STUDENT_ID]) # Filtering student's application
if len(application) > 0:
application = application[0]
application.selected = True if i[STUDENT_SELECTED] == "true" else False

View File

@ -4,4 +4,5 @@ from . import companyViews
urlpatterns = [
path('addPlacement/', companyViews.addPlacement, name="Add Placement"),
path('verifyEmail/', companyViews.verifyEmail, name="Verify Email"),
]

View File

@ -1,5 +1,5 @@
import json
from datetime import datetime
import datetime
from rest_framework.decorators import api_view
@ -178,7 +178,7 @@ def addPlacement(request):
else:
raise ValueError('Invalid compensation gross')
# Convert to date object
opening.tentative_date_of_joining = datetime.strptime(data[TENTATIVE_DATE_OF_JOINING], '%d-%m-%Y').date()
opening.tentative_date_of_joining = datetime.datetime.strptime(data[TENTATIVE_DATE_OF_JOINING], '%d-%m-%Y').date()
# Only Allowing Fourth Year for Placement
opening.allowed_batch = [FOURTH_YEAR, ]
@ -202,15 +202,18 @@ def addPlacement(request):
opening.save()
stat, link = generateOneTimeVerificationLink(opening.email, opening.id, "Placement")
if not stat:
raise RuntimeError("Error in generating one time verification link for placement")
data = {
"designation": opening.designation,
"opening_type": PLACEMENT,
"opening_link": PLACEMENT_OPENING_URL.format(id=opening.id), # Some Changes here too
"company_name": opening.company_name
"one_time_link": link
}
sendEmail(opening.email, COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT.format(id=opening.id), data,
COMPANY_OPENING_SUBMITTED_TEMPLATE)
sendEmail(opening.email, COMPANY_EMAIl_VERIFICATION_TEMPLATE_SUBJECT, data,
COMPANY_EMAIL_VERIFICATION_TEMPLATE)
return Response({'action': "Add Placement", 'message': "Placement Added Successfully"},
status=status.HTTP_200_OK)
@ -222,3 +225,45 @@ def addPlacement(request):
logger.warning("Add New Placement: " + str(sys.exc_info()))
return Response({'action': "Add Placement", 'message': "Something went wrong"},
status=status.HTTP_400_BAD_REQUEST)
@api_view(['POST'])
@precheck([TOKEN])
def verifyEmail(request):
try:
data = request.data
token = data[TOKEN]
# decode token
decoded_token = jwt.decode(token, os.environ.get("EMAIL_VERIFICATION_SECRET_KEY"), algorithms=['HS256'])
# get email, opening_id, opening_type from token
email = decoded_token['email']
opening_id = decoded_token['opening_id']
opening_type = decoded_token['opening_type']
# get opening based on opening_type and opening_id
if opening_type == PLACEMENT:
opening = get_object_or_404(Placement, id=opening_id)
if email != opening.email:
raise ValueError("Invalid Email")
opening.email_verified = True
opening.save()
data = {
"designation": opening.designation,
"opening_type": PLACEMENT,
"opening_link": PLACEMENT_OPENING_URL.format(id=opening.id), # Some Changes here too
"company_name": opening.company_name
}
sendEmail(opening.email, COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT.format(id=opening.id), data,
COMPANY_OPENING_SUBMITTED_TEMPLATE)
else:
raise ValueError('Invalid opening type')
return Response({'action': "Verify Email", 'message': "Email Verified Successfully"},
status=status.HTTP_200_OK)
except Http404:
return Response({'action': "Verify Email", 'message': "Opening Not Found"},
status=status.HTTP_404_NOT_FOUND)
except ValueError as e:
return Response({'action': "Verify Email", 'message': str(e)},
status=status.HTTP_400_BAD_REQUEST)
except:
logger.warning("Verify Email: " + str(sys.exc_info()))
return Response({'action': "Verify Email", 'message': "Something went wrong"},
status=status.HTTP_400_BAD_REQUEST)

View File

@ -39,13 +39,12 @@ TOTAL_BATCHES = 4 # Total No of Batches
CLIENT_ID = "956830229554-290mirc16pdhd5j7ph7v7ukibo4t1qcp.apps.googleusercontent.com" # Google Login Client ID
# To be Configured Properly
PLACEMENT_OPENING_URL = "https://www.googleapis.com/auth/adwords/{id}"
PLACEMENT_OPENING_URL = "https://www.googleapis.com/auth/adwords/{id}" # On frontend, this is the URL to be opened
LINK_TO_STORAGE_COMPANY_ATTACHMENT = "https://storage.googleapis.com/cdc-backend-attachments/company_attachments/"
LINK_TO_STORAGE_RESUME = "https://storage.googleapis.com/cdc-backend-attachments/resume/"
LINK_TO_APPLICATIONS_CSV = "https://storage.googleapis.com/cdc-backend-attachments/applications-csv/"
LINK_TO_EMAIl_VERIFICATION_API = "https://api.sendgrid.com/v3/mail/send?token={token}"
TOKEN = "token_id"
EMAIL = "email"
STUDENT = 'student'
@ -55,13 +54,14 @@ COMPANY = ''
# To be Configured Properly
FOURTH_YEAR = '2018'
MAX_OFFERS_PER_STUDENT = 2
EMAIL_VERIFICATION_TOKEN_TTL = 48 # in hours
STORAGE_DESTINATION_RESUMES = "./Storage/Resumes/"
STORAGE_DESTINATION_COMPANY_ATTACHMENTS = './Storage/Company_Attachments/'
STORAGE_DESTINATION_APPLICATION_CSV = './Storage/Application_CSV/'
TOKEN = 'token'
RESUME_FILE_NAME = 'resume_file_name'
APPLICATION_ID = "application_id"
@ -123,14 +123,16 @@ STUDENT_ID = "student_id"
STUDENT_SELECTED = "student_selected"
COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT = "Notification Submitted - {id} - CDC IIT Dharwad"
COMPANY_OPENING_SUBMITTED_TEMPLATE_SUBJECT = "Notification Submitted - {id} - Career Development Cell, IIT Dharwad"
STUDENT_APPLICATION_STATUS_TEMPLATE_SUBJECT = 'Application Status : {company_name} - {id}'
STUDENT_APPLICATION_SUBMITTED_TEMPLATE_SUBJECT = 'CDC - Application Submitted - {company_name}'
COMPANY_EMAIl_VERIFICATION_TEMPLATE_SUBJECT = 'Email Verification - Career Development Cell, IIT Dharwad'
STUDENT_APPLICATION_SUBMITTED_TEMPLATE = 'student_application_submitted.html'
COMPANY_OPENING_SUBMITTED_TEMPLATE = 'company_opening_submitted.html'
STUDENT_APPLICATION_STATUS_SELECTED_TEMPLATE = 'student_application_status_selected.html'
STUDENT_APPLICATION_STATUS_NOT_SELECTED_TEMPLATE = 'student_application_status_not_selected.html'
COMPANY_EMAIL_VERIFICATION_TEMPLATE = 'company_email_verification.html'
APPLICATION_CSV_COL_NAMES = ['Applied At', 'Roll No.', 'Name', 'Email', 'Phone Number', 'Branch', 'Batch', 'CPI',
'Resume', 'Selected', ]

View File

@ -1,9 +1,11 @@
import datetime
import logging
import os
import random
import re
import string
import sys
import jwt
from os import path, remove
import background_task
@ -214,3 +216,20 @@ def getTier(compensation_gross, is_psu=False):
print(sys.exc_info())
logger.warning("Utils - getTier: " + str(sys.exc_info()))
return False, "_"
def generateOneTimeVerificationLink(email, opening_id, opening_type):
try:
token_payload = {
"email": email,
"opening_id": opening_id,
"opening_type": opening_type,
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=EMAIL_VERIFICATION_TOKEN_TTL)
}
token = jwt.encode(token_payload, os.environ.get("EMAIL_VERIFICATION_SECRET_KEY"), algorithm="HS256")
link = LINK_TO_EMAIl_VERIFICATION_API.format(token=token)
return True, link
except:
print(sys.exc_info())
logger.warning("Utils - generateOneTimeVerificationLink: " + str(sys.exc_info()))
return False, "_"

View File

@ -32,7 +32,7 @@
style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;">
<tr>
<td align="center" style="padding:40px 0 30px 0;background:#334878;">
<img src="./image.png" alt="" width="200" style="height:auto;display:block;"/>
<img src="https://drive.google.com/uc?id=1QTA6dB7jnsZfU1kzyUqfD_2V5xODpWFt" alt="" width="200" style="height:auto;display:block;"/>
</td>
</tr>
<tr>
@ -41,9 +41,9 @@
style="width:100%;border-collapse:collapse;border:0;border-spacing:0;">
<tr>
<td style="padding:0 0 36px 0;color:#153643;">
<h1 style="font-size:24px;margin:0 0 20px 0;font-family: 'Roboto', sans-serif;">Hi,</h1>
<p style="margin:0 0 12px 0;font-size:16px;line-height:24px;font-family: 'Roboto', sans-serif;">
We have received your Job Notification for {{designation}}. Kindly verify your email by clicking <a href={{ one_time_link }}>here</a>.
We have received your Job Notification. Kindly verify your email by clicking <a href="{{ one_time_link }}">here</a>.
</p>
</td>
</tr>

View File

@ -32,7 +32,7 @@
style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;">
<tr>
<td align="center" style="padding:40px 0 30px 0;background:#334878;">
<img src="./image.png" alt="" width="200" style="height:auto;display:block;"/>
<img src="https://drive.google.com/uc?id=1QTA6dB7jnsZfU1kzyUqfD_2V5xODpWFt" alt="" width="200" style="height:auto;display:block;"/>
</td>
</tr>
<tr>

View File

@ -31,7 +31,7 @@
style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;">
<tr>
<td align="center" style="padding:40px 0 30px 0;background:#334878;">
<img src="./image.png" alt="" width="200" style="height:auto;display:block;"/>
<img src="https://drive.google.com/uc?id=1QTA6dB7jnsZfU1kzyUqfD_2V5xODpWFt" alt="" width="200" style="height:auto;display:block;"/>
</td>
</tr>
<tr>

View File

@ -31,7 +31,7 @@
style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;">
<tr>
<td align="center" style="padding:40px 0 30px 0;background:#334878;">
<img src="./image.png" alt="" width="200" style="height:auto;display:block;"/>
<img src="https://drive.google.com/uc?id=1QTA6dB7jnsZfU1kzyUqfD_2V5xODpWFt" alt="" width="200" style="height:auto;display:block;"/>
</td>
</tr>
<tr>

View File

@ -32,7 +32,7 @@
style="width:602px;border-collapse:collapse;border:1px solid #334878;border-spacing:0;text-align:left;">
<tr>
<td align="center" style="padding:40px 0 30px 0;background:#334878;">
<img src="./image.png" alt="" width="200" style="height:auto;display:block;"/>
<img src="https://drive.google.com/uc?id=1QTA6dB7jnsZfU1kzyUqfD_2V5xODpWFt" alt="" width="200" style="height:auto;display:block;"/>
</td>
</tr>
<tr>

View File

@ -28,6 +28,7 @@ pyasn1-modules==0.2.8
pylint==2.12.2
python-dotenv==0.19.2
pytz==2021.3
PyJWT==2.0.1
requests==2.26.0
rsa==4.8
six==1.16.0