66 lines
2.3 KiB
Python
66 lines
2.3 KiB
Python
"""Authentication service."""
|
|
from models.user import User, db
|
|
from sqlalchemy import func
|
|
from typing import Optional
|
|
|
|
|
|
def _normalize_username(username: str) -> str:
|
|
return (username or '').strip()
|
|
|
|
def authenticate_user(username: str, password: str) -> Optional[User]:
|
|
"""Authenticate a user by username and password."""
|
|
normalized_username = _normalize_username(username)
|
|
if not normalized_username or not password:
|
|
return None
|
|
|
|
user = User.query.filter(func.lower(User.username) == normalized_username.lower()).first()
|
|
if user and user.check_password(password):
|
|
return user
|
|
return None
|
|
|
|
def get_user_by_id(user_id: int) -> Optional[User]:
|
|
"""Get user by ID."""
|
|
return User.query.get(user_id)
|
|
|
|
def get_user_by_username(username: str) -> Optional[User]:
|
|
"""Get user by username."""
|
|
normalized_username = _normalize_username(username)
|
|
if not normalized_username:
|
|
return None
|
|
return User.query.filter(func.lower(User.username) == normalized_username.lower()).first()
|
|
|
|
|
|
def register_user(username: str, password: str, email: Optional[str] = None) -> User:
|
|
"""Register a new user with basic defaults for public SUT usage."""
|
|
normalized_username = _normalize_username(username)
|
|
normalized_password = (password or '').strip()
|
|
|
|
if not normalized_username or not normalized_password:
|
|
raise ValueError('Username and password are required')
|
|
|
|
if len(normalized_username) < 3:
|
|
raise ValueError('Username must be at least 3 characters long')
|
|
|
|
if len(normalized_password) < 8 or not any(char.isdigit() for char in normalized_password):
|
|
raise ValueError('Password must be at least 8 characters and contain at least one number')
|
|
|
|
if get_user_by_username(normalized_username):
|
|
raise ValueError('Username already exists')
|
|
|
|
normalized_email = (email or '').strip().lower() or f'{normalized_username.lower()}@testingfantasy.local'
|
|
existing_email = User.query.filter_by(email=normalized_email).first()
|
|
if existing_email:
|
|
raise ValueError('Email is already in use')
|
|
|
|
user = User(
|
|
username=normalized_username,
|
|
email=normalized_email,
|
|
role=normalized_username, # Use username as role/character name
|
|
gold=500,
|
|
)
|
|
user.set_password(normalized_password)
|
|
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
return user
|