Describe the bug
The create_certificate API endpoint is vulnerable to a race condition that allows duplicate certificates to be created for the same user and course. When a user clicks the "Get Certificate" button multiple times in quick succession, multiple parallel requests pass both the is_certified() check and the validate_duplicate_certificate() validation before any of them commit to the database, resulting in duplicate LMS Certificate records.
This inflates the certification count reported by get_chart_details and creates orphan certificate records.
To Reproduce
Steps to reproduce the behavior:
- Go to a course with enable_certification enabled
- Complete the course (progress = 100%)
- Click the "Get Certificate" button rapidly multiple times (3-5 clicks within 1-2 seconds)
- Check LMS Certificate list — multiple duplicate certificates are created for the same user and course
Expected behavior
Only one certificate should be created per user per course, regardless of how many times the button is clicked. Subsequent clicks should return the existing certificate (as is_certified() intends) rather than creating duplicates.
Desktop (please complete the following information):
- OS: Ubuntu 22.04
- Browser: Chrome 136
- Version: Frappe LMS v2.54.1
Describe the bug
The create_certificate API endpoint is vulnerable to a race condition that allows duplicate certificates to be created for the same user and course. When a user clicks the "Get Certificate" button multiple times in quick succession, multiple parallel requests pass both the is_certified() check and the validate_duplicate_certificate() validation before any of them commit to the database, resulting in duplicate LMS Certificate records.
This inflates the certification count reported by get_chart_details and creates orphan certificate records.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Only one certificate should be created per user per course, regardless of how many times the button is clicked. Subsequent clicks should return the existing certificate (as is_certified() intends) rather than creating duplicates.
Desktop (please complete the following information):