Commit 1676fc31 by David Ormsbee

Halfway state for course enrollment by mode

parent 775ae010
......@@ -51,3 +51,8 @@ class CourseMode(models.Model):
if not modes:
modes = [cls.DEFAULT_MODE]
return modes
def __unicode__(self):
return u"{} : {}, min={}, prices={}".format(
self.course_id, self.mode_slug, self.min_price, self.suggested_prices
)
# Create your views here.
from django.http import HttpResponse
from django.views.generic.base import View
from mitxmako.shortcuts import render_to_response
from course_modes.models import CourseMode
class ChooseModeView(View):
def get(self, request):
course_id = request.GET.get("course_id")
context = {
"course_id" : course_id,
"available_modes" : CourseMode.modes_for_course(course_id)
}
return render_to_response("course_modes/choose.html", context)
def post(self, request):
course_id = request.GET.get("course_id")
mode_slug = request.POST.get("mode_slug")
user = request.user
# This is a bit redundant with logic in student.views.change_enrollement,
# but I don't really have the time to refactor it more nicely and test.
course = course_from_id(course_id)
if has_access(user, course, 'enroll'):
pass
......@@ -27,18 +27,19 @@ from django_future.csrf import ensure_csrf_cookie
from django.utils.http import cookie_date
from django.utils.http import base36_to_int
from django.utils.translation import ugettext as _
from django.views.decorators.http import require_POST
from ratelimitbackend.exceptions import RateLimitException
from mitxmako.shortcuts import render_to_response, render_to_string
from bs4 import BeautifulSoup
from course_modes.models import CourseMode
from student.models import (Registration, UserProfile, TestCenterUser, TestCenterUserForm,
TestCenterRegistration, TestCenterRegistrationForm,
PendingNameChange, PendingEmailChange,
CourseEnrollment, unique_id_for_user,
get_testcenter_registration, CourseEnrollmentAllowed)
from student.forms import PasswordResetFormNoActive
from certificates.models import CertificateStatuses, certificate_status_for_student
......@@ -328,7 +329,8 @@ def try_change_enrollment(request):
except Exception, e:
log.exception("Exception automatically enrolling after login: {0}".format(str(e)))
@login_required
@require_POST
def change_enrollment(request):
"""
Modify the enrollment status for the logged-in user.
......@@ -346,12 +348,7 @@ def change_enrollment(request):
as a post-login/registration helper, so the error messages in the responses
should never actually be user-visible.
"""
if request.method != "POST":
return HttpResponseNotAllowed(["POST"])
user = request.user
if not user.is_authenticated():
return HttpResponseForbidden()
action = request.POST.get("enrollment_action")
course_id = request.POST.get("course_id")
......@@ -371,6 +368,12 @@ def change_enrollment(request):
if not has_access(user, course, 'enroll'):
return HttpResponseBadRequest(_("Enrollment is closed"))
# If this course is available in multiple modes, redirect them to a page
# where they can choose which mode they want.
available_modes = CourseMode.modes_for_course(course_id)
if len(available_modes) > 1:
return HttpResponse(reverse("course_modes.views.choose"))
org, course_num, run = course_id.split("/")
statsd.increment("common.student.enrollment",
tags=["org:{0}".format(org),
......
......@@ -7,7 +7,7 @@ from student.tests.factories import UserFactory
from verify_student.models import SoftwareSecurePhotoVerification, VerificationException
class TestPhotoVerification(object):
class TestPhotoVerification(TestCase):
def test_state_transitions(self):
"""Make sure we can't make unexpected status transitions.
......
......@@ -4,7 +4,7 @@ from nose.tools import assert_equals
from verify_student.ssencrypt import (
aes_decrypt, aes_encrypt, encrypt_and_encode, decode_and_decrypt,
rsa_decrypt, rsa_encrypt
rsa_decrypt, rsa_encrypt, random_aes_key
)
def test_aes():
......@@ -76,8 +76,3 @@ l8N6+LEIVTMAytPk+/bImHvGHKZkCz5rEMSuYJWOmqKI92rUtI6fz5DUb3XSbrwT
# Even though our AES key is only 32 bytes, RSA encryption will make it 256
# bytes, and base64 encoding will blow that up to 344
assert_equals(len(base64.urlsafe_b64encode(encrypted_aes_key)), 344)
# Software Secure would decrypt our photo_id image by doing:
#rsa_encrypted_aes_key = base64.urlsafe_b64decode(encoded_photo_id_key)
#photo_id_aes_key = rsa_decrypt(rsa_encrypted_aes_key, priv_key_str)
......@@ -31,7 +31,8 @@ class StartView(TestCase):
user = UserFactory.create(username="rusty", password="test")
self.client.login(username="rusty", password="test")
def must_be_logged_in(self):
self.assertHttpForbidden(self.client.get(self.start_url()))
\ No newline at end of file
......@@ -6,6 +6,8 @@ from mitxmako.shortcuts import render_to_response
from verify_student.models import SoftwareSecurePhotoVerification
from course_modes.models import CourseMode
# @login_required
def start_or_resume_attempt(request, course_id):
"""
......@@ -15,8 +17,8 @@ def start_or_resume_attempt(request, course_id):
"""
# If the user has already been verified within the given time period,
# redirect straight to the payment -- no need to verify again.
#if SoftwareSecurePhotoVerification.user_is_verified(user):
# pass
if SoftwareSecurePhotoVerification.user_is_verified(user):
pass
attempt = SoftwareSecurePhotoVerification.active_for_user(request.user)
if not attempt:
......@@ -47,3 +49,62 @@ def final_verification(request):
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', 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 SoftwareSecureVerification.has_submitted_recent_request(user):
# Capture payment info
# Create an order
# Create a VerifiedCertificate order item
return HttpResponse.Redirect(reverse('payment'))
# 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'))
......@@ -47,7 +47,12 @@
$('#class_enroll_form').on('ajax:complete', function(event, xhr) {
if(xhr.status == 200) {
location.href = "${reverse('dashboard')}";
if (xhr.responseText == "") {
location.href = "${reverse('dashboard')}";
}
else {
location.href = xhr.responseText;
}
} else if (xhr.status == 403) {
location.href = "${reverse('register_user')}?course_id=${course.id}&enrollment_action=enroll";
} else {
......
......@@ -65,7 +65,10 @@ urlpatterns = ('', # nopep8
)
if settings.MITX_FEATURES.get("MULTIPLE_ENROLLMENT_ROLES"):
urlpatterns += (url(r'^verify_student/', include('verify_student.urls')),)
urlpatterns += (
url(r'^verify_student/', include('verify_student.urls')),
url(r'^course_modes/', include('course_modes.urls')),
)
js_info_dict = {
......
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