2025-07-10 23:39:21 +08:00
|
|
|
import datetime
|
2025-06-05 17:57:14 +08:00
|
|
|
import uuid
|
|
|
|
|
2025-06-05 15:57:17 +08:00
|
|
|
from .ConnectionString import ConnectionString
|
|
|
|
from .DashboardLogger import DashboardLogger
|
|
|
|
import sqlalchemy as db
|
2025-06-05 17:57:14 +08:00
|
|
|
from .WireguardConfiguration import WireguardConfiguration
|
|
|
|
|
2025-07-10 23:39:21 +08:00
|
|
|
class Assignment:
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
self.AssignmentID: str = kwargs.get('AssignmentID')
|
|
|
|
self.ClientID: str = kwargs.get('ClientID')
|
|
|
|
self.ConfigurationName: str = kwargs.get('ConfigurationName')
|
|
|
|
self.PeerID: str = kwargs.get('PeerID')
|
|
|
|
self.AssignedDate: datetime.datetime = kwargs.get('AssignedDate')
|
|
|
|
self.UnassignedDate: datetime.datetime = kwargs.get('UnassignedDate')
|
|
|
|
self.Client: dict = {
|
|
|
|
"ClientID": self.ClientID
|
|
|
|
}
|
|
|
|
|
|
|
|
def toJson(self):
|
|
|
|
return {
|
|
|
|
"AssignmentID": self.AssignmentID,
|
|
|
|
"Client": self.Client,
|
|
|
|
"ConfigurationName": self.ConfigurationName,
|
|
|
|
"PeerID": self.PeerID,
|
|
|
|
"AssignedDate": self.AssignedDate.strftime("%Y-%m-%d %H:%M:%S"),
|
|
|
|
"UnassignedDate": self.UnassignedDate.strftime("%Y-%m-%d %H:%M:%S") if self.UnassignedDate is not None else self.UnassignedDate
|
|
|
|
}
|
|
|
|
|
2025-06-05 15:57:17 +08:00
|
|
|
class DashboardClientsPeerAssignment:
|
2025-06-05 17:57:14 +08:00
|
|
|
def __init__(self, wireguardConfigurations: dict[str, WireguardConfiguration]):
|
2025-06-05 15:57:17 +08:00
|
|
|
self.logger = DashboardLogger()
|
|
|
|
self.engine = db.create_engine(ConnectionString("wgdashboard"))
|
|
|
|
self.metadata = db.MetaData()
|
2025-06-05 17:57:14 +08:00
|
|
|
self.wireguardConfigurations = wireguardConfigurations
|
2025-06-05 15:57:17 +08:00
|
|
|
self.dashboardClientsPeerAssignmentTable = db.Table(
|
|
|
|
'DashboardClientsPeerAssignment', self.metadata,
|
|
|
|
db.Column('AssignmentID', db.String(255), nullable=False, primary_key=True),
|
|
|
|
db.Column('ClientID', db.String(255), nullable=False, index=True),
|
|
|
|
db.Column('ConfigurationName', db.String(255)),
|
|
|
|
db.Column('PeerID', db.String(500)),
|
|
|
|
db.Column('AssignedDate',
|
|
|
|
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP),
|
|
|
|
server_default=db.func.now()),
|
|
|
|
db.Column('UnassignedDate',
|
|
|
|
(db.DATETIME if 'sqlite:///' in ConnectionString("wgdashboard") else db.TIMESTAMP)),
|
|
|
|
extend_existing=True
|
|
|
|
)
|
|
|
|
self.metadata.create_all(self.engine)
|
2025-07-10 23:39:21 +08:00
|
|
|
self.assignments: list[Assignment] = []
|
2025-06-05 17:57:14 +08:00
|
|
|
self.__getAssignments()
|
|
|
|
|
2025-06-05 15:57:17 +08:00
|
|
|
def __getAssignments(self):
|
|
|
|
with self.engine.connect() as conn:
|
2025-07-10 23:39:21 +08:00
|
|
|
assignments = []
|
|
|
|
get = conn.execute(
|
2025-06-05 15:57:17 +08:00
|
|
|
self.dashboardClientsPeerAssignmentTable.select().where(
|
2025-07-10 23:39:21 +08:00
|
|
|
self.dashboardClientsPeerAssignmentTable.c.UnassignedDate.is_(None)
|
2025-06-05 15:57:17 +08:00
|
|
|
)
|
|
|
|
).mappings().fetchall()
|
2025-07-10 23:39:21 +08:00
|
|
|
for a in get:
|
|
|
|
assignments.append(Assignment(**a))
|
|
|
|
self.assignments = assignments
|
|
|
|
|
2025-06-05 15:57:17 +08:00
|
|
|
|
|
|
|
def AssignClient(self, ClientID, ConfigurationName, PeerID):
|
2025-06-05 17:57:14 +08:00
|
|
|
existing = list(
|
|
|
|
filter(lambda e:
|
2025-07-10 23:39:21 +08:00
|
|
|
e.ClientID == ClientID and
|
|
|
|
e.ConfigurationName == ConfigurationName and
|
|
|
|
e.PeerID == PeerID, self.assignments)
|
2025-06-05 17:57:14 +08:00
|
|
|
)
|
|
|
|
if len(existing) == 0:
|
|
|
|
if ConfigurationName in self.wireguardConfigurations.keys():
|
|
|
|
config = self.wireguardConfigurations.get(ConfigurationName)
|
|
|
|
peer = list(filter(lambda x : x.id == PeerID, config.Peers))
|
|
|
|
if len(peer) == 1:
|
|
|
|
with self.engine.begin() as conn:
|
|
|
|
data = {
|
2025-06-23 16:22:05 +08:00
|
|
|
"AssignmentID": str(uuid.uuid4()),
|
2025-06-05 17:57:14 +08:00
|
|
|
"ClientID": ClientID,
|
|
|
|
"ConfigurationName": ConfigurationName,
|
|
|
|
"PeerID": PeerID
|
|
|
|
}
|
|
|
|
conn.execute(
|
|
|
|
self.dashboardClientsPeerAssignmentTable.insert().values(data)
|
|
|
|
)
|
2025-06-14 19:52:23 +08:00
|
|
|
self.__getAssignments()
|
2025-06-05 17:57:14 +08:00
|
|
|
return True, data
|
|
|
|
return False, None
|
2025-06-05 15:57:17 +08:00
|
|
|
|
2025-07-10 23:39:21 +08:00
|
|
|
def UnassignClients(self, AssignmentID):
|
|
|
|
existing = list(
|
|
|
|
filter(lambda e:
|
|
|
|
e.AssignmentID == AssignmentID, self.assignments)
|
|
|
|
)
|
|
|
|
if not existing:
|
|
|
|
return False
|
|
|
|
with self.engine.begin() as conn:
|
|
|
|
conn.execute(
|
|
|
|
self.dashboardClientsPeerAssignmentTable.update().values({
|
|
|
|
"UnassignedDate": datetime.datetime.now()
|
|
|
|
}).where(
|
|
|
|
self.dashboardClientsPeerAssignmentTable.c.AssignmentID == AssignmentID
|
|
|
|
)
|
|
|
|
)
|
|
|
|
self.__getAssignments()
|
|
|
|
return True
|
|
|
|
|
2025-06-05 15:57:17 +08:00
|
|
|
|
2025-07-10 23:39:21 +08:00
|
|
|
def GetAssignedClients(self, ConfigurationName, PeerID) -> list[Assignment]:
|
|
|
|
self.__getAssignments()
|
|
|
|
return list(filter(
|
|
|
|
lambda c : c.ConfigurationName == ConfigurationName and
|
|
|
|
c.PeerID == PeerID, self.assignments))
|
2025-06-05 15:57:17 +08:00
|
|
|
|
|
|
|
def GetAssignedPeers(self, ClientID):
|
2025-06-14 19:52:23 +08:00
|
|
|
self.__getAssignments()
|
|
|
|
|
2025-06-05 17:57:14 +08:00
|
|
|
peers = []
|
2025-06-06 15:49:55 +08:00
|
|
|
assigned = filter(lambda e:
|
2025-07-10 23:39:21 +08:00
|
|
|
e.ClientID == ClientID, self.assignments)
|
2025-06-05 17:57:14 +08:00
|
|
|
|
|
|
|
for a in assigned:
|
2025-07-10 23:39:21 +08:00
|
|
|
peer = filter(lambda e : e.id == a.PeerID,
|
|
|
|
self.wireguardConfigurations[a.ConfigurationName].Peers)
|
2025-06-05 17:57:14 +08:00
|
|
|
for p in peer:
|
|
|
|
peers.append({
|
2025-07-10 23:39:21 +08:00
|
|
|
'protocol': self.wireguardConfigurations[a.ConfigurationName].Protocol,
|
2025-06-05 17:57:14 +08:00
|
|
|
'id': p.id,
|
|
|
|
'private_key': p.private_key,
|
|
|
|
'name': p.name,
|
|
|
|
'received_data': p.total_receive + p.cumu_receive,
|
|
|
|
'sent_data': p.total_sent + p.cumu_sent,
|
|
|
|
'data': p.total_data + p.cumu_data,
|
|
|
|
'status': p.status,
|
|
|
|
'latest_handshake': p.latest_handshake,
|
|
|
|
'allowed_ip': p.allowed_ip,
|
|
|
|
'jobs': p.jobs,
|
2025-07-10 23:39:21 +08:00
|
|
|
'configuration_name': a.ConfigurationName,
|
2025-06-05 17:57:14 +08:00
|
|
|
'peer_configuration_data': p.downloadPeer()
|
|
|
|
})
|
|
|
|
return peers
|