From 60b547273d1892462db87f76cdf6f97977dc24c5 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Sat, 21 Jul 2012 15:31:48 -0400 Subject: [PATCH 01/27] Registering now temporarily logs you in. A message is displayed on the dashboard, reminding you to activate your account. Logging in shows a reminder about activating. --- common/djangoapps/student/views.py | 29 ++- lms/templates/dashboard.html | 4 + lms/templates/login.html | 34 ---- lms/templates/login_modal.html | 4 +- lms/templates/marketing.html | 178 ------------------ .../registration/activate_account_notice.html | 3 + lms/templates/registration/reg_complete.html | 7 - lms/templates/signup_modal.html | 2 +- 8 files changed, 29 insertions(+), 232 deletions(-) delete mode 100644 lms/templates/login.html delete mode 100644 lms/templates/marketing.html create mode 100644 lms/templates/registration/activate_account_notice.html delete mode 100644 lms/templates/registration/reg_complete.html diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 9d2ea93049..003500b48e 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -83,7 +83,6 @@ def index(request): @login_required @ensure_csrf_cookie def dashboard(request): - csrf_token = csrf(request)['csrf_token'] user = request.user enrollments = CourseEnrollment.objects.filter(user=user) @@ -101,8 +100,13 @@ def dashboard(request): except ItemNotFoundError: log.error("User {0} enrolled in non-existant course {1}" .format(user.username, enrollment.course_id)) + + + message = "" + if not user.is_active: + message = render_to_string('registration/activate_account_notice.html', {'email': user.email}) - context = {'csrf': csrf_token, 'courses': courses} + context = {'courses': courses, 'message' : message} return render_to_response('dashboard.html', context) @@ -112,7 +116,7 @@ def login_user(request, error=""): ''' AJAX request to log in the user. ''' if 'email' not in request.POST or 'password' not in request.POST: return HttpResponse(json.dumps({'success': False, - 'error': 'Invalid login'})) # TODO: User error message + 'value': 'There was an error receiving your login information. Please email us.'})) # TODO: User error message email = request.POST['email'] password = request.POST['password'] @@ -121,14 +125,14 @@ def login_user(request, error=""): except User.DoesNotExist: log.warning("Login failed - Unknown user email: {0}".format(email)) return HttpResponse(json.dumps({'success': False, - 'error': 'Invalid login'})) # TODO: User error message + 'value': 'Email or password is incorrect.'})) # TODO: User error message username = user.username user = authenticate(username=username, password=password) if user is None: log.warning("Login failed - password for {0} is invalid".format(email)) return HttpResponse(json.dumps({'success': False, - 'error': 'Invalid login'})) + 'value': 'Email or password is incorrect.'})) if user is not None and user.is_active: try: @@ -147,7 +151,7 @@ def login_user(request, error=""): log.warning("Login failed - Account not active for user {0}".format(username)) return HttpResponse(json.dumps({'success':False, - 'error': 'Account not active. Check your e-mail.'})) + 'value': 'This account has not been activated. Please check your e-mail for the activation instructions.'})) @ensure_csrf_cookie def logout_user(request): @@ -275,10 +279,15 @@ def create_account(request, post_override=None): log.exception(sys.exc_info()) js['value'] = 'Could not send activation e-mail.' return HttpResponse(json.dumps(js)) - - js={'success': True, - 'value': render_to_string('registration/reg_complete.html', {'email': post_vars['email'], - 'csrf': csrf(request)['csrf_token']})} + + # Immediately after a user creates an account, we log them in. They are only + # logged in until they close the browser. They can't log in again until they click + # the activation link from the email. + login_user = authenticate(username=post_vars['username'], password = post_vars['password'] ) + login(request, login_user) + request.session.set_expiry(0) + + js={'success': True} return HttpResponse(json.dumps(js), mimetype="application/json") def create_random_account(create_account_function): diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html index a12b8c2f37..e7b295732f 100644 --- a/lms/templates/dashboard.html +++ b/lms/templates/dashboard.html @@ -9,6 +9,10 @@ <%block name="title">Dashboard
+ +
+ ${message} +
diff --git a/lms/templates/login.html b/lms/templates/login.html deleted file mode 100644 index 0ab5206073..0000000000 --- a/lms/templates/login.html +++ /dev/null @@ -1,34 +0,0 @@ - -
-
-

Log in to edX

- -
- - -
-
    -
  1. - - -
  2. - -
  3. - - -
  4. - -
  5. - -
  6. - -
- -
- - -
diff --git a/lms/templates/login_modal.html b/lms/templates/login_modal.html index 28d116c9de..0d23a477f6 100644 --- a/lms/templates/login_modal.html +++ b/lms/templates/login_modal.html @@ -44,9 +44,9 @@ location.href="${reverse('dashboard')}"; } else { if($('#login_error').length == 0) { - $('#login_form').prepend(''); + $('#login_form').prepend(''); } - $('#login_error').stop().css("display", "block"); + $('#login_error').html(json.value).stop().css("display", "block"); } }); })(this) diff --git a/lms/templates/marketing.html b/lms/templates/marketing.html deleted file mode 100644 index a0d53802b5..0000000000 --- a/lms/templates/marketing.html +++ /dev/null @@ -1,178 +0,0 @@ -<%! from django.core.urlresolvers import reverse %> -<%namespace name='static' file='static_content.html'/> - - - - <%block name="title">MITx: MIT's new online learning initiative</%block> - - MITx will offer a portfolio of MIT courses for free to a virtual community of learners around the world" /> - - MITx, online learning, MIT, online laboratory, education, learners, undergraduate, certificate" /> - - - - - - - - - - - - - - - - <%block name="headextra"/> - - - - - - - <%block name="header"> -
"> -
- <%block name="header_nav"> - - - - <%block name="header_text"> -
-

MITx

-

MIT’s new online learning initiative

-
- -
-
- - - ${self.body()} - <%block name="bodyextra"/> - - - - % if settings.COURSEWARE_ENABLED: -
<%include file="login.html" />
- % endif -
<%include file="password_reset_form.html" />
-
- - - - <%block name="js_extra"/> - - diff --git a/lms/templates/registration/activate_account_notice.html b/lms/templates/registration/activate_account_notice.html new file mode 100644 index 0000000000..ca051902b1 --- /dev/null +++ b/lms/templates/registration/activate_account_notice.html @@ -0,0 +1,3 @@ +

Thanks For Registering!

+

Your account is not active yet. An activation link has been sent to ${ email }, along with +instructions for activating your account.

diff --git a/lms/templates/registration/reg_complete.html b/lms/templates/registration/reg_complete.html deleted file mode 100644 index aea7e6df1a..0000000000 --- a/lms/templates/registration/reg_complete.html +++ /dev/null @@ -1,7 +0,0 @@ -
-

Thanks For Registering!

-
-
- -

Please check your email. An activation link has been sent to ${ email }, along with -instructions for activating your account.

diff --git a/lms/templates/signup_modal.html b/lms/templates/signup_modal.html index ee59f40396..acbba87eab 100644 --- a/lms/templates/signup_modal.html +++ b/lms/templates/signup_modal.html @@ -121,7 +121,7 @@ (function() { $(document).delegate('#enroll_form', 'ajax:success', function(data, json, xhr) { if(json.success) { - $('#enroll').html(json.value); + location.href="${reverse('dashboard')}"; } else { $('#enroll_error').html(json.value).stop().css("display", "block"); } From 2f4aba8042c0f54309fe8a99f19f57ff9b6508ba Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Sat, 21 Jul 2012 17:52:28 -0400 Subject: [PATCH 02/27] If a user is anonymous when they click the enroll button, they will automatically be enrolled in the course if they immediately log in our create an account. --- cms/templates/signup.html | 14 ++-- common/djangoapps/student/views.py | 65 +++++++++++++++++-- common/djangoapps/util/cache.py | 2 +- lms/djangoapps/courseware/views.py | 33 ---------- .../sass/sass_old/layout/_leanmodal.scss | 2 +- lms/templates/portal/course_about.html | 55 +++++++++++----- lms/templates/signup_modal.html | 12 ++-- lms/urls.py | 2 +- 8 files changed, 115 insertions(+), 70 deletions(-) diff --git a/cms/templates/signup.html b/cms/templates/signup.html index d3eedc8070..f22e3c7950 100644 --- a/cms/templates/signup.html +++ b/cms/templates/signup.html @@ -10,10 +10,10 @@
-
+
-
-
+ +
@@ -64,17 +64,17 @@ }); } - $('form#enroll_form').submit(function(e) { + $('form#register_form').submit(function(e) { e.preventDefault(); - var submit_data = $('#enroll_form').serialize(); + var submit_data = $('#register_form').serialize(); postJSON('/create_account', submit_data, function(json) { if(json.success) { - $('#enroll').html(json.value); + $('#register').html(json.value); } else { - $('#enroll_error').html(json.value).stop().css("background-color", "#933").animate({ backgroundColor: "#333"}, 2000); + $('#register_error').html(json.value).stop().css("background-color", "#933").animate({ backgroundColor: "#333"}, 2000); } } ); diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 003500b48e..1f7ea626a5 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -79,6 +79,9 @@ def index(request): return render_to_response('index.html', {'universities': universities, 'entries': entries}) +def course_from_id(id): + course_loc = CourseDescriptor.id_to_location(id) + return modulestore().get_item(course_loc) @login_required @ensure_csrf_cookie @@ -86,10 +89,6 @@ def dashboard(request): user = request.user enrollments = CourseEnrollment.objects.filter(user=user) - def course_from_id(id): - course_loc = CourseDescriptor.id_to_location(id) - return modulestore().get_item(course_loc) - # Build our courses list for the user, but ignore any courses that no longer # exist (because the course IDs have changed). Still, we don't delete those # enrollments, because it could have been a data push snafu. @@ -110,6 +109,45 @@ def dashboard(request): return render_to_response('dashboard.html', context) +@login_required +def change_enrollment_view(request): + return HttpResponse(json.dumps(change_enrollment(request))) + +def change_enrollment(request): + if request.method != "POST": + raise Http404 + + action = request.POST.get("enrollment_action" , "") + user = request.user + course_id = request.POST.get("course_id", None) + if course_id == None: + return HttpResponse(json.dumps({'success': False, 'error': 'There was an error receiving the course id.'})) + + if action == "enroll": + # Make sure the course exists + # We don't do this check on unenroll, or a bad course id can't be unenrolled from + try: + course = course_from_id(course_id) + except ItemNotFoundError: + log.error("User {0} tried to enroll in non-existant course {1}" + .format(user.username, enrollment.course_id)) + return {'success': False, 'error': 'The course requested does not exist.'} + + enrollment, created = CourseEnrollment.objects.get_or_create(user=user, course_id=course.id) + return {'success': True} + + elif action == "unenroll": + try: + enrollment = CourseEnrollment.objects.get(user=user, course_id=course_id) + enrollment.delete() + return {'success': True} + except CourseEnrollment.DoesNotExist: + return {'success': False, 'error': 'You are not enrolled for this course.'} + else: + return {'success': False, 'error': 'Invalid enrollment_action.'} + + return {'success': False, 'error': 'We weren\'t able to unenroll you. Please try again.'} + # Need different levels of logging @ensure_csrf_cookie def login_user(request, error=""): @@ -147,6 +185,16 @@ def login_user(request, error=""): log.exception(e) log.info("Login success - {0} ({1})".format(username, email)) + + if 'enrollment_action' in request.POST: + try: + enrollment_output = change_enrollment(request) + # There isn't really a way to display the results to the user, so we just log it + # We expect the enrollment to be a success, and will show up on the dashboard anyway + log.info("Attempted to automatically enroll after login. Results: {0}".format(enrollment_output)) + except Exception, e: + log.error("Exception automatically enrolling after login: {0}".format(str(e))) + return HttpResponse(json.dumps({'success':True})) log.warning("Login failed - Account not active for user {0}".format(username)) @@ -287,6 +335,15 @@ def create_account(request, post_override=None): login(request, login_user) request.session.set_expiry(0) + if 'enrollment_action' in request.POST: + try: + enrollment_output = change_enrollment(request) + # There isn't really a way to display the results to the user, so we just log it + # We expect the enrollment to be a success, and will show up on the dashboard anyway + log.info("Attempted to automatically enroll after login. Results: {0}".format(enrollment_output)) + except Exception, e: + log.error("Exception automatically enrolling after login: {0}".format(str(e))) + js={'success': True} return HttpResponse(json.dumps(js), mimetype="application/json") diff --git a/common/djangoapps/util/cache.py b/common/djangoapps/util/cache.py index e253b5b633..35715946a9 100644 --- a/common/djangoapps/util/cache.py +++ b/common/djangoapps/util/cache.py @@ -38,7 +38,7 @@ def cache_if_anonymous(view_func): @wraps(view_func) def _decorated(request, *args, **kwargs): - if not request.user.is_authenticated(): + if False and not request.user.is_authenticated(): #Use the cache cache_key = "cache_if_anonymous." + request.path response = cache.get(cache_key) diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py index 77ecc990c3..d5f24db9d0 100644 --- a/lms/djangoapps/courseware/views.py +++ b/lms/djangoapps/courseware/views.py @@ -269,39 +269,6 @@ def course_about(request, course_id): course = check_course(course_id, course_must_be_open=False) registered = registered_for_course(course, request.user) return render_to_response('portal/course_about.html', {'course': course, 'registered': registered}) - - -@login_required -def change_enrollment(request): - if request.method != "POST": - raise Http404 - - course_id = request.POST.get("course_id", None) - if course_id == None: - return HttpResponse(json.dumps({'success': False, 'error': 'There was an error receiving the course id.'})) - action = request.POST.get("enrollment_action" , "") - - user = request.user - - if action == "enroll": - # Make sure the course exists - # We don't do this check on unenroll, or a bad course id can't be unenrolled from - course = check_course(course_id, course_must_be_open=False) - - enrollment, created = CourseEnrollment.objects.get_or_create(user=user, course_id=course.id) - return HttpResponse(json.dumps({'success': True})) - - elif action == "unenroll": - try: - enrollment = CourseEnrollment.objects.get(user=user, course_id=course_id) - enrollment.delete() - return HttpResponse(json.dumps({'success': True})) - except CourseEnrollment.DoesNotExist: - return HttpResponse(json.dumps({'success': False, 'error': 'You are not enrolled for this course.'})) - else: - return HttpResponse(json.dumps({'success': False, 'error': 'Invalid enrollment_action.'})) - - return HttpResponse(json.dumps({'success': False, 'error': 'We weren\'t able to unenroll you. Please try again.'})) diff --git a/lms/static/sass/sass_old/layout/_leanmodal.scss b/lms/static/sass/sass_old/layout/_leanmodal.scss index 81639493ee..0c96e6524a 100644 --- a/lms/static/sass/sass_old/layout/_leanmodal.scss +++ b/lms/static/sass/sass_old/layout/_leanmodal.scss @@ -84,7 +84,7 @@ div.leanModal_box { form { text-align: left; - div#enroll_error, div#login_error, div#pwd_error { + div#register_error, div#login_error, div#pwd_error { $error-color: #333; background-color: $error-color; border: darken($error-color, 20%); diff --git a/lms/templates/portal/course_about.html b/lms/templates/portal/course_about.html index a6d0106138..730e3f89cf 100644 --- a/lms/templates/portal/course_about.html +++ b/lms/templates/portal/course_about.html @@ -25,7 +25,7 @@ %if registered: You are registered for this course (${course.number}). %else: - Register for ${course.number} + Register for ${course.number} %endif %else: Register for ${course.number} @@ -108,28 +108,49 @@
%if not registered: -
- - - +
+ +
+ + +
- + $(document).delegate('#class_enroll_form', 'ajax:success', function(data, json, xhr) { + if(json.success) { + location.href="${reverse('dashboard')}"; + } + }); + })(this) + + %else: + ## If the user is not authenticated, clicking the enroll button pops up the register + ## field. We also slip in the registration fields into the login/register fields so + ## the user is automatically registered after logging in / registering + + %endif %endif diff --git a/lms/templates/signup_modal.html b/lms/templates/signup_modal.html index acbba87eab..a707dfdd3a 100644 --- a/lms/templates/signup_modal.html +++ b/lms/templates/signup_modal.html @@ -7,16 +7,16 @@