Skip to content

Commit

Permalink
chore: Add username and password validation to signup endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
fcarboni committed Aug 9, 2024
1 parent 295388a commit 0a3f9bb
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
41 changes: 40 additions & 1 deletion app/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import os
import re
import time

from fastapi import FastAPI, Form, Request, Depends, HTTPException
Expand Down Expand Up @@ -92,20 +93,56 @@ async def signup_page(request: Request):
return templates.TemplateResponse(request=request, name="signup.html")


def validate_username(username: str):
if len(username) < 3 or len(username) > 30:
raise ValueError("El nombre de usuario debe tener entre 3 y 30 caracteres.")
if not re.match(r'^[\w.]+$', username):
raise ValueError("El nombre de usuario solo puede contener letras, números, guiones bajos y puntos.")

def validate_password(password: str):
if len(password) < 8:
raise ValueError("La contraseña debe tener al menos 8 caracteres.")
if not re.search(r"[A-Z]", password):
raise ValueError("La contraseña debe contener al menos una letra mayúscula.")
if not re.search(r"[a-z]", password):
raise ValueError("La contraseña debe contener al menos una letra minúscula.")
if not re.search(r"[0-9]", password):
raise ValueError("La contraseña debe contener al menos un número.")
if not re.search(r"[!@#$%^&*(),.?\":{}|<>]", password):
raise ValueError("La contraseña debe contener al menos un carácter especial.")
if re.search(r"(.)\1\1\1", password):
raise ValueError("La contraseña no debe contener más de tres caracteres repetidos consecutivos.")
if re.search(r"(012|123|234|345|456|567|678|789|890|qwerty|asdf)", password.lower()):
raise ValueError("La contraseña no debe contener secuencias de números o teclas comunes.")

common_passwords = ["123456", "password", "12345678", "qwerty", "abc123"]
if password.lower() in common_passwords:
raise ValueError("La contraseña es demasiado común. Por favor, elija una diferente.")


@app.post("/signup")
async def signup(
request: Request,
username: str = Form(...),
password: str = Form(...),
db: Session = Depends(get_db),
):
username = username.strip().lower()

# Validar nombre de usuario y contraseña
try:
validate_username(username)
validate_password(password)
except ValueError as e:
return templates.TemplateResponse("signup.html", {"request": request, "error": str(e)})

try:
user = execute_with_retries(query_user, db, username)
except OperationalError:
return HTMLResponse("Error al acceder a la base de datos. Inténtalo de nuevo más tarde.", status_code=500)

if user:
return templates.TemplateResponse(request=request, name="signup.html", context={"error": "Usuario ya resgistrado"})
return templates.TemplateResponse(request=request, name="signup.html", context={"error": "Usuario ya registrado"})

new_user = User(username=username)
new_user.set_password(password)
Expand All @@ -131,6 +168,8 @@ async def login(
password: str = Form(...),
db: Session = Depends(get_db),
):
username = username.strip().lower()

try:
user = execute_with_retries(query_user, db, username)
except OperationalError:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def test_post_signup(db_session):
response = client.post("/signup", data={"username": "newuser1", "password": "newpassword"}, follow_redirects=False)
assert response.status_code == 200
assert response.template.name == "signup.html"
assert "Usuario ya resgistrado" in response.text
assert "Usuario ya registrado" in response.text

def test_post_login(db_session):
# Empty the database
Expand Down

0 comments on commit 0a3f9bb

Please sign in to comment.