don't overwrite rules if they already exist.

Don't overwrite rules when adding or editing rules, to avoid losing
already added rules.

closes #512
This commit is contained in:
Gustavo Iñiguez Goia 2021-09-19 16:01:58 +02:00
parent 3b6c0412e0
commit c97a01d52f
4 changed files with 82 additions and 48 deletions

View file

@ -161,31 +161,6 @@ class Database:
q = QSqlQuery("delete from " + table, self.db)
q.exec_()
def empty_rule(self, name=""):
if name == "":
return
qstr = "DELETE FROM connections WHERE rule = ?"
with self._lock:
q = QSqlQuery(qstr, self.db)
q.prepare(qstr)
q.addBindValue(name)
if not q.exec_():
print("db, empty_rule() ERROR: ", qstr)
print(q.lastError().driverText())
def delete_rule(self, name, node):
qstr = "DELETE FROM rules WHERE name=? AND node=?"
with self._lock:
q = QSqlQuery(qstr, self.db)
q.prepare(qstr)
q.addBindValue(name)
q.addBindValue(node)
if not q.exec_():
print("db, delete_rule() ERROR: ", qstr)
print(q.lastError().driverText())
def clone_db(self, name):
return QSqlDatabase.cloneDatabase(self.db, name)
@ -335,3 +310,44 @@ class Database:
def get_query(self, table, fields):
return "SELECT " + fields + " FROM " + table
def empty_rule(self, name=""):
if name == "":
return
qstr = "DELETE FROM connections WHERE rule = ?"
with self._lock:
q = QSqlQuery(qstr, self.db)
q.prepare(qstr)
q.addBindValue(name)
if not q.exec_():
print("db, empty_rule() ERROR: ", qstr)
print(q.lastError().driverText())
def delete_rule(self, name, node):
qstr = "DELETE FROM rules WHERE name=? AND node=?"
with self._lock:
q = QSqlQuery(qstr, self.db)
q.prepare(qstr)
q.addBindValue(name)
q.addBindValue(node)
if not q.exec_():
print("db, delete_rule() ERROR: ", qstr)
print(q.lastError().driverText())
def get_rule(self, rule_name, node_addr=None):
"""
get rule records, given the name of the rule and the node
"""
qstr = "SELECT * from rules WHERE name=?"
if node_addr != None:
qstr = qstr + " AND node=?"
q = QSqlQuery(qstr, self.db)
q.prepare(qstr)
q.addBindValue(rule_name)
q.addBindValue(node_addr)
q.exec_()
return q

View file

@ -28,6 +28,10 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
LAN_RANGES = "^(" + others_net + "|" + classC_net + "|" + classB_net + "|" + classA_net + "|::1|f[cde].*::.*)$"
LAN_LABEL = "LAN"
ADD_RULE = 0
EDIT_RULE = 1
WORK_MODE = ADD_RULE
_notification_callback = QtCore.pyqtSignal(ui_pb2.NotificationReply)
def __init__(self, parent=None, _rule=None):
@ -150,16 +154,29 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
self.statusLabel.setText(msg)
def _cb_apply_clicked(self):
result, error = self._save_rule()
if result == False:
self._set_status_error(error)
return
if self.nodesCombo.count() == 0:
self._set_status_error(QC.translate("rules", "There're no nodes connected."))
return
rule_name = self.ruleNameEdit.text()
if rule_name == "":
return
node = self.nodesCombo.currentText()
if self._db.get_rule(rule_name, node).next() == True:
self._set_status_error(QC.translate("rules", "There's already a rule with this name."))
return
result, error = self._save_rule()
if result == False:
self._set_status_error(error)
return
self._add_rule()
self._delete_rule()
if self._old_rule_name != None and self._old_rule_name != self.rule.name:
self._delete_rule()
self._old_rule_name = rule_name
@QtCore.pyqtSlot(ui_pb2.NotificationReply)
def _cb_notification_callback(self, reply):
@ -438,21 +455,18 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
def _delete_rule(self):
try:
if self._old_rule_name != None:
# if the rule name has changed, we need to remove the old one
if self._old_rule_name != self.rule.name:
node = self.nodesCombo.currentText()
old_rule = self.rule
old_rule.name = self._old_rule_name
if self.nodeApplyAllCheck.isChecked():
nid, noti = self._nodes.delete_rule(rule_name=self._old_rule_name, addr=None, callback=self._notification_callback)
self._notifications_sent[nid] = noti
else:
nid, noti = self._nodes.delete_rule(self._old_rule_name, node, self._notification_callback)
self._notifications_sent[nid] = noti
# if the rule name has changed, we need to remove the old one
if self._old_rule_name != self.rule.name:
self._db.remove("DELETE FROM rules WHERE name='%s'" % self._old_rule_name)
old_rule = self.rule
old_rule.name = self._old_rule_name
notif_delete = ui_pb2.Notification(type=ui_pb2.DELETE_RULE, rules=[old_rule])
if self.nodeApplyAllCheck.isChecked():
nid = self._nodes.send_notifications(notif_delete, self._notification_callback)
else:
nid = self._nodes.send_notification(self.nodesCombo.currentText(), notif_delete, self._notification_callback)
self._old_rule_name = None
except Exception as e:
print(self.LOG_TAG, "delete_rule() exception: ", e)
@ -704,7 +718,7 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
if self._is_regex(self.rule.operator.data):
self.rule.operator.type = Config.RULE_TYPE_REGEXP
else:
return False, ""
return False, QC.translate("rules", "Select at least one field.")
if self.ruleNameEdit.text() == "":
self.rule.name = slugify("%s %s %s" % (self.rule.action, self.rule.operator.type, self.rule.operator.data))
@ -712,6 +726,7 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
return True, ""
def edit_rule(self, records, _addr=None):
self.WORK_MODE = self.EDIT_RULE
self._reset_state()
self.rule = self.get_rule_from_records(records)
@ -728,6 +743,7 @@ class RulesEditorDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
self.show()
def new_rule(self):
self.WORK_MODE = self.ADD_RULE
self._reset_state()
self._load_nodes()
self.show()

View file

@ -1085,8 +1085,7 @@ class StatsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0]):
get rule records, given the name of the rule and the node
"""
cur_idx = self.tabWidget.currentIndex()
records = self._db.select("SELECT * from rules WHERE name='%s' AND node='%s'" % (
rule_name, node_name))
records = self._db.get_rule(rule_name, node_name)
if records.next() == False:
print("[stats dialog] edit rule, no records: ", rule_name, node_name)
self.TABLES[cur_idx]['cmd'].click()

View file

@ -276,7 +276,10 @@ class Nodes():
rule.operator.data = ""
noti = ui_pb2.Notification(type=ui_pb2.DELETE_RULE, rules=[rule])
nid = self.send_notification(addr, noti, None)
if addr != None:
nid = self.send_notification(addr, noti, None)
else:
nid = self.send_notifications(noti, None)
self._db.delete_rule(rule.name, addr)
return nid, noti