feat(auth): enhance user authentication with detailed error handling
This commit is contained in:
parent
ebbbf62df5
commit
b53746dd1f
@ -191,14 +191,36 @@ async def login_for_access_token(form_data: UserLogin, db: Session = Depends(get
|
|||||||
Raises:
|
Raises:
|
||||||
HTTPException: If credentials are invalid
|
HTTPException: If credentials are invalid
|
||||||
"""
|
"""
|
||||||
user = authenticate_user(db, form_data.email, form_data.password)
|
user, reason = authenticate_user(db, form_data.email, form_data.password)
|
||||||
if not user:
|
if not user:
|
||||||
logger.warning(f"Login attempt with invalid credentials: {form_data.email}")
|
if reason == "user_not_found" or reason == "invalid_password":
|
||||||
raise HTTPException(
|
logger.warning(f"Login attempt with invalid credentials: {form_data.email}")
|
||||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
raise HTTPException(
|
||||||
detail="Invalid email or password",
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
headers={"WWW-Authenticate": "Bearer"},
|
detail="Invalid email or password",
|
||||||
)
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
|
)
|
||||||
|
elif reason == "email_not_verified":
|
||||||
|
logger.warning(f"Login attempt with unverified email: {form_data.email}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
detail="Email not verified",
|
||||||
|
)
|
||||||
|
elif reason == "inactive_user":
|
||||||
|
logger.warning(f"Login attempt with inactive user: {form_data.email}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_403_FORBIDDEN,
|
||||||
|
detail="User account is inactive",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
logger.warning(
|
||||||
|
f"Login attempt failed for {form_data.email} (reason: {reason})"
|
||||||
|
)
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||||
|
detail="Invalid email or password",
|
||||||
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
|
)
|
||||||
|
|
||||||
access_token = create_access_token(user)
|
access_token = create_access_token(user)
|
||||||
logger.info(f"Login successful for user: {user.email}")
|
logger.info(f"Login successful for user: {user.email}")
|
||||||
|
@ -374,7 +374,9 @@ def get_user_by_email(db: Session, email: str) -> Optional[User]:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def authenticate_user(db: Session, email: str, password: str) -> Optional[User]:
|
def authenticate_user(
|
||||||
|
db: Session, email: str, password: str
|
||||||
|
) -> Tuple[Optional[User], str]:
|
||||||
"""
|
"""
|
||||||
Authenticates a user with email and password
|
Authenticates a user with email and password
|
||||||
|
|
||||||
@ -384,16 +386,18 @@ def authenticate_user(db: Session, email: str, password: str) -> Optional[User]:
|
|||||||
password: User password
|
password: User password
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Optional[User]: Authenticated user or None
|
Tuple[Optional[User], str]: Authenticated user and reason (or None and reason)
|
||||||
"""
|
"""
|
||||||
user = get_user_by_email(db, email)
|
user = get_user_by_email(db, email)
|
||||||
if not user:
|
if not user:
|
||||||
return None
|
return None, "user_not_found"
|
||||||
if not verify_password(password, user.password_hash):
|
if not verify_password(password, user.password_hash):
|
||||||
return None
|
return None, "invalid_password"
|
||||||
|
if not user.email_verified:
|
||||||
|
return None, "email_not_verified"
|
||||||
if not user.is_active:
|
if not user.is_active:
|
||||||
return None
|
return None, "inactive_user"
|
||||||
return user
|
return user, "success"
|
||||||
|
|
||||||
|
|
||||||
def get_admin_users(db: Session, skip: int = 0, limit: int = 100):
|
def get_admin_users(db: Session, skip: int = 0, limit: int = 100):
|
||||||
|
Loading…
Reference in New Issue
Block a user