""" Security Models Models for security tracking, blocked IPs, and incidents. """ import uuid from sqlalchemy import Boolean, Column, DateTime, Integer, String from core.models.base import Base, utc_now class BlockedIP(Base): """ Blocked IP Address Model Tracks IPs that have been blocked due to suspicious activity. """ __tablename__ = "blocked_ips" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) ip_address = Column(String, nullable=False, unique=True, index=True) reason = Column(String, nullable=False) blocked_at = Column(DateTime, default=utc_now, nullable=False) expires_at = Column(DateTime, nullable=True) # Null means permanent blocked_by = Column(String, default="system") # system or admin user_id # Metadata for analysis country_code = Column(String, nullable=True) isp = Column(String, nullable=True) total_failed_attempts = Column(Integer, default=0) def to_dict(self): return { "id": self.id, "ip_address": self.ip_address, "reason": self.reason, "blocked_at": self.blocked_at.isoformat() if self.blocked_at else None, "expires_at": self.expires_at.isoformat() if self.expires_at else None, "blocked_by": self.blocked_by, "country_code": self.country_code } class APIKey(Base): """ API Key Model for persistent storage Tracks authentication keys issued to users or services. """ __tablename__ = "api_keys" id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) key_prefix = Column(String, nullable=False, index=True) # First 8 chars for identification key_hash = Column(String, nullable=False, unique=True, index=True) # Full hashed key name = Column(String, nullable=False) description = Column(String, nullable=True) user_id = Column(String, nullable=False, index=True) # Owner of the key permissions = Column(String, nullable=False) # JSON string of permissions is_active = Column(Boolean, default=True) created_at = Column(DateTime, default=utc_now, nullable=False) expires_at = Column(DateTime, nullable=True) last_used_at = Column(DateTime, nullable=True) def to_dict(self): import json return { "id": self.id, "prefix": self.key_prefix, "name": self.name, "description": self.description, "user_id": self.user_id, "permissions": json.loads(self.permissions) if self.permissions else [], "is_active": self.is_active, "created_at": self.created_at.isoformat() if self.created_at else None, "expires_at": self.expires_at.isoformat() if self.expires_at else None, "last_used_at": self.last_used_at.isoformat() if self.last_used_at else None, }