Commit 1dfd3310 by David Baumgold

Refactor student views

Fix pylint/pep8 warnings, use JsonResponse instead of HttpResponse where useful,
put in TODOs to change HTTP status codes to be more accurate.
parent 01ac04ca
...@@ -23,6 +23,7 @@ from external_auth.models import ExternalAuthMap ...@@ -23,6 +23,7 @@ from external_auth.models import ExternalAuthMap
TEST_DATA_MIXED_MODULESTORE = mixed_store_config(settings.COMMON_TEST_DATA_ROOT, {}) TEST_DATA_MIXED_MODULESTORE = mixed_store_config(settings.COMMON_TEST_DATA_ROOT, {})
class LoginTest(TestCase): class LoginTest(TestCase):
''' '''
Test student.views.login_user() view Test student.views.login_user() view
...@@ -224,7 +225,11 @@ class ExternalAuthShibTest(ModuleStoreTestCase): ...@@ -224,7 +225,11 @@ class ExternalAuthShibTest(ModuleStoreTestCase):
""" """
response = self.client.post(reverse('login'), {'email': self.user_w_map.email, 'password': ''}) response = self.client.post(reverse('login'), {'email': self.user_w_map.email, 'password': ''})
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, json.dumps({'success': False, 'redirect': reverse('shib-login')})) obj = json.loads(response.content)
self.assertEqual(obj, {
'success': False,
'redirect': reverse('shib-login'),
})
@unittest.skipUnless(settings.FEATURES.get('AUTH_USE_SHIB'), "AUTH_USE_SHIB not set") @unittest.skipUnless(settings.FEATURES.get('AUTH_USE_SHIB'), "AUTH_USE_SHIB not set")
def test__get_course_enrollment_domain(self): def test__get_course_enrollment_domain(self):
......
...@@ -68,8 +68,11 @@ class ResetPasswordTests(TestCase): ...@@ -68,8 +68,11 @@ class ResetPasswordTests(TestCase):
bad_pwd_resp = password_reset(bad_pwd_req) bad_pwd_resp = password_reset(bad_pwd_req)
# If they've got an unusable password, we return a successful response code # If they've got an unusable password, we return a successful response code
self.assertEquals(bad_pwd_resp.status_code, 200) self.assertEquals(bad_pwd_resp.status_code, 200)
self.assertEquals(bad_pwd_resp.content, json.dumps({'success': True, obj = json.loads(bad_pwd_resp.content)
'value': "('registration/password_reset_done.html', [])"})) self.assertEquals(obj, {
'success': True,
'value': "('registration/password_reset_done.html', [])",
})
@patch('student.views.render_to_string', Mock(side_effect=mock_render_to_string, autospec=True)) @patch('student.views.render_to_string', Mock(side_effect=mock_render_to_string, autospec=True))
def test_nonexist_email_password_reset(self): def test_nonexist_email_password_reset(self):
...@@ -80,12 +83,19 @@ class ResetPasswordTests(TestCase): ...@@ -80,12 +83,19 @@ class ResetPasswordTests(TestCase):
# Note: even if the email is bad, we return a successful response code # Note: even if the email is bad, we return a successful response code
# This prevents someone potentially trying to "brute-force" find out which emails are and aren't registered with edX # This prevents someone potentially trying to "brute-force" find out which emails are and aren't registered with edX
self.assertEquals(bad_email_resp.status_code, 200) self.assertEquals(bad_email_resp.status_code, 200)
self.assertEquals(bad_email_resp.content, json.dumps({'success': True, obj = json.loads(bad_email_resp.content)
'value': "('registration/password_reset_done.html', [])"})) self.assertEquals(obj, {
'success': True,
@unittest.skipIf(settings.FEATURES.get('DISABLE_RESET_EMAIL_TEST', False), 'value': "('registration/password_reset_done.html', [])",
dedent("""Skipping Test because CMS has not provided necessary templates for password reset. })
If LMS tests print this message, that needs to be fixed."""))
@unittest.skipIf(
settings.FEATURES.get('DISABLE_RESET_EMAIL_TEST', False),
dedent("""
Skipping Test because CMS has not provided necessary templates for password reset.
If LMS tests print this message, that needs to be fixed.
""")
)
@patch('django.core.mail.send_mail') @patch('django.core.mail.send_mail')
@patch('student.views.render_to_string', Mock(side_effect=mock_render_to_string, autospec=True)) @patch('student.views.render_to_string', Mock(side_effect=mock_render_to_string, autospec=True))
def test_reset_password_email(self, send_email): def test_reset_password_email(self, send_email):
...@@ -94,9 +104,11 @@ class ResetPasswordTests(TestCase): ...@@ -94,9 +104,11 @@ class ResetPasswordTests(TestCase):
good_req = self.request_factory.post('/password_reset/', {'email': self.user.email}) good_req = self.request_factory.post('/password_reset/', {'email': self.user.email})
good_resp = password_reset(good_req) good_resp = password_reset(good_req)
self.assertEquals(good_resp.status_code, 200) self.assertEquals(good_resp.status_code, 200)
self.assertEquals(good_resp.content, obj = json.loads(good_resp.content)
json.dumps({'success': True, self.assertEquals(obj, {
'value': "('registration/password_reset_done.html', [])"})) 'success': True,
'value': "('registration/password_reset_done.html', [])",
})
((subject, msg, from_addr, to_addrs), sm_kwargs) = send_email.call_args ((subject, msg, from_addr, to_addrs), sm_kwargs) = send_email.call_args
self.assertIn("Password reset", subject) self.assertIn("Password reset", subject)
......
...@@ -4,9 +4,7 @@ Student Views ...@@ -4,9 +4,7 @@ Student Views
import datetime import datetime
import json import json
import logging import logging
import random
import re import re
import string # pylint: disable=W0402
import urllib import urllib
import uuid import uuid
import time import time
...@@ -18,13 +16,11 @@ from django.contrib.auth import logout, authenticate, login ...@@ -18,13 +16,11 @@ from django.contrib.auth import logout, authenticate, login
from django.contrib.auth.models import User, AnonymousUser from django.contrib.auth.models import User, AnonymousUser
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import password_reset_confirm from django.contrib.auth.views import password_reset_confirm
# from django.contrib.sessions.models import Session
from django.core.cache import cache from django.core.cache import cache
from django.core.context_processors import csrf from django.core.context_processors import csrf
from django.core.mail import send_mail from django.core.mail import send_mail
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.validators import validate_email, validate_slug, ValidationError from django.core.validators import validate_email, validate_slug, ValidationError
from django.core.exceptions import ObjectDoesNotExist
from django.db import IntegrityError, transaction from django.db import IntegrityError, transaction
from django.http import (HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, from django.http import (HttpResponse, HttpResponseBadRequest, HttpResponseForbidden,
Http404) Http404)
...@@ -33,7 +29,6 @@ from django_future.csrf import ensure_csrf_cookie ...@@ -33,7 +29,6 @@ from django_future.csrf import ensure_csrf_cookie
from django.utils.http import cookie_date, base36_to_int from django.utils.http import cookie_date, base36_to_int
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.decorators.http import require_POST, require_GET from django.views.decorators.http import require_POST, require_GET
from django.contrib.admin.views.decorators import staff_member_required
from ratelimitbackend.exceptions import RateLimitException from ratelimitbackend.exceptions import RateLimitException
...@@ -46,6 +41,7 @@ from student.models import ( ...@@ -46,6 +41,7 @@ from student.models import (
CourseEnrollmentAllowed, UserStanding, LoginFailures CourseEnrollmentAllowed, UserStanding, LoginFailures
) )
from student.forms import PasswordResetFormNoActive from student.forms import PasswordResetFormNoActive
from student.firebase_token_generator import create_token
from verify_student.models import SoftwareSecurePhotoVerification, MidcourseReverificationWindow from verify_student.models import SoftwareSecurePhotoVerification, MidcourseReverificationWindow
from certificates.models import CertificateStatuses, certificate_status_for_student from certificates.models import CertificateStatuses, certificate_status_for_student
...@@ -69,7 +65,6 @@ import shoppingcart ...@@ -69,7 +65,6 @@ import shoppingcart
import track.views import track.views
from dogapi import dog_stats_api from dogapi import dog_stats_api
from pytz import UTC
from util.json_request import JsonResponse from util.json_request import JsonResponse
...@@ -265,7 +260,6 @@ def get_course_enrollment_pairs(user, course_org_filter, org_filter_out_set): ...@@ -265,7 +260,6 @@ def get_course_enrollment_pairs(user, course_org_filter, org_filter_out_set):
.format(user.username, enrollment.course_id)) .format(user.username, enrollment.course_id))
def _cert_info(user, course, cert_status): def _cert_info(user, course, cert_status):
""" """
Implements the logic for cert_info -- split out for testing. Implements the logic for cert_info -- split out for testing.
...@@ -674,8 +668,10 @@ def accounts_login(request): ...@@ -674,8 +668,10 @@ def accounts_login(request):
def login_user(request, error=""): def login_user(request, error=""):
"""AJAX request to log in the user.""" """AJAX request to log in the user."""
if 'email' not in request.POST or 'password' not in request.POST: if 'email' not in request.POST or 'password' not in request.POST:
return HttpResponse(json.dumps({'success': False, return JsonResponse({
'value': _('There was an error receiving your login information. Please email us.')})) # TODO: User error message "success": False,
"value": _('There was an error receiving your login information. Please email us.'), # TODO: User error message
}) # TODO: this should be status code 400 # pylint: disable=fixme
email = request.POST['email'] email = request.POST['email']
password = request.POST['password'] password = request.POST['password']
...@@ -692,7 +688,10 @@ def login_user(request, error=""): ...@@ -692,7 +688,10 @@ def login_user(request, error=""):
try: try:
eamap = ExternalAuthMap.objects.get(user=user) eamap = ExternalAuthMap.objects.get(user=user)
if eamap.external_domain.startswith(external_auth.views.SHIBBOLETH_DOMAIN_PREFIX): if eamap.external_domain.startswith(external_auth.views.SHIBBOLETH_DOMAIN_PREFIX):
return HttpResponse(json.dumps({'success': False, 'redirect': reverse('shib-login')})) return JsonResponse({
"success": False,
"redirect": reverse('shib-login'),
}) # TODO: this should be status code 301 # pylint: disable=fixme
except ExternalAuthMap.DoesNotExist: except ExternalAuthMap.DoesNotExist:
# This is actually the common case, logging in user without external linked login # This is actually the common case, logging in user without external linked login
AUDIT_LOG.info("User %s w/o external auth attempting login", user) AUDIT_LOG.info("User %s w/o external auth attempting login", user)
...@@ -701,12 +700,10 @@ def login_user(request, error=""): ...@@ -701,12 +700,10 @@ def login_user(request, error=""):
user_found_by_email_lookup = user user_found_by_email_lookup = user
if user_found_by_email_lookup and LoginFailures.is_feature_enabled(): if user_found_by_email_lookup and LoginFailures.is_feature_enabled():
if LoginFailures.is_user_locked_out(user_found_by_email_lookup): if LoginFailures.is_user_locked_out(user_found_by_email_lookup):
return HttpResponse( return JsonResponse({
json.dumps({ "success": False,
'success': False, "value": _('This account has been temporarily locked due to excessive login failures. Try again later.'),
'value': _('This account has been temporarily locked due to excessive login failures. Try again later.') }) # TODO: this should be status code 429 # pylint: disable=fixme
})
)
# if the user doesn't exist, we want to set the username to an invalid # if the user doesn't exist, we want to set the username to an invalid
# username so that authentication is guaranteed to fail and we can take # username so that authentication is guaranteed to fail and we can take
...@@ -716,8 +713,10 @@ def login_user(request, error=""): ...@@ -716,8 +713,10 @@ def login_user(request, error=""):
user = authenticate(username=username, password=password, request=request) user = authenticate(username=username, password=password, request=request)
# this occurs when there are too many attempts from the same IP address # this occurs when there are too many attempts from the same IP address
except RateLimitException: except RateLimitException:
return HttpResponse(json.dumps({'success': False, return JsonResponse({
'value': _('Too many failed login attempts. Try again later.')})) "success": False,
"value": _('Too many failed login attempts. Try again later.'),
}) # TODO: this should be status code 429 # pylint: disable=fixme
if user is None: if user is None:
# tick the failed login counters if the user exists in the database # tick the failed login counters if the user exists in the database
if user_found_by_email_lookup and LoginFailures.is_feature_enabled(): if user_found_by_email_lookup and LoginFailures.is_feature_enabled():
...@@ -727,8 +726,10 @@ def login_user(request, error=""): ...@@ -727,8 +726,10 @@ def login_user(request, error=""):
# doesn't exist, and doesn't have a corresponding password # doesn't exist, and doesn't have a corresponding password
if username != "": if username != "":
AUDIT_LOG.warning(u"Login failed - password for {0} is invalid".format(email)) AUDIT_LOG.warning(u"Login failed - password for {0} is invalid".format(email))
return HttpResponse(json.dumps({'success': False, return JsonResponse({
'value': _('Email or password is incorrect.')})) "success": False,
"value": _('Email or password is incorrect.'),
}) # TODO: this should be status code 400 # pylint: disable=fixme
# successful login, clear failed login attempts counters, if applicable # successful login, clear failed login attempts counters, if applicable
if LoginFailures.is_feature_enabled(): if LoginFailures.is_feature_enabled():
...@@ -753,7 +754,10 @@ def login_user(request, error=""): ...@@ -753,7 +754,10 @@ def login_user(request, error=""):
redirect_url = try_change_enrollment(request) redirect_url = try_change_enrollment(request)
dog_stats_api.increment("common.student.successful_login") dog_stats_api.increment("common.student.successful_login")
response = HttpResponse(json.dumps({'success': True, 'redirect_url': redirect_url})) response = JsonResponse({
"success": True,
"redirect_url": redirect_url,
})
# set the login cookie for the edx marketing site # set the login cookie for the edx marketing site
# we want this cookie to be accessed via javascript # we want this cookie to be accessed via javascript
...@@ -767,12 +771,11 @@ def login_user(request, error=""): ...@@ -767,12 +771,11 @@ def login_user(request, error=""):
expires_time = time.time() + max_age expires_time = time.time() + max_age
expires = cookie_date(expires_time) expires = cookie_date(expires_time)
response.set_cookie(settings.EDXMKTG_COOKIE_NAME, response.set_cookie(
'true', max_age=max_age, settings.EDXMKTG_COOKIE_NAME, 'true', max_age=max_age,
expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN,
path='/', path='/', secure=None, httponly=None,
secure=None, )
httponly=None)
return response return response
...@@ -780,8 +783,10 @@ def login_user(request, error=""): ...@@ -780,8 +783,10 @@ def login_user(request, error=""):
reactivation_email_for_user(user) reactivation_email_for_user(user)
not_activated_msg = _("This account has not been activated. We have sent another activation message. Please check your e-mail for the activation instructions.") not_activated_msg = _("This account has not been activated. We have sent another activation message. Please check your e-mail for the activation instructions.")
return HttpResponse(json.dumps({'success': False, return JsonResponse({
'value': not_activated_msg})) "success": False,
"value": not_activated_msg,
}) # TODO: this should be status code 400 # pylint: disable=fixme
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -799,11 +804,13 @@ def logout_user(request): ...@@ -799,11 +804,13 @@ def logout_user(request):
else: else:
target = '/' target = '/'
response = redirect(target) response = redirect(target)
response.delete_cookie(settings.EDXMKTG_COOKIE_NAME, response.delete_cookie(
path='/', settings.EDXMKTG_COOKIE_NAME,
domain=settings.SESSION_COOKIE_DOMAIN) path='/', domain=settings.SESSION_COOKIE_DOMAIN,
)
return response return response
@require_GET @require_GET
@login_required @login_required
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -890,8 +897,10 @@ def change_setting(request): ...@@ -890,8 +897,10 @@ def change_setting(request):
up.location = request.POST['location'] up.location = request.POST['location']
up.save() up.save()
return HttpResponse(json.dumps({'success': True, return JsonResponse({
'location': up.location, })) "success": True,
"location": up.location,
})
def _do_create_account(post_vars): def _do_create_account(post_vars):
...@@ -1106,8 +1115,8 @@ def create_account(request, post_override=None): ...@@ -1106,8 +1115,8 @@ def create_account(request, post_override=None):
'-' * 80 + '\n\n' + message) '-' * 80 + '\n\n' + message)
send_mail(subject, message, from_address, [dest_addr], fail_silently=False) send_mail(subject, message, from_address, [dest_addr], fail_silently=False)
else: else:
_res = user.email_user(subject, message, from_address) user.email_user(subject, message, from_address)
except: except Exception: # pylint: disable=broad-except
log.warning('Unable to send activation email to user', exc_info=True) log.warning('Unable to send activation email to user', exc_info=True)
js['value'] = _('Could not send activation e-mail.') js['value'] = _('Could not send activation e-mail.')
# What is the correct status code to use here? I think it's 500, because # What is the correct status code to use here? I think it's 500, because
...@@ -1298,8 +1307,10 @@ def password_reset(request): ...@@ -1298,8 +1307,10 @@ def password_reset(request):
from_email=settings.DEFAULT_FROM_EMAIL, from_email=settings.DEFAULT_FROM_EMAIL,
request=request, request=request,
domain_override=request.get_host()) domain_override=request.get_host())
return HttpResponse(json.dumps({'success': True, return JsonResponse({
'value': render_to_string('registration/password_reset_done.html', {})})) 'success': True,
'value': render_to_string('registration/password_reset_done.html', {}),
})
def password_reset_confirm_wrapper( def password_reset_confirm_wrapper(
...@@ -1330,23 +1341,30 @@ def reactivation_email_for_user(user): ...@@ -1330,23 +1341,30 @@ def reactivation_email_for_user(user):
try: try:
reg = Registration.objects.get(user=user) reg = Registration.objects.get(user=user)
except Registration.DoesNotExist: except Registration.DoesNotExist:
return HttpResponse(json.dumps({'success': False, return JsonResponse({
'error': _('No inactive user with this e-mail exists')})) "success": False,
"error": _('No inactive user with this e-mail exists'),
}) # TODO: this should be status code 400 # pylint: disable=fixme
d = {'name': user.profile.name, context = {
'key': reg.activation_key} 'name': user.profile.name,
'key': reg.activation_key,
}
subject = render_to_string('emails/activation_email_subject.txt', d) subject = render_to_string('emails/activation_email_subject.txt', context)
subject = ''.join(subject.splitlines()) subject = ''.join(subject.splitlines())
message = render_to_string('emails/activation_email.txt', d) message = render_to_string('emails/activation_email.txt', context)
try: try:
_res = user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL) user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
except: except Exception: # pylint: disable=broad-except
log.warning('Unable to send reactivation email', exc_info=True) log.warning('Unable to send reactivation email', exc_info=True)
return HttpResponse(json.dumps({'success': False, 'error': _('Unable to send reactivation email')})) return JsonResponse({
"success": False,
"error": _('Unable to send reactivation email')
}) # TODO: this should be status code 500 # pylint: disable=fixme
return HttpResponse(json.dumps({'success': True})) return JsonResponse({"success": True})
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -1360,20 +1378,26 @@ def change_email_request(request): ...@@ -1360,20 +1378,26 @@ def change_email_request(request):
user = request.user user = request.user
if not user.check_password(request.POST['password']): if not user.check_password(request.POST['password']):
return HttpResponse(json.dumps({'success': False, return JsonResponse({
'error': _('Invalid password')})) "success": False,
"error": _('Invalid password'),
}) # TODO: this should be status code 400 # pylint: disable=fixme
new_email = request.POST['new_email'] new_email = request.POST['new_email']
try: try:
validate_email(new_email) validate_email(new_email)
except ValidationError: except ValidationError:
return HttpResponse(json.dumps({'success': False, return JsonResponse({
'error': _('Valid e-mail address required.')})) "success": False,
"error": _('Valid e-mail address required.'),
}) # TODO: this should be status code 400 # pylint: disable=fixme
if User.objects.filter(email=new_email).count() != 0: if User.objects.filter(email=new_email).count() != 0:
## CRITICAL TODO: Handle case sensitivity for e-mails ## CRITICAL TODO: Handle case sensitivity for e-mails
return HttpResponse(json.dumps({'success': False, return JsonResponse({
'error': _('An account with this e-mail already exists.')})) "success": False,
"error": _('An account with this e-mail already exists.'),
}) # TODO: this should be status code 400 # pylint: disable=fixme
pec_list = PendingEmailChange.objects.filter(user=request.user) pec_list = PendingEmailChange.objects.filter(user=request.user)
if len(pec_list) == 0: if len(pec_list) == 0:
...@@ -1388,8 +1412,10 @@ def change_email_request(request): ...@@ -1388,8 +1412,10 @@ def change_email_request(request):
if pec.new_email == user.email: if pec.new_email == user.email:
pec.delete() pec.delete()
return HttpResponse(json.dumps({'success': False, return JsonResponse({
'error': _('Old email is the same as the new email.')})) "success": False,
"error": _('Old email is the same as the new email.'),
}) # TODO: this should be status code 400 # pylint: disable=fixme
context = { context = {
'key': pec.activation_key, 'key': pec.activation_key,
...@@ -1407,9 +1433,9 @@ def change_email_request(request): ...@@ -1407,9 +1433,9 @@ def change_email_request(request):
settings.DEFAULT_FROM_EMAIL settings.DEFAULT_FROM_EMAIL
) )
_res = send_mail(subject, message, from_address, [pec.new_email]) send_mail(subject, message, from_address, [pec.new_email])
return HttpResponse(json.dumps({'success': True})) return JsonResponse({"success": True})
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -1491,14 +1517,17 @@ def change_name_request(request): ...@@ -1491,14 +1517,17 @@ def change_name_request(request):
pnc.new_name = request.POST['new_name'] pnc.new_name = request.POST['new_name']
pnc.rationale = request.POST['rationale'] pnc.rationale = request.POST['rationale']
if len(pnc.new_name) < 2: if len(pnc.new_name) < 2:
return HttpResponse(json.dumps({'success': False, 'error': _('Name required')})) return JsonResponse({
"success": False,
"error": _('Name required'),
}) # TODO: this should be status code 400 # pylint: disable=fixme
pnc.save() pnc.save()
# The following automatically accepts name change requests. Remove this to # The following automatically accepts name change requests. Remove this to
# go back to the old system where it gets queued up for admin approval. # go back to the old system where it gets queued up for admin approval.
accept_name_change_by_id(pnc.id) accept_name_change_by_id(pnc.id)
return HttpResponse(json.dumps({'success': True})) return JsonResponse({"success": True})
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -1507,14 +1536,19 @@ def pending_name_changes(request): ...@@ -1507,14 +1536,19 @@ def pending_name_changes(request):
if not request.user.is_staff: if not request.user.is_staff:
raise Http404 raise Http404
changes = list(PendingNameChange.objects.all()) students = []
js = {'students': [{'new_name': c.new_name, for change in PendingNameChange.objects.all():
'rationale': c.rationale, profile = UserProfile.objects.get(user=change.user)
'old_name': UserProfile.objects.get(user=c.user).name, students.append({
'email': c.user.email, "new_name": change.new_name,
'uid': c.user.id, "rationale": change.rationale,
'cid': c.id} for c in changes]} "old_name": profile.name,
return render_to_response('name_changes.html', js) "email": change.user.email,
"uid": change.user.id,
"cid": change.id,
})
return render_to_response("name_changes.html", {"students": students})
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -1526,17 +1560,23 @@ def reject_name_change(request): ...@@ -1526,17 +1560,23 @@ def reject_name_change(request):
try: try:
pnc = PendingNameChange.objects.get(id=int(request.POST['id'])) pnc = PendingNameChange.objects.get(id=int(request.POST['id']))
except PendingNameChange.DoesNotExist: except PendingNameChange.DoesNotExist:
return HttpResponse(json.dumps({'success': False, 'error': _('Invalid ID')})) return JsonResponse({
"success": False,
"error": _('Invalid ID'),
}) # TODO: this should be status code 400 # pylint: disable=fixme
pnc.delete() pnc.delete()
return HttpResponse(json.dumps({'success': True})) return JsonResponse({"success": True})
def accept_name_change_by_id(id): def accept_name_change_by_id(id):
try: try:
pnc = PendingNameChange.objects.get(id=id) pnc = PendingNameChange.objects.get(id=id)
except PendingNameChange.DoesNotExist: except PendingNameChange.DoesNotExist:
return HttpResponse(json.dumps({'success': False, 'error': _('Invalid ID')})) return JsonResponse({
"success": False,
"error": _('Invalid ID'),
}) # TODO: this should be status code 400 # pylint: disable=fixme
u = pnc.user u = pnc.user
up = UserProfile.objects.get(user=u) up = UserProfile.objects.get(user=u)
...@@ -1552,7 +1592,7 @@ def accept_name_change_by_id(id): ...@@ -1552,7 +1592,7 @@ def accept_name_change_by_id(id):
up.save() up.save()
pnc.delete() pnc.delete()
return HttpResponse(json.dumps({'success': True})) return JsonResponse({"success": True})
@ensure_csrf_cookie @ensure_csrf_cookie
...@@ -1589,9 +1629,7 @@ def change_email_settings(request): ...@@ -1589,9 +1629,7 @@ def change_email_settings(request):
log.info(u"User {0} ({1}) opted out of receiving emails from course {2}".format(user.username, user.email, course_id)) log.info(u"User {0} ({1}) opted out of receiving emails from course {2}".format(user.username, user.email, course_id))
track.views.server_track(request, "change-email-settings", {"receive_emails": "no", "course": course_id}, page='dashboard') track.views.server_track(request, "change-email-settings", {"receive_emails": "no", "course": course_id}, page='dashboard')
return HttpResponse(json.dumps({'success': True})) return JsonResponse({"success": True})
from student.firebase_token_generator import create_token
@login_required @login_required
......
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