From 041becc84691a8fb833fda3ab1b5136ee27d4691 Mon Sep 17 00:00:00 2001
From: Bianca Severino
Date: Thu, 9 Jul 2020 11:46:34 -0400
Subject: [PATCH] Implement waffle flag for IDV redirect
Created helper function to render url dynamically
Modify helper function to include reverify links
Fix code based on failing tests
Fixed query string in redirect URL
---
lms/djangoapps/courseware/date_summary.py | 7 +++-
.../send_verification_expiry_email.py | 3 +-
lms/djangoapps/verify_student/services.py | 38 ++++++++++++++++++-
lms/djangoapps/verify_student/toggles.py | 22 +++++++++++
lms/djangoapps/verify_student/views.py | 13 +++++--
.../dashboard/_dashboard_course_listing.html | 8 ++--
.../_dashboard_status_verification.html | 7 ++--
7 files changed, 85 insertions(+), 13 deletions(-)
diff --git a/lms/djangoapps/courseware/date_summary.py b/lms/djangoapps/courseware/date_summary.py
index 8cb8550398..c63a457c51 100644
--- a/lms/djangoapps/courseware/date_summary.py
+++ b/lms/djangoapps/courseware/date_summary.py
@@ -655,10 +655,13 @@ class VerificationDeadlineDate(DateSummary):
"""Maps verification state to a tuple of link text and location."""
return {
'verification-deadline-passed': (_('Learn More'), ''),
- 'verification-deadline-retry': (_('Retry Verification'), reverse('verify_student_reverify')),
+ 'verification-deadline-retry': (
+ _('Retry Verification'),
+ IDVerificationService.get_verify_location('verify_student_reverify'),
+ ),
'verification-deadline-upcoming': (
_('Verify My Identity'),
- reverse('verify_student_verify_now', args=(self.course_id,))
+ IDVerificationService.get_verify_location('verify_student_verify_now', self.course_id),
)
}
diff --git a/lms/djangoapps/verify_student/management/commands/send_verification_expiry_email.py b/lms/djangoapps/verify_student/management/commands/send_verification_expiry_email.py
index 3b0ca6f33f..644697d23f 100644
--- a/lms/djangoapps/verify_student/management/commands/send_verification_expiry_email.py
+++ b/lms/djangoapps/verify_student/management/commands/send_verification_expiry_email.py
@@ -22,6 +22,7 @@ from util.query import use_read_replica_if_available
from lms.djangoapps.verify_student.message_types import VerificationExpiry
from lms.djangoapps.verify_student.models import ManualVerification, SoftwareSecurePhotoVerification, SSOVerification
+from lms.djangoapps.verify_student.services import IDVerificationService
from openedx.core.djangoapps.ace_common.template_context import get_base_template_context
from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
@@ -190,7 +191,7 @@ class Command(BaseCommand):
message_context = get_base_template_context(site)
message_context.update({
'platform_name': settings.PLATFORM_NAME,
- 'lms_verification_link': '{}{}'.format(settings.LMS_ROOT_URL, reverse("verify_student_reverify")),
+ 'lms_verification_link': IDVerificationService.email_reverify_url(),
'help_center_link': settings.ID_VERIFICATION_SUPPORT_LINK
})
diff --git a/lms/djangoapps/verify_student/services.py b/lms/djangoapps/verify_student/services.py
index 49d41120e8..a12737246d 100644
--- a/lms/djangoapps/verify_student/services.py
+++ b/lms/djangoapps/verify_student/services.py
@@ -15,6 +15,7 @@ from openedx.core.djangoapps.site_configuration import helpers as configuration_
from student.models import User
from .models import ManualVerification, SoftwareSecurePhotoVerification, SSOVerification
+from .toggles import redirect_to_idv_microfrontend
from .utils import earliest_allowed_verification_date, most_recent_verification
log = logging.getLogger(__name__)
@@ -46,7 +47,7 @@ class XBlockVerificationService(object):
"""
Returns the URL for a user to verify themselves.
"""
- return reverse('verify_student_reverify')
+ return IDVerificationService.get_verify_location('verify_student_reverify')
class IDVerificationService(object):
@@ -240,3 +241,38 @@ class IDVerificationService(object):
return 'Not ID Verified'
else:
return 'ID Verified'
+
+ @classmethod
+ def get_verify_location(cls, url_name, course_id=None):
+ """
+ url_name is one of:
+ 'verify_student_verify_now'
+ 'verify_student_reverify'
+
+ Returns a string:
+ If waffle flag is active, returns URL for IDV microfrontend.
+ Else, returns URL for corresponding view.
+ """
+ location = ''
+ if redirect_to_idv_microfrontend():
+ location = '{}/id-verification'.format(settings.ACCOUNT_MICROFRONTEND_URL)
+ if course_id:
+ location = location + '?{}'.format(str(course_id))
+ else:
+ if course_id:
+ location = reverse(url_name, args=[str(course_id)])
+ else:
+ location = reverse(url_name)
+ return location
+
+ @classmethod
+ def email_reverify_url(cls):
+ """
+ Return a URL string for reverification emails:
+ If waffle flag is active, returns URL for IDV microfrontend.
+ Else, returns URL for reverify view.
+ """
+ if redirect_to_idv_microfrontend():
+ return '{}/id-verification'.format(settings.ACCOUNT_MICROFRONTEND_URL)
+ else:
+ return '{}{}'.format(settings.LMS_ROOT_URL, reverse('verify_student_reverify'))
diff --git a/lms/djangoapps/verify_student/toggles.py b/lms/djangoapps/verify_student/toggles.py
index c2fb3fd58d..541939f52c 100644
--- a/lms/djangoapps/verify_student/toggles.py
+++ b/lms/djangoapps/verify_student/toggles.py
@@ -27,3 +27,25 @@ USE_NEW_EMAIL_TEMPLATES = WaffleFlag(
def use_new_templates_for_id_verification_emails():
return USE_NEW_EMAIL_TEMPLATES.is_enabled()
+
+
+# Waffle flag to redirect to the new IDV flow on the account microfrontend
+# .. toggle_name: verify_student.redirect_to_idv_microfrontend
+# .. toggle_implementation: WaffleFlag
+# .. toggle_default: False
+# .. toggle_description: Supports staged rollout to students for the new IDV flow.
+# .. toggle_category: verify student
+# .. toggle_use_cases: incremental_release, open_edx
+# .. toggle_creation_date: 2020-07-09
+# .. toggle_expiration_date: n/a
+# .. toggle_warnings: n/a
+# .. toggle_tickets: MST-318
+# .. toggle_status: supported
+REDIRECT_TO_IDV_MICROFRONTEND = WaffleFlag(
+ waffle_namespace=WAFFLE_FLAG_NAMESPACE,
+ flag_name='redirect_to_idv_microfrontend',
+)
+
+
+def redirect_to_idv_microfrontend():
+ return REDIRECT_TO_IDV_MICROFRONTEND.is_enabled()
diff --git a/lms/djangoapps/verify_student/views.py b/lms/djangoapps/verify_student/views.py
index 5fd97303f9..60e6eab8aa 100644
--- a/lms/djangoapps/verify_student/views.py
+++ b/lms/djangoapps/verify_student/views.py
@@ -36,7 +36,6 @@ from lms.djangoapps.commerce.utils import EcommerceService, is_account_activatio
from lms.djangoapps.verify_student.emails import send_verification_approved_email, send_verification_confirmation_email
from lms.djangoapps.verify_student.image import InvalidImageData, decode_image_data
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, VerificationDeadline
-from lms.djangoapps.verify_student.services import IDVerificationService
from lms.djangoapps.verify_student.ssencrypt import has_valid_signature
from lms.djangoapps.verify_student.tasks import send_verification_status_email
from lms.djangoapps.verify_student.utils import can_verify_now
@@ -54,6 +53,9 @@ from util.json_request import JsonResponse
from verify_student.toggles import use_new_templates_for_id_verification_emails
from xmodule.modulestore.django import modulestore
+from .services import IDVerificationService
+from .toggles import redirect_to_idv_microfrontend
+
log = logging.getLogger(__name__)
@@ -510,7 +512,10 @@ class PayAndVerifyView(View):
if is_enrolled:
if already_paid:
# If the student has paid, but not verified, redirect to the verification flow.
- url = reverse('verify_student_verify_now', kwargs=course_kwargs)
+ url = IDVerificationService.get_verify_location(
+ 'verify_student_verify_now',
+ six.text_type(course_key)
+ )
else:
url = reverse('verify_student_start_flow', kwargs=course_kwargs)
@@ -1139,7 +1144,7 @@ def results_callback(request):
log.debug(u"Denying verification for %s", receipt_id)
attempt.deny(json.dumps(reason), error_code=error_code)
status = "denied"
- reverify_url = '{}{}'.format(settings.LMS_ROOT_URL, reverse("verify_student_reverify"))
+ reverify_url = IDVerificationService.email_reverify_url()
verification_status_email_vars['reasons'] = reason
verification_status_email_vars['reverify_url'] = reverify_url
verification_status_email_vars['faq_url'] = settings.ID_VERIFICATION_SUPPORT_LINK
@@ -1229,6 +1234,8 @@ class ReverifyView(View):
verification_status = IDVerificationService.user_status(request.user)
expiration_datetime = IDVerificationService.get_expiration_datetime(request.user, ['approved'])
if can_verify_now(verification_status, expiration_datetime):
+ if redirect_to_idv_microfrontend():
+ return redirect('{}/id-verification'.format(settings.ACCOUNT_MICROFRONTEND_URL))
context = {
"user_full_name": request.user.profile.name,
"platform_name": configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME),
diff --git a/lms/templates/dashboard/_dashboard_course_listing.html b/lms/templates/dashboard/_dashboard_course_listing.html
index 8963bfbf28..48adca88db 100644
--- a/lms/templates/dashboard/_dashboard_course_listing.html
+++ b/lms/templates/dashboard/_dashboard_course_listing.html
@@ -3,12 +3,14 @@
<%!
import six
+from django.conf import settings
from django.utils.http import urlencode, urlquote_plus
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from django.urls import reverse
from course_modes.models import CourseMode
from course_modes.helpers import enrollment_mode_display
+from lms.djangoapps.verify_student.services import IDVerificationService
from openedx.core.djangolib.js_utils import dump_js_escaped_json, js_escaped_string
from openedx.core.djangolib.markup import HTML, Text
from openedx.features.course_experience import course_home_url_name
@@ -26,7 +28,7 @@ from lms.djangoapps.experiments.utils import UPSELL_TRACKING_FLAG
%>
<%
- reverify_link = reverse('verify_student_reverify')
+ reverify_link = IDVerificationService.get_verify_location('verify_student_reverify')
cert_name_short = course_overview.cert_name_short
if cert_name_short == "":
cert_name_short = settings.CERT_NAME_SHORT
@@ -364,7 +366,7 @@ from lms.djangoapps.experiments.utils import UPSELL_TRACKING_FLAG
% endif
% elif verification_status['status'] == VERIFY_STATUS_SUBMITTED:
${_('You have submitted your verification information.')}
@@ -382,7 +384,7 @@ from lms.djangoapps.experiments.utils import UPSELL_TRACKING_FLAG
## Translators: start_link and end_link will be replaced with HTML tags;
## please do not translate these.
${Text(_('Your current verification will expire in {days} days. {start_link}Re-verify your identity now{end_link} using a webcam and a government-issued photo ID.')).format(
- start_link=HTML('').format(href=reverse('verify_student_reverify')),
+ start_link=HTML('').format(href=IDVerificationService.get_verify_location('verify_student_reverify')),
end_link=HTML(''),
days=settings.VERIFY_STUDENT.get("EXPIRING_SOON_WINDOW")
)}
diff --git a/lms/templates/dashboard/_dashboard_status_verification.html b/lms/templates/dashboard/_dashboard_status_verification.html
index ca992ccac4..42e5b15dc4 100644
--- a/lms/templates/dashboard/_dashboard_status_verification.html
+++ b/lms/templates/dashboard/_dashboard_status_verification.html
@@ -3,6 +3,7 @@
<%!
from django.urls import reverse
from django.utils.translation import ugettext as _
+from lms.djangoapps.verify_student.services import IDVerificationService
%>
%if verification_display:
@@ -13,7 +14,7 @@ from django.utils.translation import ugettext as _
%if verification_expiry:
${_("Warning")}: ${_("Your photo verification expires on {verification_expiry}. Please be aware photo verification can take up to three days once initiated and you will not be able to earn a certificate or take a proctored exam until approved.").format(verification_expiry=verification_expiry)}
%endif
@@ -39,7 +40,7 @@ from django.utils.translation import ugettext as _
%endif
%elif verification_status == 'expired':
@@ -48,7 +49,7 @@ from django.utils.translation import ugettext as _
${_("Your verification has expired. To receive a verified certificate, you must submit a new photo of yourself and your government-issued photo ID before the verification deadline for your course.")}
${_("Warning")}: ${_(" Please be aware photo verification can take up to three days once initiated and you will not be able to earn a certificate or take a proctored exam until approved.")}
%endif