diff --git a/lms/djangoapps/verify_student/urls.py b/lms/djangoapps/verify_student/urls.py
index 15c2cc5f6b..843ebf9602 100644
--- a/lms/djangoapps/verify_student/urls.py
+++ b/lms/djangoapps/verify_student/urls.py
@@ -35,4 +35,15 @@ urlpatterns = patterns(
name="verify_student_results_callback",
),
+ url(
+ r'^reverify$',
+ views.ReverifyView.as_view(),
+ name="verify_student_reverify"
+ ),
+
+ url(
+ r'^reverification_confirmation$',
+ views.reverification_submission_confirmation,
+ name="verify_student_reverification_confirmation"
+ ),
)
diff --git a/lms/djangoapps/verify_student/views.py b/lms/djangoapps/verify_student/views.py
index 8fafc26834..673564e72c 100644
--- a/lms/djangoapps/verify_student/views.py
+++ b/lms/djangoapps/verify_student/views.py
@@ -267,3 +267,66 @@ def show_requirements(request, course_id):
"upgrade": upgrade,
}
return render_to_response("verify_student/show_requirements.html", context)
+
+
+class ReverifyView(View):
+ """
+ The main reverification view. Under similar constraints as the main verification view.
+ Has to perform these functions:
+ - take new face photo
+ - take new id photo
+ - submit photos to photo verification service
+
+ Does not need to be attached to a particular course.
+ Does not need to worry about pricing
+ """
+ @method_decorator(login_required)
+ def get(self, request):
+ """
+ display this view
+ """
+ context = {
+ "user_full_name": request.user.profile.name,
+ "error": False,
+ }
+
+ return render_to_response("verify_student/photo_reverification.html", context)
+
+ @method_decorator(login_required)
+ def post(self, request):
+ """
+ submits the reverification to SoftwareSecure
+ """
+
+ try:
+ attempt = SoftwareSecurePhotoVerification(user=request.user)
+ b64_face_image = request.POST['face_image'].split(",")[1]
+ b64_photo_id_image = request.POST['photo_id_image'].split(",")[1]
+
+ attempt.upload_face_image(b64_face_image.decode('base64'))
+ attempt.upload_photo_id_image(b64_photo_id_image.decode('base64'))
+ attempt.mark_ready()
+
+ # save this attempt
+ attempt.save()
+ # then submit it across
+ attempt.submit()
+ return HttpResponseRedirect(reverse('verify_student_reverification_confirmation'))
+ except Exception:
+ log.exception(
+ "Could not submit verification attempt for user {}".format(request.user.id)
+ )
+ context = {
+ "user_full_name": request.user.profile.name,
+ "error": True,
+ }
+ return render_to_response("verify_student/photo_reverification.html", context)
+
+
+@login_required
+def reverification_submission_confirmation(_request):
+ """
+ Shows the user a confirmation page if the submission to SoftwareSecure was successful
+ """
+
+ return render_to_response("verify_student/reverification_confirmation.html")
diff --git a/lms/static/js/verify_student/photocapture.js b/lms/static/js/verify_student/photocapture.js
index 0519767841..4db15e9d51 100644
--- a/lms/static/js/verify_student/photocapture.js
+++ b/lms/static/js/verify_student/photocapture.js
@@ -18,6 +18,23 @@ function initVideoCapture() {
return !(navigator.getUserMedia == undefined);
}
+var submitReverificationPhotos = function() {
+ // add photos to the form
+ $(' ').attr({
+ type: 'hidden',
+ name: 'face_image',
+ value: $("#face_image")[0].src,
+ }).appendTo("#reverify_form");
+ $(' ').attr({
+ type: 'hidden',
+ name: 'photo_id_image',
+ value: $("#photo_id_image")[0].src,
+ }).appendTo("#reverify_form");
+
+ $("#reverify_form").submit();
+
+}
+
var submitToPaymentProcessing = function() {
var contribution_input = $("input[name='contribution']:checked")
var contribution = 0;
@@ -255,10 +272,15 @@ $(document).ready(function() {
submitToPaymentProcessing();
});
+ $("#reverify_button").click(function() {
+ submitReverificationPhotos();
+ });
+
// prevent browsers from keeping this button checked
$("#confirm_pics_good").prop("checked", false)
$("#confirm_pics_good").change(function() {
$("#pay_button").toggleClass('disabled');
+ $("#reverify_button").toggleClass('disabled');
});
diff --git a/lms/templates/verify_student/photo_reverification.html b/lms/templates/verify_student/photo_reverification.html
new file mode 100644
index 0000000000..764458b791
--- /dev/null
+++ b/lms/templates/verify_student/photo_reverification.html
@@ -0,0 +1,394 @@
+<%! from django.utils.translation import ugettext as _ %>
+<%! from django.core.urlresolvers import reverse %>
+<%inherit file="../main.html" />
+<%namespace name='static' file='/static_content.html'/>
+
+<%block name="bodyclass">register verification-process step-photos%block>
+<%block name="title">
${_("Re-Verification")} %block>
+
+<%block name="js_extra">
+
+
+
+%block>
+
+
+<%block name="content">
+
+
+
+
+
+
${_("No Webcam Detected")}
+
+
${_("You don't seem to have a webcam connected. Double-check that your webcam is connected and working to continue.")}
+
+
+
+
+
+
+
+
+
+
${_("No Flash Detected")}
+
+
${_("You don't seem to have Flash installed. {a_start} Get Flash {a_end} to continue your registration.").format(a_start='', a_end=" ")}
+
+
+
+
+
+%if error:
+
+
+
+
+
${_("Error submitting your images")}
+
+
${_("Oops! Something went wrong. Please confirm your details again and try again.")}
+
+
+
+
+%endif
+
+
+
+
+
+
+ ${_("Your Progress")}
+
+
+
+
+ 0
+ ${_("Intro")}
+
+
+
+ 1
+ ${_("Current Step: ")} ${_("Take Photo")}
+
+
+
+ 2
+ ${_("Take ID Photo")}
+
+
+
+ 3
+ ${_("Review")}
+
+
+
+ 4
+ ${_("Make Payment")}
+
+
+
+
+
+
+ ${_("Confirmation")}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
${_("Take Your Photo")}
+
+
${_("Use your webcam to take a picture of your face so we can match it with the picture on your ID.")}
+
+
+
+
+
+
+
+
${_("Don't see your picture? Make sure to allow your browser to use your camera when it asks for permission.")}
+
+
+
+
+
+
+
+
+
+
+
+
${_("Tips on taking a successful photo")}
+
+
+
+ ${_("Make sure your face is well-lit")}
+ ${_("Be sure your entire face is inside the frame")}
+ ${_("Can we match the photo you took with the one on your ID?")}
+ ${_("Once in position, use the camera button")} ( ) ${_("to capture your picture")}
+ ${_("Use the checkmark button")} ( ) ${_("once you are happy with the photo")}
+
+
+
+
+
+
${_("Common Questions")}
+
+
+
+ ${_("Why do you need my photo?")}
+ ${_("As part of the verification process, we need your photo to confirm that you are you.")}
+
+ ${_("What do you do with this picture?")}
+ ${_("We only use it to verify your identity. It is not displayed anywhere.")}
+ ${_("What if my camera isn't working?")}
+ ${_("")}
+
+
+
+
+
+
+
+ ${_("Once you verify your photo looks good, you can move on to step 2.")}
+
+
+
+ ${_("Go to Step 2: Take ID Photo")}
+
+
+
+
+
+
+
+
+
+
${_("Show Us Your ID")}
+
+
${_("Use your webcam to take a picture of your ID so we can match it with your photo and the name on your account.")}
+
+
+
+
+
+
+
+
${_("Don't see your picture? Make sure to allow your browser to use your camera when it asks for permission.")}
+
+
+
+
+
+
+
+
+
+
+
+
${_("Tips on taking a successful photo")}
+
+
+
+ ${_("Make sure your ID is well-lit")}
+ ${_("Check that there isn't any glare")}
+ ${_("Ensure that you can see your photo and read your name")}
+ ${_("Try to keep your fingers at the edge to avoid covering important information")}
+ ${_("Acceptable IDs include drivers licenses, passports, or other goverment-issued IDs that include your name and photo")}
+ ${_("Once in position, use the camera button")} ( ) ${_("to capture your ID")}
+ ${_("Use the checkmark button")} ( ) ${_("once you are happy with the photo")}
+
+
+
+
+
+
${_("Common Questions")}
+
+
+
+ ${_("Why do you need a photo of my ID?")}
+ ${_("We need to match your ID with your photo and name to confirm that you are you.")}
+
+ ${_("What do you do with this picture?")}
+ ${_("We encrypt it and send it to our secure authorization service for review. We use the highest levels of security and do not save the photo or information anywhere once the match has been completed.")}
+
+
+
+
+
+
+
+ ${_("Once you verify your ID photo looks good, you can move on to step 3.")}
+
+
+
+ ${_("Go to Step 3: Review Your Info")}
+
+
+
+
+
+
+
+
+
${_("Verify Your Submission")}
+
+
${_("Make sure we can verify your identity with the photos and information below.")}
+
+
+
+
+
+
+ ${_("Review the Photos You've Taken")}
+
+
+
${_("Please review the photos and verify that they meet the requirements listed below.")}
+
+
+
+
+
+
+
+
+
+
${_("The photo above needs to meet the following requirements:")}
+
+ ${_("Be well lit")}
+ ${_("Show your whole face")}
+ ${_("The photo on your ID must match the photo of your face")}
+
+
+
+
+
+
+
+
+
+
+
${_("The photo above needs to meet the following requirements:")}
+
+ ${_("Be readable (not too far away, no glare)")}
+ ${_("The photo on your ID must match the photo of your face")}
+ ${_("The name on your ID must match the name on your account below")}
+
+
+
+
+
+
+
+
${_("Photos don't meet the requirements?")}
+
+
+
+
+
+
+
+ ${_("Check Your Name")}
+
+
+
${_("Make sure your full name on your edX account ({full_name}) matches your ID. We will also use this as the name on your certificate.").format(full_name="" + user_full_name + " ")}
+
+
+
+
+
+
+
+
+
+
Before proceeding, please confirm that your details match
+
+
${_("Once you verify your details match the requirements, you can move on to step 4, payment on our secure server.")}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<%include file="_modal_editname.html" />
+%block>
diff --git a/lms/templates/verify_student/reverification_confirmation.html b/lms/templates/verify_student/reverification_confirmation.html
new file mode 100644
index 0000000000..2ab639effc
--- /dev/null
+++ b/lms/templates/verify_student/reverification_confirmation.html
@@ -0,0 +1,18 @@
+
+<%! from django.utils.translation import ugettext as _ %>
+<%! from django.core.urlresolvers import reverse %>
+<%inherit file="../main.html" />
+<%namespace name='static' file='/static_content.html'/>
+
+<%block name="bodyclass">register verification-process step-photos%block>
+<%block name="title">${_("Verification Submission Confirmation")} %block>
+
+<%block name="js_extra">
+
+
+%block>
+<%block name="content">
+Successfully reverified!
+
+Return to Dashboard
+%block>