ui,events: display all columns in the Events tab

Display by default all columns in the Events tab, and allow to configure
what columns to display.

Closes #1223
This commit is contained in:
Gustavo Iñiguez Goia 2024-12-15 23:04:47 +01:00
parent 7944532922
commit 4e8b222bd4
Failed to generate hash of commit
4 changed files with 207 additions and 76 deletions

View file

@ -672,7 +672,7 @@ class PreferencesDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
if cols == None:
return
for c in range(8):
for c in range(13):
checked = str(c) in cols
if c == 0:
@ -682,14 +682,26 @@ class PreferencesDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
elif c == 2:
self.checkHideAction.setChecked(checked)
elif c == 3:
self.checkHideDst.setChecked(checked)
self.checkHideSrcPort.setChecked(checked)
elif c == 4:
self.checkHideProto.setChecked(checked)
self.checkHideSrcIP.setChecked(checked)
elif c == 5:
self.checkHideProc.setChecked(checked)
self.checkHideDstIP.setChecked(checked)
elif c == 6:
self.checkHideCmdline.setChecked(checked)
self.checkHideDstHost.setChecked(checked)
elif c == 7:
self.checkHideDstPort.setChecked(checked)
elif c == 8:
self.checkHideProto.setChecked(checked)
elif c == 9:
self.checkHideUID.setChecked(checked)
elif c == 10:
self.checkHidePID.setChecked(checked)
elif c == 11:
self.checkHideProc.setChecked(checked)
elif c == 12:
self.checkHideCmdline.setChecked(checked)
elif c == 13:
self.checkHideRule.setChecked(checked)
def _reset_node_settings(self):
@ -845,16 +857,28 @@ class PreferencesDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
cols.append("1")
if self.checkHideAction.isChecked():
cols.append("2")
if self.checkHideDst.isChecked():
if self.checkHideSrcPort.isChecked():
cols.append("3")
if self.checkHideProto.isChecked():
if self.checkHideSrcIP.isChecked():
cols.append("4")
if self.checkHideProc.isChecked():
if self.checkHideDstIP.isChecked():
cols.append("5")
if self.checkHideCmdline.isChecked():
if self.checkHideDstHost.isChecked():
cols.append("6")
if self.checkHideRule.isChecked():
if self.checkHideDstPort.isChecked():
cols.append("7")
if self.checkHideProto.isChecked():
cols.append("8")
if self.checkHideUID.isChecked():
cols.append("9")
if self.checkHidePID.isChecked():
cols.append("10")
if self.checkHideProc.isChecked():
cols.append("11")
if self.checkHideCmdline.isChecked():
cols.append("12")
if self.checkHideRule.isChecked():
cols.append("13")
self._cfg.setSettings(Config.STATS_SHOW_COLUMNS, cols)

View file

@ -48,15 +48,22 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
LAST_GROUP_BY = ""
# general
COL_TIME = 0
COL_NODE = 1
COL_ACTION = 2
COL_DSTIP = 3
COL_PROTO = 4
COL_PROCS = 5
COL_CMDLINE = 6
COL_RULES = 7
GENERAL_COL_NUM = 8
COL_TIME = 0
COL_NODE = 1
COL_ACTION = 2
COL_SRCPORT = 3
COL_SRCIP = 4
COL_DSTIP = 5
COL_DSTHOST = 6
COL_DSTPORT = 7
COL_PROTO = 8
COL_UID = 9
COL_PID = 10
COL_PROCS = 11
COL_CMDLINE = 12
COL_RULES = 13
# total number of columns: cols + 1
GENERAL_COL_NUM = 14
# nodes
COL_N_STATUS = 2
@ -159,11 +166,14 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
"display_fields": "time as Time, " \
"node as Node, " \
"action as Action, " \
"CASE dst_host WHEN ''" \
" THEN dst_ip || ' -> ' || dst_port " \
" ELSE dst_host || ' -> ' || dst_port " \
"END Destination, " \
"src_port as SrcPort, " \
"src_ip as SrcIP, " \
"dst_ip as DstIP, " \
"dst_host as DstHost, " \
"dst_port as DstPort, " \
"protocol as Protocol, " \
"uid as UID, " \
"pid as PID, " \
"process as Process, " \
"process_args as Cmdline, " \
"rule as Rule",
@ -382,11 +392,14 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
self.COL_STR_PROCESS = QC.translate("stats", "Process", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_PROC_CMDLINE = QC.translate("stats", "Cmdline", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_DESTINATION = QC.translate("stats", "Destination", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_SRC_PORT = QC.translate("stats", "SrcPort", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_SRC_IP = QC.translate("stats", "SrcIP", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_DST_IP = QC.translate("stats", "DstIP", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_DST_HOST = QC.translate("stats", "DstHost", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_DST_PORT = QC.translate("stats", "DstPort", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_RULE = QC.translate("stats", "Rule", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_UID = QC.translate("stats", "UserID", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_PID = QC.translate("stats", "PID", "This is a word, without spaces and symbols.").replace(" ", "")
self.COL_STR_LAST_CONNECTION = QC.translate("stats", "LastConnection", "This is a word, without spaces and symbols.").replace(" ", "")
self.FIREWALL_STOPPED = QC.translate("stats", "Not running")
@ -433,6 +446,9 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
# used to skip updates while the user is moving the scrollbar
self.scrollbar_active = False
# flag to force a refresh of the columns
self._refresh_columns = False
self._lock = threading.RLock()
self._address = address
self._stats = None
@ -607,9 +623,16 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
self.COL_STR_TIME,
self.COL_STR_NODE,
self.COL_STR_ACTION,
self.COL_STR_DESTINATION,
self.COL_STR_SRC_PORT,
self.COL_STR_SRC_IP,
self.COL_STR_DST_IP,
self.COL_STR_DST_HOST,
self.COL_STR_DST_PORT,
self.COL_STR_PROTOCOL,
self.COL_STR_UID,
self.COL_STR_PID,
self.COL_STR_PROCESS,
self.COL_STR_PROC_CMDLINE,
self.COL_STR_RULE,
]),
verticalScrollBar=self.connectionsTableScrollBar,
@ -1870,14 +1893,44 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
self._set_rules_query(r_name, node)
elif idx == StatsDialog.COL_DSTIP:
cur_idx = self.TAB_HOSTS
cur_idx = self.TAB_ADDRS
self.IN_DETAIL_VIEW[cur_idx] = True
rowdata = row.model().index(row.row(), self.COL_DSTIP).data()
hostip = rowdata.split(" ")[0]
self.LAST_SELECTED_ITEM = hostip
ip = rowdata
self.LAST_SELECTED_ITEM = ip
self.tabWidget.setCurrentIndex(cur_idx)
self._set_active_widgets(True, hostip)
self._set_hosts_query(hostip)
self._set_active_widgets(True, ip)
self._set_addrs_query(ip)
elif idx == StatsDialog.COL_DSTHOST:
cur_idx = self.TAB_HOSTS
self.IN_DETAIL_VIEW[cur_idx] = True
rowdata = row.model().index(row.row(), self.COL_DSTHOST).data()
host = rowdata
self.LAST_SELECTED_ITEM = host
self.tabWidget.setCurrentIndex(cur_idx)
self._set_active_widgets(True, host)
self._set_hosts_query(host)
elif idx == StatsDialog.COL_DSTPORT:
cur_idx = self.TAB_PORTS
self.IN_DETAIL_VIEW[cur_idx] = True
rowdata = row.model().index(row.row(), self.COL_DSTPORT).data()
port = rowdata
self.LAST_SELECTED_ITEM = port
self.tabWidget.setCurrentIndex(cur_idx)
self._set_active_widgets(True, port)
self._set_ports_query(port)
elif idx == StatsDialog.COL_UID:
cur_idx = self.TAB_USERS
self.IN_DETAIL_VIEW[cur_idx] = True
rowdata = row.model().index(row.row(), self.COL_UID).data()
uid = rowdata
self.LAST_SELECTED_ITEM = uid
self.tabWidget.setCurrentIndex(cur_idx)
self._set_active_widgets(True, uid)
self._set_users_query(uid)
else:
cur_idx = self.TAB_PROCS
@ -3229,6 +3282,7 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
self._ui_refresh_interval = self._cfg.getInt(Config.STATS_REFRESH_INTERVAL, 0)
self._show_columns()
self.settings_saved.emit()
self._refresh_columns = True
def _on_menu_node_export_clicked(self, triggered):
outdir = QtWidgets.QFileDialog.getExistingDirectory(self,
@ -3508,4 +3562,6 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
except Exception as e:
print(self._address, "setQuery() exception: ", e)
finally:
self._show_columns()
if self._refresh_columns:
self._show_columns()
self._refresh_columns = False

View file

@ -168,6 +168,8 @@ class Nodes(QObject):
def get_node_config(self, addr):
try:
if addr not in self._nodes:
return None
return self._nodes[addr]['data'].config
except Exception as e:
print(self.LOG_TAG + " exception get_node_config(): ", e)

View file

@ -26,7 +26,7 @@
<enum>QTabWidget::North</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<property name="elideMode">
<enum>Qt::ElideRight</enum>
@ -515,7 +515,7 @@
<item row="1" column="1">
<widget class="QToolBox" name="toolBox_2">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="page_5">
<property name="geometry">
@ -947,7 +947,11 @@ Use ; to define multiple screens: 1;1.5 etc...</string>
</sizepolicy>
</property>
<property name="toolTip">
<string>Set the address where the GUI is listening for new nodes.</string>
<string>Set the address where the GUI is listening for new nodes.
It can be a unix socket: unix:///run/user/1000/opensnitch/osui.sock
or a network socket: 127.0.0.1:50051</string>
</property>
<property name="text">
<string>Address</string>
@ -1069,8 +1073,8 @@ Use ; to define multiple screens: 1;1.5 etc...</string>
<rect>
<x>0</x>
<y>0</y>
<width>219</width>
<height>115</height>
<width>599</width>
<height>323</height>
</rect>
</property>
<attribute name="label">
@ -1104,35 +1108,17 @@ Use ; to define multiple screens: 1;1.5 etc...</string>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QCheckBox" name="checkHideTime">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="2" column="0">
<widget class="QCheckBox" name="checkHideSrcPort">
<property name="text">
<string>Time</string>
</property>
<property name="checked">
<bool>true</bool>
<string>Source port</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="checkHideRule">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="2" column="1">
<widget class="QCheckBox" name="checkHideSrcIP">
<property name="text">
<string>Rule</string>
</property>
<property name="checked">
<bool>true</bool>
<string>Source IP</string>
</property>
</widget>
</item>
@ -1152,23 +1138,17 @@ Use ; to define multiple screens: 1;1.5 etc...</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkHideProto">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="7" column="1">
<widget class="QCheckBox" name="checkHideCmdline">
<property name="text">
<string>Protocol</string>
<string>Command line</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="0" column="2">
<widget class="QCheckBox" name="checkHideAction">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
@ -1184,8 +1164,8 @@ Use ; to define multiple screens: 1;1.5 etc...</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkHideDst">
<item row="0" column="0">
<widget class="QCheckBox" name="checkHideTime">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -1193,14 +1173,46 @@ Use ; to define multiple screens: 1;1.5 etc...</string>
</sizepolicy>
</property>
<property name="text">
<string>Destination</string>
<string>Time</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="0">
<widget class="QCheckBox" name="checkHideProto">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Protocol</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QCheckBox" name="checkHideRule">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Rule</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="checkHideProc">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -1216,16 +1228,53 @@ Use ; to define multiple screens: 1;1.5 etc...</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="checkHideCmdline">
<item row="5" column="1">
<widget class="QCheckBox" name="checkHidePID">
<property name="text">
<string>Command line</string>
<string>PID</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QCheckBox" name="checkHideDstPort">
<property name="text">
<string>Dest port</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkHideDstHost">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Dest host</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkHideDstIP">
<property name="text">
<string>Dest IP</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QCheckBox" name="checkHideUID">
<property name="text">
<string>UID</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>