"""Access control and logging models.""" from datetime import datetime from sqlalchemy import Column, Integer, String, DateTime, ForeignKey from sqlalchemy.orm import relationship from ..database import Base class UserGatewayAccess(Base): """User access to gateways.""" __tablename__ = "user_gateway_access" id = Column(Integer, primary_key=True, index=True) user_id = Column(Integer, ForeignKey("users.id"), nullable=False) gateway_id = Column(Integer, ForeignKey("gateways.id"), nullable=False) granted_at = Column(DateTime, default=datetime.utcnow, nullable=False) granted_by_id = Column(Integer, ForeignKey("users.id"), nullable=True) # Relationships user = relationship("User", foreign_keys=[user_id], back_populates="gateway_access") gateway = relationship("Gateway", back_populates="user_access") granted_by = relationship("User", foreign_keys=[granted_by_id]) def __repr__(self): return f"" class UserEndpointAccess(Base): """User access to specific endpoints (optional fine-grained control).""" __tablename__ = "user_endpoint_access" id = Column(Integer, primary_key=True, index=True) user_id = Column(Integer, ForeignKey("users.id"), nullable=False) endpoint_id = Column(Integer, ForeignKey("endpoints.id"), nullable=False) granted_at = Column(DateTime, default=datetime.utcnow, nullable=False) granted_by_id = Column(Integer, ForeignKey("users.id"), nullable=True) # Relationships user = relationship("User", foreign_keys=[user_id], back_populates="endpoint_access") endpoint = relationship("Endpoint", back_populates="user_access") granted_by = relationship("User", foreign_keys=[granted_by_id]) def __repr__(self): return f"" class ConnectionLog(Base): """Log of VPN connections for auditing.""" __tablename__ = "connection_logs" id = Column(Integer, primary_key=True, index=True) user_id = Column(Integer, ForeignKey("users.id"), nullable=False) gateway_id = Column(Integer, ForeignKey("gateways.id"), nullable=False) endpoint_id = Column(Integer, ForeignKey("endpoints.id"), nullable=True) # Connection details client_ip = Column(String(45), nullable=True) # Client's real IP vpn_ip = Column(String(45), nullable=True) # Assigned VPN IP connected_at = Column(DateTime, default=datetime.utcnow, nullable=False) disconnected_at = Column(DateTime, nullable=True) # Relationships user = relationship("User", back_populates="connection_logs") gateway = relationship("Gateway", back_populates="connection_logs") endpoint = relationship("Endpoint", back_populates="connection_logs") def __repr__(self): return f"" @property def duration_seconds(self) -> int | None: """Get connection duration in seconds.""" if self.disconnected_at: return int((self.disconnected_at - self.connected_at).total_seconds()) return None