diff --git a/src/dashboard.py b/src/dashboard.py index d1c018ba..d52c3cbe 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -90,7 +90,7 @@ _, APP_PREFIX = DashboardConfig.GetConfig("Server", "app_prefix") cors = CORS(app, resources={rf"{APP_PREFIX}/api/*": { "origins": "*", "methods": "DELETE, POST, GET, OPTIONS", - "allow_headers": ["Content-Type", "wg-dashboard-apikey", "name"] + "allow_headers": ["Content-Type", "wg-dashboard-apikey"] }}) ''' @@ -883,6 +883,31 @@ def API_getConfigurationInfo(): "configurationRestrictedPeers": WireguardConfigurations[configurationName].getRestrictedPeersList() }) +@app.get(f'{APP_PREFIX}/api/getPeerSessions') +def API_GetPeerSessions(): + configurationName = request.args.get("configurationName") + id = request.args.get('id') + try: + startDate = request.args.get('startDate', None) + endDate = request.args.get('endDate', None) + + if startDate is None: + endDate = None + else: + startDate = datetime.strptime(startDate, "%Y-%m-%d") + if endDate: + endDate = datetime.strptime(endDate, "%Y-%m-%d") + if startDate > endDate: + return ResponseObject(False, "startDate must be smaller than endDate") + except Exception as e: + return ResponseObject(False, "Dates are invalid") + if not configurationName or not id: + return ResponseObject(False, "Please provide configurationName and id") + fp, p = WireguardConfigurations.get(configurationName).searchPeer(id) + if fp: + return ResponseObject(data=p.getSessions(startDate, endDate)) + return ResponseObject(False, "Peer does not exist") + @app.get(f'{APP_PREFIX}/api/getDashboardTheme') def API_getDashboardTheme(): return ResponseObject(data=DashboardConfig.GetConfig("Server", "dashboard_theme")[1]) @@ -1431,17 +1456,23 @@ def peerInformationBackgroundThread(): global WireguardConfigurations app.logger.info("Background Thread #1 Started") app.logger.info("Background Thread #1 PID:" + str(threading.get_native_id())) - + delay = 6 time.sleep(10) while True: with app.app_context(): for c in WireguardConfigurations.values(): if c.getStatus(): - c.getPeersTransfer() c.getPeersLatestHandshake() + c.getPeersTransfer() c.getPeersEndpoint() c.getPeers() + if delay == 6: + c.logPeersTraffic() c.getRestrictedPeersList() + if delay == 6: + delay = 1 + else: + delay += 1 time.sleep(10) def peerJobScheduleBackgroundThread(): diff --git a/src/modules/Peer.py b/src/modules/Peer.py index 0c0f85dd..14b47eee 100644 --- a/src/modules/Peer.py +++ b/src/modules/Peer.py @@ -1,10 +1,12 @@ """ Peer """ +import datetime import os, subprocess, uuid, random, re +from datetime import timedelta import jinja2 - +import sqlalchemy as db from .PeerJob import PeerJob from .PeerShareLink import PeerShareLink from .Utilities import GenerateWireguardPublicKey, ValidateIPAddressesWithRange, ValidateDNSAddress @@ -232,4 +234,54 @@ class Peer: except Exception as e: print(e) return False - return True \ No newline at end of file + return True + + def getSessions(self, startDate: datetime.datetime = None, endDate: datetime.datetime = None): + if endDate is None: + endDate = datetime.datetime.now() + + if startDate is None: + startDate = (endDate - datetime.timedelta(days=1)) + + endDate = endDate.replace(hour=23, minute=59, second=59, microsecond=999999) + startDate = startDate.replace(hour=0, minute=0, second=0, microsecond=0) + + + with self.configuration.engine.connect() as conn: + result = conn.execute( + db.select( + self.configuration.peersTransferTable.c.time + ).where( + db.and_( + self.configuration.peersTransferTable.c.id == self.id, + self.configuration.peersTransferTable.c.time <= endDate, + self.configuration.peersTransferTable.c.time >= startDate, + ) + ).order_by( + self.configuration.peersTransferTable.c.time + ) + ).fetchall() + # sessions = [] + # current_session = [time[0]] + # + # for ts in time[1:]: + # if ts - current_session[-1] <= datetime.timedelta(minutes=3): + # current_session.append(ts) + # else: + # sessions.append({ + # "duration": self.__duration(current_session[-1], current_session[0]), + # "timestamps": current_session + # }) + # current_session = [ts] + # sessions.append({ + # "duration": self.__duration(current_session[-1], current_session[0]), + # "timestamps": current_session + # }) + return list(map(lambda x : x[0], result)) + + def __duration(self, t1: datetime.datetime, t2: datetime.datetime): + delta = t1 - t2 + + hours, remainder = divmod(delta.total_seconds(), 3600) + minutes, seconds = divmod(remainder, 60) + return f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}" \ No newline at end of file diff --git a/src/modules/WireguardConfiguration.py b/src/modules/WireguardConfiguration.py index 8b42ba09..5e740953 100644 --- a/src/modules/WireguardConfiguration.py +++ b/src/modules/WireguardConfiguration.py @@ -397,14 +397,13 @@ class WireguardConfiguration: if len(split) == 2: p[pCounter]["name"] = split[1] with self.engine.begin() as conn: - - for i in p: if "PublicKey" in i.keys(): - tempPeer = conn.execute(self.peersTable.select().where( - self.peersTable.columns.id == i['PublicKey'] - )).mappings().fetchone() - + tempPeer = conn.execute( + self.peersTable.select().where( + self.peersTable.columns.id == i['PublicKey'] + ) + ).mappings().fetchone() if tempPeer is None: tempPeer = { "id": i['PublicKey'], @@ -439,6 +438,7 @@ class WireguardConfiguration: self.peersTable.columns.id == i['PublicKey'] ) ) + tmpList.append(Peer(tempPeer, self)) except Exception as e: if __name__ == '__main__': @@ -449,7 +449,26 @@ class WireguardConfiguration: for i in existingPeers: tmpList.append(Peer(i, self)) self.Peers = tmpList - + + def logPeersTraffic(self): + with self.engine.begin() as conn: + for tempPeer in self.Peers: + if tempPeer.status == "running": + print(tempPeer.id + " running") + conn.execute( + self.peersTransferTable.insert().values({ + "id": tempPeer.id, + "total_receive": tempPeer.total_receive, + "total_sent": tempPeer.total_sent, + "total_data": tempPeer.total_data, + "cumu_sent": tempPeer.cumu_sent, + "cumu_receive": tempPeer.cumu_receive, + "cumu_data": tempPeer.cumu_data, + "time": datetime.now() + }) + ) + + def addPeers(self, peers: list) -> tuple[bool, dict]: result = { "message": None, @@ -750,9 +769,6 @@ class WireguardConfiguration: ) ) - # except Exception as e: - # print(cur_i, cur_i['total_receive']) - # print(f"[WGDashboard] {self.Name} getPeersTransfer() Error: {str(e)} {str(e.__traceback__)}") def getPeersEndpoint(self):