数据库模型基本完成
This commit is contained in:
parent
fb41b442da
commit
287a1e5629
5
models/__init__.py
Normal file
5
models/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
from .user import User
|
||||
from .auth import get_password_hash, verify_password
|
||||
from .database import init_db
|
||||
|
||||
__all__ = ["User", "get_password_hash", "verify_password", "init_db"]
|
11
models/auth.py
Normal file
11
models/auth.py
Normal file
@ -0,0 +1,11 @@
|
||||
from passlib.context import CryptContext
|
||||
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
|
||||
def get_password_hash(password: str) -> str:
|
||||
"""Generate password hash using bcrypt"""
|
||||
return pwd_context.hash(password)
|
||||
|
||||
def verify_password(plain_password: str, hashed_password: str) -> bool:
|
||||
"""Verify password against stored hash"""
|
||||
return pwd_context.verify(plain_password, hashed_password)
|
25
models/database.py
Normal file
25
models/database.py
Normal file
@ -0,0 +1,25 @@
|
||||
from sqlalchemy.ext.asyncio import AsyncEngine
|
||||
from .user import Base, User, UserRole
|
||||
from sqlalchemy import select
|
||||
from .auth import get_password_hash
|
||||
|
||||
async def init_db(engine: AsyncEngine):
|
||||
"""Initialize database"""
|
||||
async with engine.begin() as conn:
|
||||
# Create all tables
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
|
||||
# Check if system admin exists
|
||||
result = await conn.execute(
|
||||
select(User).where(User.role == UserRole.SYSTEM_ADMIN)
|
||||
)
|
||||
if not result.scalars().first():
|
||||
# Create default system admin
|
||||
admin = User(
|
||||
username="admin",
|
||||
password=get_password_hash("password"),
|
||||
role=UserRole.SYSTEM_ADMIN,
|
||||
description="default system admin"
|
||||
)
|
||||
conn.add(admin)
|
||||
await conn.commit()
|
25
models/user.py
Normal file
25
models/user.py
Normal file
@ -0,0 +1,25 @@
|
||||
from datetime import datetime, timezone
|
||||
from enum import Enum
|
||||
from sqlalchemy import Column, Integer, String, Text, DateTime, Enum as SQLEnum
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class UserRole(str, Enum):
|
||||
SYSTEM_ADMIN = "system_admin"
|
||||
ADMIN = "admin"
|
||||
USER = "user"
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
username = Column(String(50), unique=True, nullable=False)
|
||||
password = Column(String(255), nullable=False)
|
||||
role = Column(SQLEnum(UserRole), nullable=False, default=UserRole.USER)
|
||||
description = Column(Text)
|
||||
created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
|
||||
updated_at = Column(DateTime, default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User(id={self.id}, username={self.username}, role={self.role})>"
|
8
requirements.txt
Normal file
8
requirements.txt
Normal file
@ -0,0 +1,8 @@
|
||||
fastapi>=0.95.2
|
||||
sqlalchemy>=2.0.15
|
||||
passlib>=1.7.4
|
||||
bcrypt>=4.0.1
|
||||
pyjwt>=2.6.0
|
||||
pytest>=7.3.1
|
||||
requests>=2.28.2
|
||||
uvicorn[standard]>=0.21.1
|
Loading…
x
Reference in New Issue
Block a user