Commit f0f37664 by Matt Drayer

mattdrayer/ECOM-1773: Fixed invalid URL reversal

parent d9cdb5d6
...@@ -59,7 +59,8 @@ class CertificateDisplayTest(ModuleStoreTestCase): ...@@ -59,7 +59,8 @@ class CertificateDisplayTest(ModuleStoreTestCase):
def test_linked_student_to_web_view_credential(self, enrollment_mode): def test_linked_student_to_web_view_credential(self, enrollment_mode):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=unicode(self.course.id) course_id=unicode(self.course.id),
verify_uuid='abcdefg12345678'
) )
self._create_certificate(enrollment_mode) self._create_certificate(enrollment_mode)
......
...@@ -307,11 +307,14 @@ def _cert_info(user, course, cert_status, course_mode): ...@@ -307,11 +307,14 @@ def _cert_info(user, course, cert_status, course_mode):
# showing the certificate web view button if certificate is ready state and feature flags are enabled. # showing the certificate web view button if certificate is ready state and feature flags are enabled.
if settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False): if settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False):
if get_active_web_certificate(course) is not None: if get_active_web_certificate(course) is not None:
certificate_url = get_certificate_url(
user_id=user.id,
course_id=unicode(course.id),
verify_uuid=None
)
status_dict.update({ status_dict.update({
'show_cert_web_view': True, 'show_cert_web_view': True,
'cert_web_view_url': u'{url}'.format( 'cert_web_view_url': u'{url}'.format(url=certificate_url)
url=get_certificate_url(user_id=user.id, course_id=unicode(course.id))
)
}) })
else: else:
# don't show download certificate button if we don't have an active certificate for course # don't show download certificate button if we don't have an active certificate for course
......
...@@ -253,15 +253,18 @@ def example_certificates_status(course_key): ...@@ -253,15 +253,18 @@ def example_certificates_status(course_key):
# pylint: disable=no-member # pylint: disable=no-member
def get_certificate_url(user_id, course_id): def get_certificate_url(user_id, course_id, verify_uuid):
""" """
:return certificate url :return certificate url
""" """
url = u'{url}'.format(url=reverse('cert_html_view', if settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False):
kwargs=dict( return u'{url}'.format(
user_id=str(user_id), url=reverse(
course_id=unicode(course_id)))) 'cert_html_view',
return url kwargs=dict(user_id=str(user_id), course_id=unicode(course_id))
)
)
return '{url}{uuid}'.format(url=settings.CERTIFICATES_STATIC_VERIFY_URL, uuid=verify_uuid)
def get_active_web_certificate(course, is_preview_mode=None): def get_active_web_certificate(course, is_preview_mode=None):
...@@ -290,7 +293,7 @@ def emit_certificate_event(event_name, user, course_id, course=None, event_data= ...@@ -290,7 +293,7 @@ def emit_certificate_event(event_name, user, course_id, course=None, event_data=
data = { data = {
'user_id': user.id, 'user_id': user.id,
'course_id': unicode(course_id), 'course_id': unicode(course_id),
'certificate_url': get_certificate_url(user.id, course_id) 'certificate_url': get_certificate_url(user.id, course_id, event_data['certificate_id'])
} }
event_data = event_data or {} event_data = event_data or {}
event_data.update(data) event_data.update(data)
......
...@@ -148,7 +148,7 @@ class GenerateUserCertificatesTest(EventTestMixin, ModuleStoreTestCase): ...@@ -148,7 +148,7 @@ class GenerateUserCertificatesTest(EventTestMixin, ModuleStoreTestCase):
'edx.certificate.created', 'edx.certificate.created',
user_id=self.student.id, user_id=self.student.id,
course_id=unicode(self.course.id), course_id=unicode(self.course.id),
certificate_url=certs_api.get_certificate_url(self.student.id, self.course.id), certificate_url=certs_api.get_certificate_url(self.student.id, self.course.id, cert.verify_uuid),
certificate_id=cert.verify_uuid, certificate_id=cert.verify_uuid,
enrollment_mode=cert.mode, enrollment_mode=cert.mode,
generation_mode='batch' generation_mode='batch'
...@@ -164,7 +164,7 @@ class GenerateUserCertificatesTest(EventTestMixin, ModuleStoreTestCase): ...@@ -164,7 +164,7 @@ class GenerateUserCertificatesTest(EventTestMixin, ModuleStoreTestCase):
self.assertEqual(cert.status, 'error') self.assertEqual(cert.status, 'error')
self.assertIn(self.ERROR_REASON, cert.error_reason) self.assertIn(self.ERROR_REASON, cert.error_reason)
@override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) @patch.dict(settings.FEATURES, {'CERTIFICATES_HTML_VIEW': True})
def test_new_cert_requests_returns_generating_for_html_certificate(self): def test_new_cert_requests_returns_generating_for_html_certificate(self):
""" """
Test no message sent to Xqueue if HTML certificate view is enabled Test no message sent to Xqueue if HTML certificate view is enabled
......
...@@ -308,7 +308,8 @@ class MicrositeCertificatesViewsTests(ModuleStoreTestCase): ...@@ -308,7 +308,8 @@ class MicrositeCertificatesViewsTests(ModuleStoreTestCase):
self.assertEquals(config.configuration, test_configuration_string) self.assertEquals(config.configuration, test_configuration_string)
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
self._add_course_certificates(count=1, signatory_count=2) self._add_course_certificates(count=1, signatory_count=2)
response = self.client.get(test_url) response = self.client.get(test_url)
...@@ -341,7 +342,8 @@ class MicrositeCertificatesViewsTests(ModuleStoreTestCase): ...@@ -341,7 +342,8 @@ class MicrositeCertificatesViewsTests(ModuleStoreTestCase):
self.assertEquals(config.configuration, test_configuration_string) self.assertEquals(config.configuration, test_configuration_string)
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
self._add_course_certificates(count=1, signatory_count=2) self._add_course_certificates(count=1, signatory_count=2)
response = self.client.get(test_url) response = self.client.get(test_url)
...@@ -427,7 +429,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -427,7 +429,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
def test_render_html_view_valid_certificate(self): def test_render_html_view_valid_certificate(self):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=unicode(self.course.id) # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
self._add_course_certificates(count=1, signatory_count=2) self._add_course_certificates(count=1, signatory_count=2)
response = self.client.get(test_url) response = self.client.get(test_url)
...@@ -449,7 +452,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -449,7 +452,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
def test_render_html_view_with_valid_signatories(self): def test_render_html_view_with_valid_signatories(self):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
self._add_course_certificates(count=1, signatory_count=2) self._add_course_certificates(count=1, signatory_count=2)
response = self.client.get(test_url) response = self.client.get(test_url)
...@@ -465,7 +469,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -465,7 +469,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
# if certificate in descriptor has not course_title then course name should not be overridden with this title. # if certificate in descriptor has not course_title then course name should not be overridden with this title.
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
test_certificates = [ test_certificates = [
{ {
...@@ -488,7 +493,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -488,7 +493,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
def test_certificate_view_without_org_logo(self): def test_certificate_view_without_org_logo(self):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
test_certificates = [ test_certificates = [
{ {
...@@ -510,7 +516,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -510,7 +516,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
def test_render_html_view_without_signatories(self): def test_render_html_view_without_signatories(self):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course),
verify_uuid=self.cert.verify_uuid
) )
self._add_course_certificates(count=1, signatory_count=0) self._add_course_certificates(count=1, signatory_count=0)
response = self.client.get(test_url) response = self.client.get(test_url)
...@@ -518,19 +525,20 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -518,19 +525,20 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
self.assertNotIn('Signatory_Title 0', response.content) self.assertNotIn('Signatory_Title 0', response.content)
@override_settings(FEATURES=FEATURES_WITH_CERTS_DISABLED) @override_settings(FEATURES=FEATURES_WITH_CERTS_DISABLED)
def test_render_html_view_invalid_feature_flag(self): def test_render_html_view_disabled_feature_flag_returns_static_url(self):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
response = self.client.get(test_url) self.assertIn(str(self.cert.verify_uuid), test_url)
self.assertIn('invalid', response.content)
@override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED)
def test_render_html_view_invalid_course_id(self): def test_render_html_view_invalid_course_id(self):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id='az/23423/4vs' course_id='az/23423/4vs',
verify_uuid=self.cert.verify_uuid
) )
response = self.client.get(test_url) response = self.client.get(test_url)
...@@ -540,7 +548,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -540,7 +548,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
def test_render_html_view_invalid_course(self): def test_render_html_view_invalid_course(self):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id='missing/course/key' course_id='missing/course/key',
verify_uuid=self.cert.verify_uuid
) )
response = self.client.get(test_url) response = self.client.get(test_url)
self.assertIn('invalid', response.content) self.assertIn('invalid', response.content)
...@@ -549,7 +558,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -549,7 +558,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
def test_render_html_view_invalid_user(self): def test_render_html_view_invalid_user(self):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=111, user_id=111,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
response = self.client.get(test_url) response = self.client.get(test_url)
self.assertIn('invalid', response.content) self.assertIn('invalid', response.content)
...@@ -560,7 +570,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -560,7 +570,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
self.assertEqual(len(GeneratedCertificate.objects.all()), 0) self.assertEqual(len(GeneratedCertificate.objects.all()), 0)
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
response = self.client.get(test_url) response = self.client.get(test_url)
self.assertIn('invalid', response.content) self.assertIn('invalid', response.content)
...@@ -576,7 +587,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -576,7 +587,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
self._add_course_certificates(count=1, signatory_count=2) self._add_course_certificates(count=1, signatory_count=2)
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=self.course.id.to_deprecated_string() # pylint: disable=no-member course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
response = self.client.get(test_url + '?preview=honor') response = self.client.get(test_url + '?preview=honor')
self.assertNotIn(self.course.display_name, response.content) self.assertNotIn(self.course.display_name, response.content)
...@@ -594,7 +606,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -594,7 +606,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
def test_render_html_view_invalid_certificate_configuration(self): def test_render_html_view_invalid_certificate_configuration(self):
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=unicode(self.course.id) course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
response = self.client.get(test_url) response = self.client.get(test_url)
self.assertIn("Invalid Certificate", response.content) self.assertIn("Invalid Certificate", response.content)
...@@ -606,7 +619,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -606,7 +619,8 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
self.recreate_tracker() self.recreate_tracker()
test_url = get_certificate_url( test_url = get_certificate_url(
user_id=self.user.id, user_id=self.user.id,
course_id=unicode(self.course.id) course_id=unicode(self.course.id),
verify_uuid=self.cert.verify_uuid
) )
response = self.client.get(test_url) response = self.client.get(test_url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
...@@ -626,7 +640,12 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase): ...@@ -626,7 +640,12 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
@override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED) @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED)
def test_evidence_event_sent(self): def test_evidence_event_sent(self):
test_url = get_certificate_url(user_id=self.user.id, course_id=self.course_id) + '?evidence_visit=1' cert_url = get_certificate_url(
user_id=self.user.id,
course_id=self.course_id,
verify_uuid=self.cert.verify_uuid
)
test_url = '{}?evidence_visit=1'.format(cert_url)
self.recreate_tracker() self.recreate_tracker()
assertion = BadgeAssertion( assertion = BadgeAssertion(
user=self.user, course_id=self.course_id, mode='honor', user=self.user, course_id=self.course_id, mode='honor',
......
...@@ -439,7 +439,8 @@ def _update_certificate_context(context, course, user, user_certificate): ...@@ -439,7 +439,8 @@ def _update_certificate_context(context, course, user, user_certificate):
user_certificate.mode, user_certificate.mode,
get_certificate_url( get_certificate_url(
user_id=user.id, user_id=user.id,
course_id=course.id.to_deprecated_string() course_id=unicode(course.id),
verify_uuid=user_certificate.verify_uuid
) )
) )
......
...@@ -824,7 +824,7 @@ class ProgressPageTests(ModuleStoreTestCase): ...@@ -824,7 +824,7 @@ class ProgressPageTests(ModuleStoreTestCase):
If certificate web view is enabled then certificate web view button should appear for user who certificate is If certificate web view is enabled then certificate web view button should appear for user who certificate is
available/generated available/generated
""" """
GeneratedCertificateFactory.create( certificate = GeneratedCertificateFactory.create(
user=self.user, user=self.user,
course_id=self.course.id, course_id=self.course.id,
status=CertificateStatuses.downloadable, status=CertificateStatuses.downloadable,
...@@ -859,7 +859,12 @@ class ProgressPageTests(ModuleStoreTestCase): ...@@ -859,7 +859,12 @@ class ProgressPageTests(ModuleStoreTestCase):
resp = views.progress(self.request, course_id=unicode(self.course.id)) resp = views.progress(self.request, course_id=unicode(self.course.id))
self.assertContains(resp, u"View Certificate") self.assertContains(resp, u"View Certificate")
self.assertContains(resp, u"You can now view your certificate") self.assertContains(resp, u"You can now view your certificate")
self.assertContains(resp, certs_api.get_certificate_url(user_id=self.user.id, course_id=self.course.id)) cert_url = certs_api.get_certificate_url(
user_id=self.user.id,
course_id=self.course.id,
verify_uuid=certificate.verify_uuid
)
self.assertContains(resp, cert_url)
# when course certificate is not active # when course certificate is not active
certificates[0]['is_active'] = False certificates[0]['is_active'] = False
......
...@@ -1100,7 +1100,11 @@ def _progress(request, course_key, student_id): ...@@ -1100,7 +1100,11 @@ def _progress(request, course_key, student_id):
context.update({ context.update({
'show_cert_web_view': True, 'show_cert_web_view': True,
'cert_web_view_url': u'{url}'.format( 'cert_web_view_url': u'{url}'.format(
url=certs_api.get_certificate_url(user_id=student.id, course_id=unicode(course.id)) url=certs_api.get_certificate_url(
user_id=student.id,
course_id=unicode(course.id),
verify_uuid=None
)
) )
}) })
else: else:
......
...@@ -640,3 +640,7 @@ EDXNOTES_INTERNAL_API = ENV_TOKENS.get('EDXNOTES_INTERNAL_API', EDXNOTES_INTERNA ...@@ -640,3 +640,7 @@ EDXNOTES_INTERNAL_API = ENV_TOKENS.get('EDXNOTES_INTERNAL_API', EDXNOTES_INTERNA
##### Credit Provider Integration ##### ##### Credit Provider Integration #####
CREDIT_PROVIDER_SECRET_KEYS = AUTH_TOKENS.get("CREDIT_PROVIDER_SECRET_KEYS", {}) CREDIT_PROVIDER_SECRET_KEYS = AUTH_TOKENS.get("CREDIT_PROVIDER_SECRET_KEYS", {})
############ CERTIFICATE VERIFICATION URL (STATIC FILES) ###########
ENV_TOKENS.get('CERTIFICATES_STATIC_VERIFY_URL', CERTIFICATES_STATIC_VERIFY_URL)
...@@ -2067,6 +2067,9 @@ REGISTRATION_EXTRA_FIELDS = { ...@@ -2067,6 +2067,9 @@ REGISTRATION_EXTRA_FIELDS = {
CERT_NAME_SHORT = "Certificate" CERT_NAME_SHORT = "Certificate"
CERT_NAME_LONG = "Certificate of Achievement" CERT_NAME_LONG = "Certificate of Achievement"
############ CERTIFICATE VERIFICATION URL (STATIC FILES) ###########
CERTIFICATES_STATIC_VERIFY_URL = "https://verify-test.edx.org/cert/"
#################### Badgr OpenBadges generation ####################### #################### Badgr OpenBadges generation #######################
# Be sure to set up images for course modes using the BadgeImageConfiguration model in the certificates app. # Be sure to set up images for course modes using the BadgeImageConfiguration model in the certificates app.
BADGR_API_TOKEN = None BADGR_API_TOKEN = None
......
...@@ -472,9 +472,6 @@ FACEBOOK_APP_SECRET = "Test" ...@@ -472,9 +472,6 @@ FACEBOOK_APP_SECRET = "Test"
FACEBOOK_APP_ID = "Test" FACEBOOK_APP_ID = "Test"
FACEBOOK_API_VERSION = "v2.2" FACEBOOK_API_VERSION = "v2.2"
# Certificates Views
FEATURES['CERTIFICATES_HTML_VIEW'] = True
######### custom courses ######### ######### custom courses #########
INSTALLED_APPS += ('ccx',) INSTALLED_APPS += ('ccx',)
FEATURES['CUSTOM_COURSES_EDX'] = True FEATURES['CUSTOM_COURSES_EDX'] = True
......
...@@ -663,11 +663,10 @@ if settings.FEATURES.get('ENABLE_OAUTH2_PROVIDER'): ...@@ -663,11 +663,10 @@ if settings.FEATURES.get('ENABLE_OAUTH2_PROVIDER'):
) )
# Certificates Web/HTML View # Certificates Web/HTML View
if settings.FEATURES.get('CERTIFICATES_HTML_VIEW', False): urlpatterns += (
urlpatterns += ( url(r'^certificates/user/(?P<user_id>[^/]*)/course/{course_id}'.format(course_id=settings.COURSE_ID_PATTERN),
url(r'^certificates/user/(?P<user_id>[^/]*)/course/{course_id}'.format(course_id=settings.COURSE_ID_PATTERN), 'certificates.views.render_html_view', name='cert_html_view'),
'certificates.views.render_html_view', name='cert_html_view'), )
)
BADGE_SHARE_TRACKER_URL = url( BADGE_SHARE_TRACKER_URL = url(
r'^certificates/badge_share_tracker/{}/(?P<network>[^/]+)/(?P<student_username>[^/]+)/$'.format( r'^certificates/badge_share_tracker/{}/(?P<network>[^/]+)/(?P<student_username>[^/]+)/$'.format(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment