from datetime import datetime from enum import Enum from flask_sqlalchemy import SQLAlchemy from flask_login import UserMixin from werkzeug.security import generate_password_hash, check_password_hash from app.config.database import db class UserRole(Enum): """User role enumeration for role-based access control.""" VIEWER = "viewer" USER = "user" ADMIN = "admin" class User(UserMixin, db.Model): """User model for authentication and authorization.""" __tablename__ = "users" id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(50), unique=True, nullable=False) email = db.Column(db.String(100), unique=True, nullable=False) password_hash = db.Column(db.String(255), nullable=False) user_level = db.Column(db.String(20), nullable=False) preferred_language = db.Column(db.String(5), default="en") preferred_theme = db.Column(db.String(10), default="light") created_at = db.Column(db.DateTime, default=datetime.utcnow) last_login = db.Column(db.DateTime) is_active = db.Column(db.Boolean, default=True) # Relationships user_projects = db.relationship("UserProject", backref="user", lazy=True) user_script_tags = db.relationship("UserScriptTag", backref="user", lazy=True) execution_logs = db.relationship("ExecutionLog", backref="user", lazy=True) def set_password(self, password): """Set password hash.""" self.password_hash = generate_password_hash(password) def check_password(self, password): """Check password against hash.""" return check_password_hash(self.password_hash, password) def get_id(self): """Return user ID as string for Flask-Login.""" return str(self.id) def to_dict(self): """Convert user to dictionary.""" return { "id": self.id, "username": self.username, "email": self.email, "user_level": self.user_level, "preferred_language": self.preferred_language, "preferred_theme": self.preferred_theme, "created_at": self.created_at.isoformat() if self.created_at else None, "last_login": self.last_login.isoformat() if self.last_login else None, "is_active": self.is_active, }