151 lines
5.2 KiB
Python
151 lines
5.2 KiB
Python
"""User model for authentication system."""
|
|
|
|
from sqlalchemy import Column, String, Boolean, DateTime, ForeignKey
|
|
from sqlalchemy.orm import relationship
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from backend.core.database_registry import registry
|
|
from backend.models.base import Model
|
|
|
|
Base = registry.Base
|
|
|
|
|
|
class User(Model):
|
|
"""User model for authentication and authorization."""
|
|
|
|
__tablename__ = "users"
|
|
__table_args__ = {"extend_existing": True} # Allow redefinition during imports
|
|
|
|
# Primary key
|
|
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
|
|
|
# User credentials
|
|
email = Column(String(255), unique=True, nullable=False, index=True)
|
|
password_hash = Column(String(255), nullable=False)
|
|
|
|
# User status
|
|
is_verified = Column(Boolean, default=False)
|
|
is_active = Column(Boolean, default=True)
|
|
|
|
# Timestamps
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
last_login = Column(DateTime)
|
|
|
|
# Relationships
|
|
refresh_tokens = relationship("backend.models.user.RefreshToken", back_populates="user", cascade="all, delete-orphan")
|
|
summaries = relationship("backend.models.summary.Summary", back_populates="user", cascade="all, delete-orphan")
|
|
api_keys = relationship("backend.models.user.APIKey", back_populates="user", cascade="all, delete-orphan")
|
|
batch_jobs = relationship("backend.models.batch_job.BatchJob", back_populates="user", cascade="all, delete-orphan")
|
|
|
|
# Enhanced export relationships (Story 4.4)
|
|
prompt_templates = relationship("backend.models.prompt_models.PromptTemplate", back_populates="user", cascade="all, delete-orphan")
|
|
|
|
def __repr__(self):
|
|
return f"<User(email='{self.email}', is_verified={self.is_verified})>"
|
|
|
|
|
|
class RefreshToken(Model):
|
|
"""Refresh token model for JWT authentication."""
|
|
|
|
__tablename__ = "refresh_tokens"
|
|
__table_args__ = {"extend_existing": True}
|
|
|
|
# Primary key
|
|
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
|
|
|
# Foreign key to user
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
|
|
# Token data
|
|
token_hash = Column(String(255), unique=True, nullable=False, index=True)
|
|
expires_at = Column(DateTime, nullable=False)
|
|
revoked = Column(Boolean, default=False)
|
|
|
|
# Metadata
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
|
|
# Relationships
|
|
user = relationship("backend.models.user.User", back_populates="refresh_tokens")
|
|
|
|
def __repr__(self):
|
|
return f"<RefreshToken(user_id='{self.user_id}', expires_at={self.expires_at}, revoked={self.revoked})>"
|
|
|
|
|
|
class APIKey(Model):
|
|
"""API Key model for programmatic access."""
|
|
|
|
__tablename__ = "api_keys"
|
|
__table_args__ = {"extend_existing": True}
|
|
|
|
# Primary key
|
|
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
|
|
|
# Foreign key to user
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
|
|
# Key data
|
|
name = Column(String(255), nullable=False)
|
|
key_hash = Column(String(255), unique=True, nullable=False, index=True)
|
|
last_used = Column(DateTime)
|
|
|
|
# Status
|
|
is_active = Column(Boolean, default=True)
|
|
expires_at = Column(DateTime)
|
|
|
|
# Metadata
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
|
|
# Relationships
|
|
user = relationship("backend.models.user.User", back_populates="api_keys")
|
|
|
|
def __repr__(self):
|
|
return f"<APIKey(name='{self.name}', user_id='{self.user_id}', is_active={self.is_active})>"
|
|
|
|
|
|
class EmailVerificationToken(Model):
|
|
"""Email verification token model."""
|
|
|
|
__tablename__ = "email_verification_tokens"
|
|
__table_args__ = {"extend_existing": True}
|
|
|
|
# Primary key
|
|
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
|
|
|
# Foreign key to user
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False, unique=True)
|
|
|
|
# Token data
|
|
token_hash = Column(String(255), unique=True, nullable=False, index=True)
|
|
expires_at = Column(DateTime, nullable=False)
|
|
|
|
# Metadata
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
|
|
def __repr__(self):
|
|
return f"<EmailVerificationToken(user_id='{self.user_id}', expires_at={self.expires_at})>"
|
|
|
|
|
|
class PasswordResetToken(Model):
|
|
"""Password reset token model."""
|
|
|
|
__tablename__ = "password_reset_tokens"
|
|
__table_args__ = {"extend_existing": True}
|
|
|
|
# Primary key
|
|
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
|
|
|
|
# Foreign key to user
|
|
user_id = Column(String(36), ForeignKey("users.id"), nullable=False)
|
|
|
|
# Token data
|
|
token_hash = Column(String(255), unique=True, nullable=False, index=True)
|
|
expires_at = Column(DateTime, nullable=False)
|
|
used = Column(Boolean, default=False)
|
|
|
|
# Metadata
|
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
|
|
def __repr__(self):
|
|
return f"<PasswordResetToken(user_id='{self.user_id}', expires_at={self.expires_at}, used={self.used})>" |