Added check for duplicate email and username
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
"""Python API for user accounts.
|
||||
|
||||
|
||||
Account information includes a student's username, password, and email
|
||||
address, but does NOT include user profile information (i.e., demographic
|
||||
information and preferences).
|
||||
|
||||
"""
|
||||
from django.db import transaction, IntegrityError
|
||||
from django.db.models import Q
|
||||
from django.core.validators import validate_email, validate_slug, ValidationError
|
||||
from user_api.models import User, UserProfile, Registration, PendingEmailChange
|
||||
from user_api.helpers import intercept_errors
|
||||
@@ -138,6 +140,34 @@ def create_account(username, password, email):
|
||||
return registration.activation_key
|
||||
|
||||
|
||||
def check_account_exists(username=None, email=None):
|
||||
"""Check whether an account with a particular username or email already exists.
|
||||
|
||||
Keyword Arguments:
|
||||
username (unicode)
|
||||
email (unicode)
|
||||
|
||||
Returns:
|
||||
list of conflicting fields
|
||||
|
||||
Example Usage:
|
||||
>>> account_api.check_account_exists(username="bob")
|
||||
[]
|
||||
>>> account_api.check_account_exists(username="ted", email="ted@example.com")
|
||||
["email", "username"]
|
||||
|
||||
"""
|
||||
conflicts = []
|
||||
|
||||
if email is not None and User.objects.filter(email=email).exists():
|
||||
conflicts.append("email")
|
||||
|
||||
if username is not None and User.objects.filter(username=username).exists():
|
||||
conflicts.append("username")
|
||||
|
||||
return conflicts
|
||||
|
||||
|
||||
@intercept_errors(AccountInternalError, ignore_errors=[AccountRequestError])
|
||||
def account_info(username):
|
||||
"""Retrieve information about a user's account.
|
||||
|
||||
@@ -1037,7 +1037,6 @@ class RegistrationViewTest(ApiTestCase):
|
||||
response = self.client.post(self.url, data)
|
||||
self.assertHttpBadRequest(response)
|
||||
|
||||
|
||||
@override_settings(REGISTRATION_EXTRA_FIELDS={"country": "required"})
|
||||
@ddt.data("email", "name", "username", "password", "country")
|
||||
def test_register_missing_required_field(self, missing_field):
|
||||
@@ -1055,21 +1054,65 @@ class RegistrationViewTest(ApiTestCase):
|
||||
response = self.client.post(self.url, data)
|
||||
self.assertHttpBadRequest(response)
|
||||
|
||||
def test_register_already_authenticated(self):
|
||||
data = {
|
||||
def test_register_duplicate_email(self):
|
||||
# Register the first user
|
||||
response = self.client.post(self.url, {
|
||||
"email": self.EMAIL,
|
||||
"name": self.NAME,
|
||||
"username": self.USERNAME,
|
||||
"password": self.PASSWORD,
|
||||
}
|
||||
|
||||
# Register once, which will also log us in
|
||||
response = self.client.post(self.url, data)
|
||||
})
|
||||
self.assertHttpOK(response)
|
||||
|
||||
# Try to register again
|
||||
response = self.client.post(self.url, data)
|
||||
self.assertHttpBadRequest(response)
|
||||
# Try to create a second user with the same email address
|
||||
response = self.client.post(self.url, {
|
||||
"email": self.EMAIL,
|
||||
"name": "Someone Else",
|
||||
"username": "someone_else",
|
||||
"password": self.PASSWORD,
|
||||
})
|
||||
self.assertEqual(response.status_code, 409)
|
||||
self.assertEqual(response.content, json.dumps(["email"]))
|
||||
|
||||
def test_register_duplicate_username(self):
|
||||
# Register the first user
|
||||
response = self.client.post(self.url, {
|
||||
"email": self.EMAIL,
|
||||
"name": self.NAME,
|
||||
"username": self.USERNAME,
|
||||
"password": self.PASSWORD,
|
||||
})
|
||||
self.assertHttpOK(response)
|
||||
|
||||
# Try to create a second user with the same username
|
||||
response = self.client.post(self.url, {
|
||||
"email": "someone+else@example.com",
|
||||
"name": "Someone Else",
|
||||
"username": self.USERNAME,
|
||||
"password": self.PASSWORD,
|
||||
})
|
||||
self.assertEqual(response.status_code, 409)
|
||||
self.assertEqual(response.content, json.dumps(["username"]))
|
||||
|
||||
def test_register_duplicate_username_and_email(self):
|
||||
# Register the first user
|
||||
response = self.client.post(self.url, {
|
||||
"email": self.EMAIL,
|
||||
"name": self.NAME,
|
||||
"username": self.USERNAME,
|
||||
"password": self.PASSWORD,
|
||||
})
|
||||
self.assertHttpOK(response)
|
||||
|
||||
# Try to create a second user with the same username
|
||||
response = self.client.post(self.url, {
|
||||
"email": self.EMAIL,
|
||||
"name": "Someone Else",
|
||||
"username": self.USERNAME,
|
||||
"password": self.PASSWORD,
|
||||
})
|
||||
self.assertEqual(response.status_code, 409)
|
||||
self.assertEqual(response.content, json.dumps(["email", "username"]))
|
||||
|
||||
def _assert_reg_field(self, extra_fields_setting, expected_field):
|
||||
"""Retrieve the registration form description from the server and
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""HTTP end-points for the User API. """
|
||||
import json
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
@@ -177,6 +178,7 @@ class RegistrationView(APIView):
|
||||
return HttpResponse(form_desc.to_json(), content_type="application/json")
|
||||
|
||||
@method_decorator(ensure_csrf_cookie)
|
||||
@method_decorator(require_post_params(DEFAULT_FIELDS))
|
||||
def post(self, request):
|
||||
"""Create the user's account.
|
||||
|
||||
@@ -198,6 +200,18 @@ class RegistrationView(APIView):
|
||||
request.POST["honor_code"] = "true"
|
||||
request.POST["terms_of_service"] = "true"
|
||||
|
||||
# Handle duplicate username/email
|
||||
conflicts = account_api.check_account_exists(
|
||||
username=request.POST.get('username'),
|
||||
email=request.POST.get('email')
|
||||
)
|
||||
if conflicts:
|
||||
return HttpResponse(
|
||||
status=409,
|
||||
content=json.dumps(conflicts),
|
||||
content_type="application/json"
|
||||
)
|
||||
|
||||
# For the initial implementation, shim the existing login view
|
||||
# from the student Django app.
|
||||
from student.views import create_account
|
||||
|
||||
Reference in New Issue
Block a user