From 0761ac56d83d790c3d13a200fdd79fe54a8fea44 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 9 May 2026 18:11:52 +0000 Subject: [PATCH] fix: add specific error messages to user registration RegisterUser now returns (user, error_message) tuple instead of just None on failure. Error messages cover: missing fields, password requirements, duplicate email, database errors, and creation failures. The register view now returns descriptive JSON error messages instead of empty responses. Also handles JSON decode errors and mail sending failures gracefully. Closes #34 --- Backend/BackendApp/api/models.py | 93 +++++++++++++++----------------- Backend/BackendApp/api/views.py | 82 +++++++++++++++------------- 2 files changed, 86 insertions(+), 89 deletions(-) diff --git a/Backend/BackendApp/api/models.py b/Backend/BackendApp/api/models.py index 48633ed..bdf8729 100644 --- a/Backend/BackendApp/api/models.py +++ b/Backend/BackendApp/api/models.py @@ -23,65 +23,61 @@ class Users(models.Model): verified = models.BooleanField() logintrys = models.IntegerField(default=0) + @staticmethod def RegisterUser(first_name,last_name,email,password): + """Register a new user. Returns (user, None) on success, (None, error_message) on failure.""" + # Validate required fields + if not all([first_name, last_name, email, password]): + return None, "Missing required fields: firstname, lastname, email, or password" # Password validation validation = pwd.checkPwdConstraints(password) - if (validation != 1): - print("Password is not valid") - return None + if validation == 0: + return None, "Password must be at least 8 characters long" + if validation == -1: + return None, "Password must contain a letter, a digit, and a special character" - #1. Set UserID - #Check if email already exists + # Check if email already exists double = False - UserID = None try: - CheckForDoubleUser = Users.objects.raw("Select * From api_users Where email = "+ "'" + email + "'") + CheckForDoubleUser = Users.objects.raw( + "SELECT * FROM api_users WHERE email = %s", [email] + ) for p in CheckForDoubleUser: double = True - except: - double = False - print("double " + str(double)) - try: - if (double == False): - #Get current highest iduser - query = "Select iduser From api_users Where iduser = (Select Max(iduser) From api_users)" - user = Users.objects.raw(query) + except Exception: + return None, "Database error while checking for existing email" - #Chech if the new user is the first then id = 1 else max id + 1 - test = False - for p in user: - test = True - if (p.iduser != None): - UserID = p.iduser - UserID = UserID + 1 - elif (p.iduser == None): - UserID = 1 - print("test " + str(test)) - - except: - print("Unexpected error ocurred!") + if double: + return None, "A user with this email address already exists" + + # Get next user ID + UserID = 1 + try: + query = "SELECT iduser FROM api_users WHERE iduser = (SELECT MAX(iduser) FROM api_users)" + user = Users.objects.raw(query) + for p in user: + if p.iduser is not None: + UserID = p.iduser + 1 + except Exception: + return None, "Database error while generating user ID" - #2. Password hashing - if (password != None): + # Password hashing + if password is not None: Password_hash, Salt = pwd.PasswordHashing(password) + else: + return None, "Password is required" - #3. Set current date + # Set current date CreatedAt = date.today() - #4. Set RoleID = 3 aka User - RoleID = 3 - - #5. Set user-validation validation set by Link to true + # Set defaults + RoleID = 3 Kilometers = 0 VerifiedUser = False - NewUser = None - #Creat new DB entry if values are filled - print("UserID") - print(UserID) - if (UserID != None and first_name != None and last_name != None and email != None and Password_hash != None and Salt != None and CreatedAt != None and RoleID != None): - print("Creating new User with ID: " + str(UserID)) + # Create new DB entry + try: NewUser = Users.objects.create( iduser=UserID, firstname=first_name, @@ -92,16 +88,11 @@ def RegisterUser(first_name,last_name,email,password): createdat=CreatedAt, roleid=RoleID, verified=VerifiedUser, - kilometers=Kilometers) - return NewUser - # try: - # except: - # print("Error, user can't be added to DB!") - else: - print("Not all requirements are fulfilled to create a user") - - # if the process was denied, no NewUser is created - return None + kilometers=Kilometers + ) + return NewUser, None + except Exception as e: + return None, f"Failed to create user in database: {str(e)}" # end def diff --git a/Backend/BackendApp/api/views.py b/Backend/BackendApp/api/views.py index 126b97d..bd53083 100644 --- a/Backend/BackendApp/api/views.py +++ b/Backend/BackendApp/api/views.py @@ -34,48 +34,54 @@ class CreateUserView(generics.CreateAPIView): serializer_class = UserSerializer permission_classes = [AllowAny] -#Handels the registration page +# Handles the registration page @csrf_protect def register(request): - if request.method == 'POST': - #Read data + if request.method != 'POST': + return JsonResponse({"message": "Only POST requests are allowed"}, status=405) + + try: data = json.loads(request.body) - first_name = data.get("firstname") - last_name = data.get("lastname") - email = data.get("email") - password = data.get("password") - domain = data.get("domain") - - # try: - #Erstelle neuen Benutzer auf der Datenbank - # Send Verification Mail - - print("first_name,last_name,email,password") - print(first_name,last_name,email,password) - NewUser = Users.RegisterUser(first_name, last_name, email,password) - # Check if the User is created - if NewUser == None: - print("Process interupted. Try Again!") - # return HttpResponse(content="User couldn't be created!", status=200) - return JsonResponse(data={}, status=400) - - - mail_handle.sendUserVerifyMail(request=request, UserID=int(NewUser.iduser), frontendDomain=domain) - # except : - # #Bei Fehler return error an Frontend - # print("Error occured: ") - # return JsonResponse(data={"userid": None, "UserIsAuth": False,'message': 'Registrierung nicht erfolgreich'}, status=401) - - #Convert Userid - NewUserID = int(NewUser.iduser) + except json.JSONDecodeError: + return JsonResponse({"message": "Invalid JSON in request body"}, status=400) - User_Data = { - "userid": NewUserID, - "UserIsAuth": False, - "message": 'Registrierung erfolgreich' - } - - return JsonResponse(data=User_Data, status=200) + first_name = data.get("firstname") + last_name = data.get("lastname") + email = data.get("email") + password = data.get("password") + domain = data.get("domain") + + try: + NewUser, error = Users.RegisterUser(first_name, last_name, email, password) + except Exception as e: + return JsonResponse( + {"message": f"Registration failed: {str(e)}", "UserIsAuth": False}, + status=500 + ) + + if error: + return JsonResponse( + {"message": error, "UserIsAuth": False}, + status=400 + ) + + try: + mail_handle.sendUserVerifyMail( + request=request, UserID=int(NewUser.iduser), frontendDomain=domain + ) + except Exception: + # User was created but verification email failed — still return success + return JsonResponse({ + "userid": int(NewUser.iduser), + "UserIsAuth": False, + "message": "Registration successful, but verification email could not be sent. Please contact support." + }, status=200) + + return JsonResponse({ + "userid": int(NewUser.iduser), + "UserIsAuth": False, + "message": "Registration successful. Please check your email to verify your account." + }, status=200) #Login user @csrf_protect