From 442369505a17e1cba3ffa923ea0d262a6cfd12e2 Mon Sep 17 00:00:00 2001 From: Davidson Gomes Date: Wed, 7 May 2025 17:33:45 -0300 Subject: [PATCH] feat(user): add auto-verification option for user creation --- src/api/auth_routes.py | 2 +- src/services/client_service.py | 4 +++- src/services/user_service.py | 44 +++++++++++++++++++++------------- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/api/auth_routes.py b/src/api/auth_routes.py index 95856561..20bf04f7 100644 --- a/src/api/auth_routes.py +++ b/src/api/auth_routes.py @@ -52,7 +52,7 @@ async def register_user(user_data: UserCreate, db: Session = Depends(get_db)): Raises: HTTPException: If there is an error in registration """ - user, message = create_user(db, user_data, is_admin=False) + user, message = create_user(db, user_data, is_admin=False, auto_verify=False) if not user: logger.error(f"Error registering user: {message}") raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message) diff --git a/src/services/client_service.py b/src/services/client_service.py index 0045db6f..d012ccd6 100644 --- a/src/services/client_service.py +++ b/src/services/client_service.py @@ -124,7 +124,9 @@ def create_client_with_user( db.flush() # Get client ID without committing the transaction # Use client ID to create the associated user - user, message = create_user(db, user_data, is_admin=False, client_id=client.id) + user, message = create_user( + db, user_data, is_admin=False, client_id=client.id, auto_verify=True + ) if not user: # If there was an error creating the user, rollback diff --git a/src/services/user_service.py b/src/services/user_service.py index 4fe56514..1c0890a4 100644 --- a/src/services/user_service.py +++ b/src/services/user_service.py @@ -20,6 +20,7 @@ def create_user( user_data: UserCreate, is_admin: bool = False, client_id: Optional[uuid.UUID] = None, + auto_verify: bool = False, ) -> Tuple[Optional[User], str]: """ Creates a new user in the system @@ -29,6 +30,7 @@ def create_user( user_data: User data to be created is_admin: If the user is an administrator client_id: Associated client ID (optional, a new one will be created if not provided) + auto_verify: If True, user is created with email already verified and active Returns: Tuple[Optional[User], str]: Tuple with the created user (or None in case of error) and status message @@ -42,9 +44,12 @@ def create_user( ) return None, "Email already registered" - # Create verification token - verification_token = generate_token() - token_expiry = datetime.utcnow() + timedelta(hours=24) + # Create verification token if needed + verification_token = None + token_expiry = None + if not auto_verify: + verification_token = generate_token() + token_expiry = datetime.utcnow() + timedelta(hours=24) # Start transaction user = None @@ -64,25 +69,32 @@ def create_user( password_hash=get_password_hash(user_data.password), client_id=local_client_id, is_admin=is_admin, - is_active=False, # Inactive until email is verified - email_verified=False, + is_active=auto_verify, + email_verified=auto_verify, verification_token=verification_token, verification_token_expiry=token_expiry, ) db.add(user) db.commit() - # Send verification email - email_sent = send_verification_email(user.email, verification_token) - if not email_sent: - logger.error(f"Failed to send verification email to {user.email}") - # We don't do rollback here, we just log the error + # Send verification email if not auto-verified + if not auto_verify: + email_sent = send_verification_email(user.email, verification_token) + if not email_sent: + logger.error(f"Failed to send verification email to {user.email}") + # We don't do rollback here, we just log the error - logger.info(f"User created successfully: {user.email}") - return ( - user, - "User created successfully. Check your email to activate your account.", - ) + logger.info(f"User created successfully: {user.email}") + return ( + user, + "User created successfully. Check your email to activate your account.", + ) + else: + logger.info(f"User created and auto-verified: {user.email}") + return ( + user, + "User created successfully.", + ) except SQLAlchemyError as e: db.rollback() @@ -388,7 +400,7 @@ def create_admin_user(db: Session, user_data: UserCreate) -> Tuple[Optional[User Returns: Tuple[Optional[User], str]: Tuple with the created user (or None in case of error) and status message """ - return create_user(db, user_data, is_admin=True) + return create_user(db, user_data, is_admin=True, auto_verify=True) def deactivate_user(db: Session, user_id: uuid.UUID) -> Tuple[bool, str]: