Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 36 additions & 10 deletions events/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,51 @@ def get_updated_form(transaction, form_type):

return form

def send_bulk_student_reset_mail(ac, batches, count, new_password, user):
# def send_bulk_student_reset_mail(ac, batches, count, new_password, user):
# batch_names = ", ".join([f"{x.id} - {x.batch_name}" for x in batches])
# subject = "Password Reset Notification"
# message = f"""
# Dear {user.first_name},

# Please find below the details of the recent student password update:
# Academic Center: {ac.institution_name}
# Batches: {batch_names}
# Total student count: {count}
# New password: {new_password}
# Changed by: {user.email}

# For security reasons, please inform students to change your password immediately after login.

# Regards,
# Admin Team
# """

# from_email = settings.ADMINISTRATOR_EMAIL
# recipient_list = [user.email, settings.DEVELOPER_EMAIL]
# send_mail(subject, message, from_email, recipient_list, fail_silently=False)

def send_bulk_student_reset_mail(school, batches, total_students, new_password, user):
batch_names = ", ".join([f"{x.id} - {x.batch_name}" for x in batches])

subject = "Password Reset Notification"
message = f"""
Dear {user.first_name},

Please find below the details of the recent student password update:
Academic Center: {ac.institution_name}
Please find below the details of the recent student password update:
Academic Center: {school.institution_name}
Batches: {batch_names}
Total student count: {count}
Total student count: {total_students}
New password: {new_password}
Changed by: {user.email}
For security reasons, please inform students to change your password immediately after login.

For security reasons, please inform students to change their password immediately after login.

Regards,
Admin Team
"""
"""

from_email = settings.DEFAULT_FROM_EMAIL
recipient_list = [user.email] + settings.DEVELOPER_EMAIL

send_mail(subject, message, from_email, recipient_list, fail_silently=False)

from_email = settings.ADMINISTRATOR_EMAIL
recipient_list = [user.email, settings.DEVELOPER_EMAIL]
send_mail(subject, message, from_email, recipient_list, fail_silently=False)
109 changes: 74 additions & 35 deletions events/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3262,43 +3262,82 @@ def handover(request):

return render(request, 'handover.html', context)


def reset_student_pwd(request):
context = {}
template = 'events/templates/reset_student_password.html'
form = StudentPasswordResetForm()
context['form'] = form

if request.method == "POST":
form = StudentPasswordResetForm(request.POST)
context['form'] = form

if form.is_valid():
school = form.cleaned_data['school']
batches = form.cleaned_data['batches']
new_password = form.cleaned_data['new_password']

batch_ids = [x.id for x in batches]
batches = StudentBatch.objects.filter(id__in=batch_ids)
student_ids = StudentMaster.objects.filter(batch__in=batches).values_list('student_id', flat=True)
students = Student.objects.filter(id__in=student_ids)
students.update(verified=1, error=0)
user_ids = [stu.user_id for stu in students]
users = User.objects.filter(id__in=user_ids)
new_hashed_pwd = make_password(new_password)
users.update(password=new_hashed_pwd, is_active=1)
emails = [user.email for user in users]
mdlUsers = MdlUser.objects.filter(email__in=emails)
mdlUsers.update(password=encript_password(new_password))
send_bulk_student_reset_mail(school,batches,users.count(), new_password,request.user)

# Add the success message
success_msg = "Password updated for {} students.".format(users.count())
messages.success(request, success_msg)


redirect_url = reverse('events:reset_student_pwd')
return HttpResponseRedirect(redirect_url)
return render(request,template,context)
# 1. ROLE VALIDATION -------------------------------
if not request.user.groups.filter(name="School Training Manager").exists():
return HttpResponseForbidden("You are not allowed to access this page.")


template = 'events/templates/reset_student_password.html'
form = StudentPasswordResetForm(request.POST or None)

if request.method == "POST" and form.is_valid():

school = form.cleaned_data['school']
batches = form.cleaned_data['batches']
new_password = form.cleaned_data['new_password']

# 2. SECURITY FIX — ensure all batches belong to the selected school
for b in batches:
if b.academic_id != school.id:
return HttpResponseForbidden("Invalid batch selected.")

batch_ids = batches.values_list("id", flat=True)

# 3. Get student IDs efficiently
student_ids = StudentMaster.objects.filter(
batch_id__in=batch_ids
).values_list('student_id', flat=True)

# 4. Update Student table in bulk
Student.objects.filter(id__in=student_ids).update(
verified=1,
error=0
)

# 5. Get User IDs linked to these students
user_ids = Student.objects.filter(
id__in=student_ids
).values_list("user_id", flat=True)

# 6. Update Django User passwords in bulk
hashed_pwd = make_password(new_password)
User.objects.filter(id__in=user_ids).update(
password=hashed_pwd,
is_active=1
)

# 7. Fetch emails efficiently
emails = User.objects.filter(
id__in=user_ids
).values_list("email", flat=True)

# 8. Update Moodle users password
MdlUser.objects.filter(email__in=emails).update(
password=encript_password(new_password)
)

# 9. Send email once (not inside loop)
send_bulk_student_reset_mail(
school=school,
batches=batches,
total_students=len(student_ids),
new_password=new_password,
user=request.user
)

messages.success(
request,
f"Password updated for {len(student_ids)} students."
)

return redirect("events:reset_student_pwd")

return render(request, template, {"form": form})




def get_schools(request):
Expand Down