From c3c3251f02daf96249a118dbdf33beea9ff6c650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Morel?= Date: Fri, 7 Oct 2022 10:59:51 +0200 Subject: [PATCH] feat: improved user creation validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémy Morel --- CHANGELOG.md | 1 + backend/users/views/user.py | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 606d8138c..0c677b89a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Add compute task category unknown value +- Improved validation at user creation. ### Fixed diff --git a/backend/users/views/user.py b/backend/users/views/user.py index c529692cd..78a355bfa 100644 --- a/backend/users/views/user.py +++ b/backend/users/views/user.py @@ -1,4 +1,5 @@ import datetime +from urllib.parse import unquote import jwt from django.conf import settings @@ -21,6 +22,7 @@ from rest_framework.mixins import CreateModelMixin from rest_framework.viewsets import GenericViewSet +from api.errors import BadRequestError from api.views.filters_utils import MatchFilter from api.views.utils import ApiResponse from api.views.utils import get_channel_name @@ -40,12 +42,20 @@ def _validate_channel(name): def _validate_password(password, user): + if not password: + raise ValidationError("Missing password") try: validate_password(password, user) except djangoValidationError as err: raise ValidationError(err.error_list) +def _validate_username(username): + user_model = get_user_model() + if user_model.objects.filter(username=username).exists(): + raise BadRequestError("Username already exists") + + def _validate_role(role): try: role = UserChannel.Role[role] @@ -124,6 +134,7 @@ def create(self, request, *args, **kwargs): role = request.data.get("role") _validate_channel(channel) + _validate_username(username) _validate_password(password, self.user_model(username=username)) channel_data = {"channel_name": channel} @@ -173,7 +184,7 @@ def set_password(self, request, *args, **kwargs): token = request.data.get("token") new_password = request.data.get("password") - username = kwargs.get("username") + username = unquote(kwargs.get("username")) instance = self.user_model.objects.get(username=username) secret = _xor_secrets(instance.password, force_str(settings.SECRET_KEY)) @@ -193,7 +204,7 @@ def verify_token(self, request, *args, **kwargs): """Return 200 if reset token is valid 401 otherwise. Accepts unauthenticated request""" token = request.query_params.get("token", None) - username = kwargs.get("username") + username = unquote(kwargs.get("username")) instance = self.user_model.objects.get(username=username) secret = _xor_secrets(instance.password, force_str(settings.SECRET_KEY))