From 4ee9ef61cf43f10c5d7c81f93974c02dad122262 Mon Sep 17 00:00:00 2001
From: Diana Huang <dkh@edx.org>
Date: Tue, 24 Sep 2013 14:11:00 -0400
Subject: [PATCH] Clean up some old pep8/pylint violations

Also, deletes some unused code.
---
 common/djangoapps/course_modes/views.py    | 27 +++++--
 lms/djangoapps/verify_student/models.py    | 32 ++++----
 lms/djangoapps/verify_student/ssencrypt.py | 35 +++++++--
 lms/djangoapps/verify_student/urls.py      |  7 --
 lms/djangoapps/verify_student/views.py     | 89 +++++-----------------
 5 files changed, 86 insertions(+), 104 deletions(-)

diff --git a/common/djangoapps/course_modes/views.py b/common/djangoapps/course_modes/views.py
index cf4dadd1a0c..02934f36509 100644
--- a/common/djangoapps/course_modes/views.py
+++ b/common/djangoapps/course_modes/views.py
@@ -1,12 +1,15 @@
+"""
+Views for the course_mode module
+"""
+
 import decimal
 from django.core.urlresolvers import reverse
 from django.http import (
-    HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, Http404
+    HttpResponseBadRequest,  Http404
 )
 from django.shortcuts import redirect
 from django.views.generic.base import View
 from django.utils.translation import ugettext as _
-from django.utils.http import urlencode
 from django.contrib.auth.decorators import login_required
 from django.utils.decorators import method_decorator
 
@@ -18,10 +21,19 @@ from student.models import CourseEnrollment
 from student.views import course_from_id
 from verify_student.models import SoftwareSecurePhotoVerification
 
-class ChooseModeView(View):
 
+class ChooseModeView(View):
+    """
+    View used when the user is asked to pick a mode
+
+    When a get request is used, shows the selection page.
+    When a post request is used, assumes that it is a form submission
+        from the selection page, parses the response, and then sends user
+        to the next step in the flow
+    """
     @method_decorator(login_required)
     def get(self, request, course_id, error=None):
+        """ Displays the course mode choice page """
         if CourseEnrollment.enrollment_mode_for_user(request.user, course_id) == 'verified':
             return redirect(reverse('dashboard'))
         modes = CourseMode.modes_for_course_dict(course_id)
@@ -34,8 +46,8 @@ class ChooseModeView(View):
             "course_id": course_id,
             "modes": modes,
             "course_name": course.display_name_with_default,
-            "course_org" : course.display_org_with_default,
-            "course_num" : course.display_number_with_default,
+            "course_org": course.display_org_with_default,
+            "course_num": course.display_number_with_default,
             "chosen_price": chosen_price,
             "error": error,
         }
@@ -48,6 +60,7 @@ class ChooseModeView(View):
 
     @method_decorator(login_required)
     def post(self, request, course_id):
+        """ Takes the form submission from the page and parses it """
         user = request.user
 
         # This is a bit redundant with logic in student.views.change_enrollement,
@@ -102,6 +115,10 @@ class ChooseModeView(View):
             )
 
     def get_requested_mode(self, user_choice):
+        """
+        Given the text of `user_choice`, return the
+        corresponding course mode slug
+        """
         choices = {
             "Select Audit": "audit",
             "Select Certificate": "verified"
diff --git a/lms/djangoapps/verify_student/models.py b/lms/djangoapps/verify_student/models.py
index 5a1821de541..80e05d09b13 100644
--- a/lms/djangoapps/verify_student/models.py
+++ b/lms/djangoapps/verify_student/models.py
@@ -26,12 +26,11 @@ from django.conf import settings
 from django.core.urlresolvers import reverse
 from django.db import models
 from django.contrib.auth.models import User
-from django.core.urlresolvers import reverse
 from model_utils.models import StatusModel
 from model_utils import Choices
 
 from verify_student.ssencrypt import (
-    random_aes_key, decode_and_decrypt, encrypt_and_encode,
+    random_aes_key, encrypt_and_encode,
     generate_signed_message, rsa_encrypt
 )
 
@@ -57,15 +56,18 @@ def status_before_must_be(*valid_start_statuses):
     distracting boilerplate when looking at a Model that needs to go through a
     workflow process.
     """
-    def decorator_func(fn):
-        @functools.wraps(fn)
+    def decorator_func(func):
+        """
+        Decorator function that gets returned
+        """
+        @functools.wraps(func)
         def with_status_check(obj, *args, **kwargs):
             if obj.status not in valid_start_statuses:
                 exception_msg = (
                     u"Error calling {} {}: status is '{}', must be one of: {}"
-                ).format(fn, obj, obj.status, valid_start_statuses)
+                ).format(func, obj, obj.status, valid_start_statuses)
                 raise VerificationException(exception_msg)
-            return fn(obj, *args, **kwargs)
+            return func(obj, *args, **kwargs)
 
         return with_status_check
 
@@ -367,7 +369,7 @@ class PhotoVerification(StatusModel):
         Status should be moved to `must_retry`.
         """
         if self.status in ["approved", "denied"]:
-            return # If we were already approved or denied, just leave it.
+            return  # If we were already approved or denied, just leave it.
 
         self.error_msg = error_msg
         self.error_code = error_code
@@ -408,7 +410,7 @@ class SoftwareSecurePhotoVerification(PhotoVerification):
     # encode that. The result is saved here. Actual expected length is 344.
     photo_id_key = models.TextField(max_length=1024)
 
-    IMAGE_LINK_DURATION = 5 * 60 * 60 * 24 # 5 days in seconds
+    IMAGE_LINK_DURATION = 5 * 60 * 60 * 24  # 5 days in seconds
 
     @status_before_must_be("created")
     def upload_face_image(self, img_data):
@@ -444,8 +446,8 @@ class SoftwareSecurePhotoVerification(PhotoVerification):
                 self.status = "must_retry"
                 self.error_msg = response.text
                 self.save()
-        except Exception as e:
-            log.exception(e)
+        except Exception as error:
+            log.exception(error)
 
     def image_url(self, name):
         """
@@ -466,7 +468,7 @@ class SoftwareSecurePhotoVerification(PhotoVerification):
         bucket = conn.get_bucket(settings.VERIFY_STUDENT["SOFTWARE_SECURE"]["S3_BUCKET"])
 
         key = Key(bucket)
-        key.key = "{}/{}".format(prefix, self.receipt_id);
+        key.key = "{}/{}".format(prefix, self.receipt_id)
 
         return key
 
@@ -507,7 +509,7 @@ class SoftwareSecurePhotoVerification(PhotoVerification):
             "Content-Type": "application/json",
             "Date": formatdate(timeval=None, localtime=False, usegmt=True)
         }
-        message, _, authorization = generate_signed_message(
+        _message, _sig, authorization = generate_signed_message(
             "POST", headers, body, access_key, secret_key
         )
         headers['Authorization'] = authorization
@@ -515,16 +517,18 @@ class SoftwareSecurePhotoVerification(PhotoVerification):
         return headers, body
 
     def request_message_txt(self):
+        """ This is the body of the request we send across """
         headers, body = self.create_request()
 
         header_txt = "\n".join(
-            "{}: {}".format(h, v) for h,v in sorted(headers.items())
+            "{}: {}".format(h, v) for h, v in sorted(headers.items())
         )
         body_txt = json.dumps(body, indent=2, sort_keys=True, ensure_ascii=False).encode('utf-8')
 
         return header_txt + "\n\n" + body_txt
 
     def send_request(self):
+        """ sends the request across to the endpoint """
         headers, body = self.create_request()
         response = requests.post(
             settings.VERIFY_STUDENT["SOFTWARE_SECURE"]["API_URL"],
@@ -538,4 +542,4 @@ class SoftwareSecurePhotoVerification(PhotoVerification):
         log.debug("Return code: {}".format(response.status_code))
         log.debug("Return message:\n\n{}\n\n".format(response.text))
 
-        return response
\ No newline at end of file
+        return response
diff --git a/lms/djangoapps/verify_student/ssencrypt.py b/lms/djangoapps/verify_student/ssencrypt.py
index aefb4292a0c..bbf32d7a8be 100644
--- a/lms/djangoapps/verify_student/ssencrypt.py
+++ b/lms/djangoapps/verify_student/ssencrypt.py
@@ -22,16 +22,11 @@ In case of PEM encoding, the private key can be encrypted with DES or 3TDES
 according to a certain pass phrase. Only OpenSSL-compatible pass phrases are
 supported.
 """
-from collections import OrderedDict
-from email.utils import formatdate
 from hashlib import md5, sha256
-from uuid import uuid4
 import base64
 import binascii
-import json
 import hmac
 import logging
-import sys
 
 from Crypto import Random
 from Crypto.Cipher import AES, PKCS1_OAEP
@@ -39,12 +34,17 @@ from Crypto.PublicKey import RSA
 
 log = logging.getLogger(__name__)
 
+
 def encrypt_and_encode(data, key):
+    """ Encrypts and endcodes `data` using `key' """
     return base64.urlsafe_b64encode(aes_encrypt(data, key))
 
+
 def decode_and_decrypt(encoded_data, key):
+    """ Decrypts and decodes `data` using `key' """
     return aes_decrypt(base64.urlsafe_b64decode(encoded_data), key)
 
+
 def aes_encrypt(data, key):
     """
     Return a version of the `data` that has been encrypted to
@@ -53,11 +53,16 @@ def aes_encrypt(data, key):
     padded_data = pad(data)
     return cipher.encrypt(padded_data)
 
+
 def aes_decrypt(encrypted_data, key):
+    """
+    Decrypt `encrypted_data` using `key`
+    """
     cipher = aes_cipher_from_key(key)
     padded_data = cipher.decrypt(encrypted_data)
     return unpad(padded_data)
 
+
 def aes_cipher_from_key(key):
     """
     Given an AES key, return a Cipher object that has `encrypt()` and
@@ -66,6 +71,7 @@ def aes_cipher_from_key(key):
     """
     return AES.new(key, AES.MODE_CBC, generate_aes_iv(key))
 
+
 def generate_aes_iv(key):
     """
     Return the initialization vector Software Secure expects for a given AES
@@ -73,17 +79,23 @@ def generate_aes_iv(key):
     """
     return md5(key + md5(key).hexdigest()).hexdigest()[:AES.block_size]
 
+
 def random_aes_key():
     return Random.new().read(32)
 
+
 def pad(data):
+    """ Pad the given `data` such that it fits into the proper AES block size """
     bytes_to_pad = AES.block_size - len(data) % AES.block_size
     return data + (bytes_to_pad * chr(bytes_to_pad))
 
+
 def unpad(padded_data):
+    """  remove all padding from `padded_data` """
     num_padded_bytes = ord(padded_data[-1])
     return padded_data[:-num_padded_bytes]
 
+
 def rsa_encrypt(data, rsa_pub_key_str):
     """
     `rsa_pub_key` is a string with the public key
@@ -93,11 +105,16 @@ def rsa_encrypt(data, rsa_pub_key_str):
     encrypted_data = cipher.encrypt(data)
     return encrypted_data
 
+
 def rsa_decrypt(data, rsa_priv_key_str):
+    """
+    When given some `data` and an RSA private key, decrypt the data
+    """
     key = RSA.importKey(rsa_priv_key_str)
     cipher = PKCS1_OAEP.new(key)
     return cipher.decrypt(data)
 
+
 def has_valid_signature(method, headers_dict, body_dict, access_key, secret_key):
     """
     Given a message (either request or response), say whether it has a valid
@@ -123,6 +140,7 @@ def has_valid_signature(method, headers_dict, body_dict, access_key, secret_key)
 
     return True
 
+
 def generate_signed_message(method, headers_dict, body_dict, access_key, secret_key):
     """
     Returns a (message, signature) pair.
@@ -137,6 +155,7 @@ def generate_signed_message(method, headers_dict, body_dict, access_key, secret_
     message += '\n'
     return message, signature, authorization_header
 
+
 def signing_format_message(method, headers_dict, body_dict):
     """
     Given a dictionary of headers and a dictionary of the JSON for the body,
@@ -149,6 +168,7 @@ def signing_format_message(method, headers_dict, body_dict):
 
     return message
 
+
 def header_string(headers_dict):
     """Given a dictionary of headers, return a canonical string representation."""
     header_list = []
@@ -160,7 +180,8 @@ def header_string(headers_dict):
     if 'Content-MD5' in headers_dict:
         header_list.append(headers_dict['Content-MD5'] + "\n")
 
-    return "".join(header_list) # Note that trailing \n's are important
+    return "".join(header_list)  # Note that trailing \n's are important
+
 
 def body_string(body_dict, prefix=""):
     """
@@ -183,5 +204,5 @@ def body_string(body_dict, prefix=""):
                 value = "null"
             body_list.append(u"{}{}:{}\n".format(prefix, key, value).encode('utf-8'))
 
-    return "".join(body_list) # Note that trailing \n's are important
+    return "".join(body_list)  # Note that trailing \n's are important
 
diff --git a/lms/djangoapps/verify_student/urls.py b/lms/djangoapps/verify_student/urls.py
index 52c55ad452d..15c2cc5f6b2 100644
--- a/lms/djangoapps/verify_student/urls.py
+++ b/lms/djangoapps/verify_student/urls.py
@@ -35,11 +35,4 @@ urlpatterns = patterns(
         name="verify_student_results_callback",
     ),
 
-    url(
-        r'^show_verification_page/(?P<course_id>[^/]+/[^/]+/[^/]+)$',
-        views.show_verification_page,
-        name="verify_student/show_verification_page"
-    ),
-
-
 )
diff --git a/lms/djangoapps/verify_student/views.py b/lms/djangoapps/verify_student/views.py
index 329e7efa102..b220ff6a97d 100644
--- a/lms/djangoapps/verify_student/views.py
+++ b/lms/djangoapps/verify_student/views.py
@@ -1,5 +1,5 @@
 """
-
+Views for the verification flow
 
 """
 import json
@@ -37,6 +37,12 @@ class VerifyView(View):
     @method_decorator(login_required)
     def get(self, request, course_id):
         """
+        Displays the main verification view, which contains three separate steps:
+            - Taking the standard face photo
+            - Taking the id photo
+            - Confirming that the photos and payment price are correct
+              before proceeding to payment
+
         """
         # If the user has already been verified within the given time period,
         # redirect straight to the payment -- no need to verify again.
@@ -69,8 +75,8 @@ class VerifyView(View):
             "user_full_name": request.user.profile.name,
             "course_id": course_id,
             "course_name": course.display_name_with_default,
-            "course_org" : course.display_org_with_default,
-            "course_num" : course.display_number_with_default,
+            "course_org": course.display_org_with_default,
+            "course_num": course.display_number_with_default,
             "purchase_endpoint": get_purchase_endpoint(),
             "suggested_prices": [
                 decimal.Decimal(price)
@@ -106,8 +112,8 @@ class VerifiedView(View):
         context = {
             "course_id": course_id,
             "course_name": course.display_name_with_default,
-            "course_org" : course.display_org_with_default,
-            "course_num" : course.display_number_with_default,
+            "course_org": course.display_org_with_default,
+            "course_num": course.display_number_with_default,
             "purchase_endpoint": get_purchase_endpoint(),
             "currency": verify_mode.currency.upper(),
             "chosen_price": chosen_price,
@@ -162,8 +168,9 @@ def create_order(request):
 
     return HttpResponse(json.dumps(params), content_type="text/json")
 
+
 @require_POST
-@csrf_exempt # SS does its own message signing, and their API won't have a cookie value
+@csrf_exempt  # SS does its own message signing, and their API won't have a cookie value
 def results_callback(request):
     """
     Software Secure will call this callback to tell us whether a user is
@@ -194,7 +201,7 @@ def results_callback(request):
         settings.VERIFY_STUDENT["SOFTWARE_SECURE"]["API_SECRET_KEY"]
     )
 
-    _, access_key_and_sig = headers["Authorization"].split(" ")
+    _response, access_key_and_sig = headers["Authorization"].split(" ")
     access_key = access_key_and_sig.split(":")[0]
 
     # This is what we should be doing...
@@ -234,10 +241,11 @@ def results_callback(request):
 
     return HttpResponse("OK!")
 
+
 @login_required
 def show_requirements(request, course_id):
     """
-    Show the requirements necessary for
+    Show the requirements necessary for the verification flow.
     """
     if CourseEnrollment.enrollment_mode_for_user(request.user, course_id) == 'verified':
         return redirect(reverse('dashboard'))
@@ -246,69 +254,8 @@ def show_requirements(request, course_id):
     context = {
         "course_id": course_id,
         "course_name": course.display_name_with_default,
-        "course_org" : course.display_org_with_default,
-        "course_num" : course.display_number_with_default,
+        "course_org": course.display_org_with_default,
+        "course_num": course.display_number_with_default,
         "is_not_active": not request.user.is_active,
     }
     return render_to_response("verify_student/show_requirements.html", context)
-
-
-def show_verification_page(request):
-    pass
-
-def enroll(user, course_id, mode_slug):
-    """
-    Enroll the user in a course for a certain mode.
-
-    This is the view you send folks to when they click on the enroll button.
-    This does NOT cover changing enrollment modes -- it's intended for new
-    enrollments only, and will just redirect to the dashboard if it detects
-    that an enrollment already exists.
-    """
-    # If the user is already enrolled, jump to the dashboard. Yeah, we could
-    # do upgrades here, but this method is complicated enough.
-    if CourseEnrollment.is_enrolled(user, course_id):
-        return HttpResponseRedirect(reverse('dashboard'))
-
-    available_modes = CourseModes.modes_for_course(course_id)
-
-    # If they haven't chosen a mode...
-    if not mode_slug:
-        # Does this course support multiple modes of Enrollment? If so, redirect
-        # to a page that lets them choose which mode they want.
-        if len(available_modes) > 1:
-            return HttpResponseRedirect(
-                reverse('choose_enroll_mode', kwargs={'course_id': course_id})
-            )
-        # Otherwise, we use the only mode that's supported...
-        else:
-            mode_slug = available_modes[0].slug
-
-    # If the mode is one of the simple, non-payment ones, do the enrollment and
-    # send them to their dashboard.
-    if mode_slug in ("honor", "audit"):
-        CourseEnrollment.enroll(user, course_id, mode=mode_slug)
-        return HttpResponseRedirect(reverse('dashboard'))
-
-    if mode_slug == "verify":
-        if SoftwareSecurePhotoVerification.has_submitted_recent_request(user):
-            # Capture payment info
-            # Create an order
-            # Create a VerifiedCertificate order item
-            return HttpResponse.Redirect(reverse('verified'))
-
-    # There's always at least one mode available (default is "honor"). If they
-    # haven't specified a mode, we just assume it's
-    if not mode:
-        mode = available_modes[0]
-
-    elif len(available_modes) == 1:
-        if mode != available_modes[0]:
-            raise Exception()
-
-        mode = available_modes[0]
-
-    if mode == "honor":
-        CourseEnrollment.enroll(user, course_id)
-        return HttpResponseRedirect(reverse('dashboard'))
-
-- 
GitLab