Skip to content

Commit

Permalink
Rely on database unique constraints (#248)
Browse files Browse the repository at this point in the history
PR #245 updated the validators to check for duplicate usernames and
emails by running a query before posting the data. Let's rely on the
database indexes instead, which is more robust. This builds on top of
PR #245's tests to verify the functionality.
  • Loading branch information
jchristgit authored Feb 17, 2022
1 parent f069a1e commit bd27043
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 21 deletions.
1 change: 0 additions & 1 deletion src/authentication/basic_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def validate(self, data):
raise ValidationError("A required field was not found.")

self.validate_email(data["email"])
self.check_email_or_username_in_use(email=data["email"], username=data["username"])
if len(data["username"]) > 36:
raise ValidationError("username_too_long")

Expand Down
4 changes: 0 additions & 4 deletions src/authentication/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ def validate_email(self, email):
email_validator = EmailValidator()
email_validator(email)

def check_email_or_username_in_use(self, email=None, username=None):
if get_user_model().objects.filter(username__iexact=username) or get_user_model().objects.filter(email=email):
raise ValidationError("email_or_username_in_use")


class LoginProvider(Provider, abc.ABC): # pragma: no cover
type = "login"
Expand Down
8 changes: 8 additions & 0 deletions src/authentication/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ class RegistrationView(CreateAPIView):
def dispatch(self, *args, **kwargs):
return super(RegistrationView, self).dispatch(*args, **kwargs)

def create(self, request, *args, **kwargs):
try:
return super().create(request, *args, **kwargs)
except IntegrityError:
# If we need granularity to see whether email or username is in used here,
# check the constraint name that is returned.
return FormattedResponse(m="email_or_username_in_use", status=HTTP_400_BAD_REQUEST)


class LogoutView(APIView):
permission_classes = (permissions.IsAuthenticated & ~IsBot,)
Expand Down
30 changes: 14 additions & 16 deletions src/team/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,18 @@ class Meta:
fields = ["id", "is_visible", "name", "owner", "password"]
read_only_fields = ["id", "is_visible", "owner"]

def validate(self, attrs):
if Team.objects.filter(name__iexact=self.initial_data["name"]):
raise ValidationError("team_name_in_use")
return super(CreateTeamSerializer, self).validate(attrs)

def create(self, validated_data):
name = validated_data["name"]
password = validated_data["password"]
team = Team.objects.create(
name=name,
password=password,
owner=self.context["request"].user,
)
self.context["request"].user.team = team
self.context["request"].user.save()
team_create.send(sender=self.__class__, team=team)
return team
try:
name = validated_data["name"]
password = validated_data["password"]
team = Team.objects.create(
name=name,
password=password,
owner=self.context["request"].user,
)
self.context["request"].user.team = team
self.context["request"].user.save()
team_create.send(sender=self.__class__, team=team)
return team
except IntegrityError:
raise ValidationError("team_name_in_use")

0 comments on commit bd27043

Please sign in to comment.