From 8cdea459bc0e9b10ebcded90310dd3701acaf345 Mon Sep 17 00:00:00 2001 From: ayishanishana21 Date: Thu, 18 Dec 2025 13:03:38 +0530 Subject: [PATCH 1/2] resolved reset password error --- events/helpers.py | 46 +++++++++++++++++++++------ events/views.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 10 deletions(-) diff --git a/events/helpers.py b/events/helpers.py index 4201c18ba..6c926f9cf 100644 --- a/events/helpers.py +++ b/events/helpers.py @@ -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) \ No newline at end of file diff --git a/events/views.py b/events/views.py index 98561d668..91abed641 100644 --- a/events/views.py +++ b/events/views.py @@ -3299,6 +3299,87 @@ def reset_student_pwd(request): redirect_url = reverse('events:reset_student_pwd') return HttpResponseRedirect(redirect_url) return render(request,template,context) +# redirect_url = reverse('events:reset_student_pwd') +# return HttpResponseRedirect(redirect_url) +# return render(request,template,context) + + + +def reset_student_pwd(request): + + # 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): From 85f2a61c5a0515b9327f8d770c4a11b506b4fd6e Mon Sep 17 00:00:00 2001 From: ayishanishana21 Date: Thu, 18 Dec 2025 13:18:02 +0530 Subject: [PATCH 2/2] resolved pasword reset error --- events/views.py | 44 +------------------------------------------- 1 file changed, 1 insertion(+), 43 deletions(-) diff --git a/events/views.py b/events/views.py index 91abed641..e776b3a2d 100644 --- a/events/views.py +++ b/events/views.py @@ -3262,49 +3262,7 @@ 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) -# redirect_url = reverse('events:reset_student_pwd') -# return HttpResponseRedirect(redirect_url) -# return render(request,template,context) - - - + def reset_student_pwd(request): # 1. ROLE VALIDATION -------------------------------