openvpn-endpoint-server/server/app/models/vpn_connection_log.py

51 lines
1.8 KiB
Python

"""VPN Connection Log model for tracking profile connection history."""
from datetime import datetime
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, BigInteger
from sqlalchemy.orm import relationship
from ..database import Base
class VPNConnectionLog(Base):
"""Log of VPN profile connections."""
__tablename__ = "vpn_connection_logs"
id = Column(Integer, primary_key=True, index=True)
vpn_profile_id = Column(Integer, ForeignKey("vpn_profiles.id"), nullable=False)
vpn_server_id = Column(Integer, ForeignKey("vpn_servers.id"), nullable=False)
gateway_id = Column(Integer, ForeignKey("gateways.id"), nullable=False)
# Connection info
common_name = Column(String(255), nullable=False)
real_address = Column(String(255), nullable=True) # IP:Port
vpn_ip = Column(String(15), nullable=True) # Assigned VPN IP
# Timestamps
connected_at = Column(DateTime, default=datetime.utcnow, nullable=False)
disconnected_at = Column(DateTime, nullable=True)
# Traffic stats (updated on disconnect)
bytes_received = Column(BigInteger, default=0)
bytes_sent = Column(BigInteger, default=0)
# Relationships
vpn_profile = relationship("VPNProfile")
vpn_server = relationship("VPNServer")
gateway = relationship("Gateway")
def __repr__(self):
return f"<VPNConnectionLog(id={self.id}, cn='{self.common_name}', connected={self.connected_at})>"
@property
def duration_seconds(self) -> int | None:
"""Connection duration in seconds."""
if self.disconnected_at:
return int((self.disconnected_at - self.connected_at).total_seconds())
return None
@property
def is_active(self) -> bool:
"""Check if connection is still active."""
return self.disconnected_at is None