diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py index 7eff05d63d..830579ccef 100644 --- a/lms/djangoapps/certificates/tests/test_webview_views.py +++ b/lms/djangoapps/certificates/tests/test_webview_views.py @@ -694,6 +694,16 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): response = self.client.get(test_url) self.assertIn('invalid', response.content) + @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) + def test_render_html_view_non_int_user(self): + self._add_course_certificates(count=1, signatory_count=0) + test_url = get_certificate_url( + user_id="Good tests make good neighbors", + course_id=unicode(self.course.id) + ) + response = self.client.get(test_url) + self.assertEqual(response.status_code, 404) + @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) def test_render_html_view_invalid_user_certificate(self): self._add_course_certificates(count=1, signatory_count=0) diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py index bd3a656548..381c2fa7ad 100644 --- a/lms/djangoapps/certificates/views/webview.py +++ b/lms/djangoapps/certificates/views/webview.py @@ -496,6 +496,11 @@ def render_html_view(request, user_id, course_id): This public view generates an HTML representation of the specified user and course If a certificate is not available, we display a "Sorry!" screen instead """ + try: + user_id = int(user_id) + except ValueError: + raise Http404 + preview_mode = request.GET.get('preview', None) platform_name = microsite.get_value("platform_name", settings.PLATFORM_NAME) configuration = CertificateHtmlViewConfiguration.get_config() @@ -506,6 +511,11 @@ def render_html_view(request, user_id, course_id): # Kick the user back to the "Invalid" screen if the feature is disabled if not has_html_certificates_enabled(course_id): + log.info( + "Invalid cert: HTML certificates disabled for %s. User id: %d", + course_id, + user_id, + ) return render_to_response(invalid_template_path, context) # Load the course and user objects @@ -515,12 +525,22 @@ def render_html_view(request, user_id, course_id): course = modulestore().get_course(course_key) # For any other expected exceptions, kick the user back to the "Invalid" screen - except (InvalidKeyError, ItemNotFoundError, User.DoesNotExist): + except (InvalidKeyError, ItemNotFoundError, User.DoesNotExist) as exception: + error_str = ( + "Invalid cert: error finding course %s or user with id " + "%d. Specific error: %s" + ) + log.info(error_str, course_id, user_id, str(exception)) return render_to_response(invalid_template_path, context) # Load user's certificate user_certificate = _get_user_certificate(request, user, course_key, course, preview_mode) if not user_certificate: + log.info( + "Invalid cert: User %d does not have eligible cert for %s.", + user_id, + course_id, + ) return render_to_response(invalid_template_path, context) # Get the active certificate configuration for this course @@ -528,7 +548,13 @@ def render_html_view(request, user_id, course_id): # Passing in the 'preview' parameter, if specified, will return a configuration, if defined active_configuration = get_active_web_certificate(course, preview_mode) if active_configuration is None: + log.info( + "Invalid cert: course %s does not have an active configuration. User id: %d", + course_id, + user_id, + ) return render_to_response(invalid_template_path, context) + context['certificate_data'] = active_configuration # Append/Override the existing view context values with any mode-specific ConfigurationModel values