import streamlit as st import hashlib import re from models import User, SessionLocal def validate_password(password: str) -> tuple[bool, str]: """Validate password requirements.""" if len(password) < 8: return False, "Password must be at least 8 characters long" if not any(c.isupper() for c in password): return False, "Password must contain at least one uppercase letter" return True, "" def hash_password(password: str) -> str: """Hash a password for storing.""" return hashlib.sha256(password.encode()).hexdigest() def verify_password(stored_password: str, provided_password: str) -> bool: """Verify a stored password against one provided by user""" return stored_password == hash_password(provided_password) def login_user(username: str, password: str) -> bool: """Verify user credentials and log them in.""" db = SessionLocal() try: user = db.query(User).filter(User.username == username).first() if user and verify_password(user.password, password): st.session_state.user_id = user.id st.session_state.username = user.username return True return False finally: db.close() def signup_user(username: str, password: str) -> tuple[bool, str]: """Create a new user account.""" # Validate password is_valid, message = validate_password(password) if not is_valid: return False, message db = SessionLocal() try: # Check if username already exists if db.query(User).filter(User.username == username).first(): return False, "Username already exists" # Create new user user = User( username=username, password=hash_password(password) ) db.add(user) db.commit() # Log in the new user st.session_state.user_id = user.id st.session_state.username = user.username return True, "Account created successfully" except Exception as e: db.rollback() return False, str(e) finally: db.close() def update_profile(user_id: int, **profile_data) -> tuple[bool, str]: """Update user profile information.""" db = SessionLocal() try: user = db.query(User).filter(User.id == user_id).first() if not user: return False, "User not found" # Update user fields for field, value in profile_data.items(): if hasattr(user, field): setattr(user, field, value) db.commit() return True, "Profile updated successfully" except Exception as e: db.rollback() return False, str(e) finally: db.close() def get_user_profile(user_id: int) -> User: """Get user profile information.""" db = SessionLocal() try: return db.query(User).filter(User.id == user_id).first() finally: db.close() def change_password(user_id: int, current_password: str, new_password: str) -> tuple[bool, str]: """Change user password.""" # Validate new password is_valid, message = validate_password(new_password) if not is_valid: return False, message db = SessionLocal() try: user = db.query(User).filter(User.id == user_id).first() if not user: return False, "User not found" # Verify current password if not verify_password(user.password, current_password): return False, "Current password is incorrect" # Update password user.password = hash_password(new_password) db.commit() return True, "Password updated successfully" except Exception as e: db.rollback() return False, str(e) finally: db.close() def is_logged_in() -> bool: """Check if user is logged in.""" return 'user_id' in st.session_state def logout_user(): """Log out the current user.""" if 'user_id' in st.session_state: del st.session_state.user_id if 'username' in st.session_state: del st.session_state.username