import bcrypt from bson import ObjectId from app.db import get_db class User: def __init__(self, username, email, password_hash=None, role="user", auth_type="local", microsoft_id=None): self.username = username self.email = email self.password_hash = password_hash self.role = role self.auth_type = auth_type self.microsoft_id = microsoft_id @staticmethod def hash_password(password): salt = bcrypt.gensalt() hashed = bcrypt.hashpw(password.encode('utf-8'), salt) return hashed.decode('utf-8') @staticmethod def check_password(password_hash, password): return bcrypt.checkpw(password.encode('utf-8'), password_hash.encode('utf-8')) @staticmethod async def find_by_username(username): db = await get_db() user_data = await db.users.find_one({"username": username}) return user_data @staticmethod async def find_by_email(email): db = await get_db() user_data = await db.users.find_one({"email": email}) return user_data @staticmethod async def find_by_id(user_id): db = await get_db() user_data = await db.users.find_one({"_id": ObjectId(user_id)}) return user_data @staticmethod async def find_by_microsoft_id(microsoft_id): db = await get_db() user_data = await db.users.find_one({"microsoft_id": microsoft_id}) return user_data @staticmethod async def update_microsoft_id(user_id, microsoft_id): db = await get_db() result = await db.users.update_one( {"_id": ObjectId(user_id)}, {"$set": {"microsoft_id": microsoft_id, "auth_type": "microsoft"}} ) return result.modified_count > 0 def to_dict(self): return { "username": self.username, "email": self.email, "role": self.role, "auth_type": self.auth_type, "microsoft_id": self.microsoft_id } async def save(self): db = await get_db() user_data = { "username": self.username, "email": self.email, "password_hash": self.password_hash, "role": self.role, "auth_type": self.auth_type, "microsoft_id": self.microsoft_id } result = await db.users.insert_one(user_data) return result.inserted_id @staticmethod async def create_default_user(): try: db = await get_db() # First check if users collection exists collections = await db.list_collection_names() if "users" not in collections: print("Creating users collection") await db.create_collection("users") # Safely check if user exists, handling potential auth errors try: user_exists = await db.users.count_documents({"username": "user"}) > 0 except Exception as e: print(f"Error checking for default user: {e}") # If we can't query, assume we need to create the user user_exists = False if not user_exists: default_user = User( username="user", email="user@example.com", password_hash=User.hash_password("pass"), role="admin" ) await default_user.save() print("Default user created successfully") else: print("Default user already exists") except Exception as e: print(f"Error creating default user: {e}") # Don't raise the exception - allow the app to continue even if we can't create the user