| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- from datetime import datetime, timezone
- from app import db
- import bcrypt
- def utc_now():
- """Return current UTC time as timezone-aware datetime"""
- return datetime.now(timezone.utc)
- def format_datetime(dt: datetime) -> str:
- """Format datetime to ISO format with UTC timezone indicator"""
- if dt is None:
- return None
- # If datetime is naive (no timezone), assume it's UTC
- if dt.tzinfo is None:
- dt = dt.replace(tzinfo=timezone.utc)
- return dt.isoformat()
- class User(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, index=True)
- email = db.Column(db.String(100), unique=True, nullable=False, index=True)
- password_hash = db.Column(db.String(255), nullable=False)
- role = db.Column(db.Enum('admin', 'power_user', 'user', name='user_role'), default='user')
- created_at = db.Column(db.DateTime, default=utc_now)
- is_active = db.Column(db.Boolean, default=True)
-
- # Relationships
- credentials = db.relationship('UserCredential', back_populates='user', cascade='all, delete-orphan')
- tasks = db.relationship('Task', back_populates='created_by_user', cascade='all, delete-orphan')
-
- def set_password(self, password: str) -> None:
- """Hash and set the user's password"""
- self.password_hash = bcrypt.hashpw(
- password.encode('utf-8'),
- bcrypt.gensalt()
- ).decode('utf-8')
-
- def check_password(self, password: str) -> bool:
- """Verify the user's password"""
- return bcrypt.checkpw(
- password.encode('utf-8'),
- self.password_hash.encode('utf-8')
- )
-
- def to_dict(self) -> dict:
- """Convert user to dictionary (excluding sensitive data)"""
- return {
- 'id': self.id,
- 'username': self.username,
- 'email': self.email,
- 'role': self.role,
- 'created_at': format_datetime(self.created_at),
- 'is_active': self.is_active
- }
-
- def __repr__(self):
- return f'<User {self.username}>'
|