Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dev.gajim.org/gajim/gajim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlovetox <philipp@hoerist.com>2022-09-01 23:44:58 +0300
committerlovetox <philipp@hoerist.com>2022-09-02 10:18:10 +0300
commit60a5041df55337ba74a7240a2bfa693280ec8979 (patch)
treecc07b17062ac9d180b6afd6bd9bc29cd2a1928c1
parentbaf1686345aa763dbf5bee245c1b99ed8fb1639a (diff)
fix: Better validate message correctionscorrection
- Refactor message processing code - Introduce 5 minute message correction limit
-rw-r--r--gajim/common/const.py2
-rw-r--r--gajim/common/modules/mam.py24
-rw-r--r--gajim/common/modules/message.py46
-rw-r--r--gajim/common/modules/util.py60
-rw-r--r--gajim/common/storage/archive.py73
5 files changed, 140 insertions, 65 deletions
diff --git a/gajim/common/const.py b/gajim/common/const.py
index 734d7bcdb..e1bfee598 100644
--- a/gajim/common/const.py
+++ b/gajim/common/const.py
@@ -36,6 +36,8 @@ from gajim.common.i18n import Q_
STOP_EVENT = True
PROPAGATE_EVENT = False
+MAX_MESSAGE_CORRECTION_DELAY = 300
+
class EncryptionData(NamedTuple):
additional_data: Any = None
diff --git a/gajim/common/modules/mam.py b/gajim/common/modules/mam.py
index b0eaae21a..f7c24c84f 100644
--- a/gajim/common/modules/mam.py
+++ b/gajim/common/modules/mam.py
@@ -43,7 +43,6 @@ from gajim.common import types
from gajim.common.events import ArchivingIntervalFinished
from gajim.common.events import FeatureDiscovered
from gajim.common.events import MamMessageReceived
-from gajim.common.events import MessageUpdated
from gajim.common.events import RawMamMessageReceived
from gajim.common.const import ArchiveState, ClientState
from gajim.common.const import KindConstant
@@ -51,7 +50,7 @@ from gajim.common.const import SyncThreshold
from gajim.common.helpers import AdditionalDataDict
from gajim.common.helpers import get_retraction_text
from gajim.common.modules.misc import parse_oob
-from gajim.common.modules.misc import parse_correction
+from gajim.common.modules.util import check_if_message_correction
from gajim.common.modules.util import get_eme_message
from gajim.common.modules.util import as_task
from gajim.common.modules.base import BaseModule
@@ -311,21 +310,12 @@ class MAM(BaseModule):
'kind': kind,
}
- correct_id = parse_correction(properties)
- if correct_id is not None:
- nickname = properties.muc_nickname or properties.nickname
- app.ged.raise_event(MessageUpdated(account=self._account,
- jid=jid,
- msgtxt=properties.body,
- nickname=nickname,
- properties=properties,
- correct_id=correct_id))
- app.storage.archive.store_message_correction(
- self._account,
- jid,
- correct_id,
- properties.body,
- properties.type.is_groupchat)
+ if check_if_message_correction(properties,
+ self._account,
+ properties.jid,
+ properties.body,
+ kind,
+ self._log):
return
app.storage.archive.insert_into_logs(
diff --git a/gajim/common/modules/message.py b/gajim/common/modules/message.py
index e0cc5f027..b58fd23b4 100644
--- a/gajim/common/modules/message.py
+++ b/gajim/common/modules/message.py
@@ -32,13 +32,12 @@ from gajim.common import types
from gajim.common.events import GcMessageReceived
from gajim.common.events import MessageError
from gajim.common.events import MessageReceived
-from gajim.common.events import MessageUpdated
from gajim.common.events import RawMessageReceived
from gajim.common.helpers import AdditionalDataDict
from gajim.common.const import KindConstant
from gajim.common.modules.base import BaseModule
+from gajim.common.modules.util import check_if_message_correction
from gajim.common.modules.util import get_eme_message
-from gajim.common.modules.misc import parse_correction
from gajim.common.modules.misc import parse_oob
from gajim.common.modules.misc import parse_xhtml
from gajim.common.structs import OutgoingMessage
@@ -190,23 +189,19 @@ class Message(BaseModule):
'properties': properties,
}
- correct_id = parse_correction(properties)
- if correct_id is not None:
- nickname = properties.muc_nickname or properties.nickname
- event = MessageUpdated(account=self._account,
- jid=event_attr['jid'],
- msgtxt=msgtxt,
- nickname=nickname,
- properties=properties,
- correct_id=correct_id)
-
- app.storage.archive.store_message_correction(
- self._account,
- jid,
- correct_id,
- msgtxt,
- properties.type.is_groupchat)
- app.ged.raise_event(event)
+ if type_.is_groupchat:
+ kind = KindConstant.GC_MSG
+ elif properties.is_sent_carbon:
+ kind = KindConstant.CHAT_MSG_SENT
+ else:
+ kind = KindConstant.CHAT_MSG_RECV
+
+ if check_if_message_correction(properties,
+ self._account,
+ from_,
+ msgtxt,
+ kind,
+ self._log):
return
if type_.is_groupchat:
@@ -224,10 +219,6 @@ class Message(BaseModule):
app.ged.raise_event(MessageReceived(**event_attr))
- log_type = KindConstant.CHAT_MSG_RECV
- if properties.is_sent_carbon:
- log_type = KindConstant.CHAT_MSG_SENT
-
if not msgtxt:
return
@@ -235,7 +226,7 @@ class Message(BaseModule):
self._account,
fjid if properties.is_muc_pm else jid,
properties.timestamp,
- log_type,
+ kind,
message=msgtxt,
subject=properties.subject,
additional_data=additional_data,
@@ -399,12 +390,13 @@ class Message(BaseModule):
return
if message.correct_id is not None:
- app.storage.archive.store_message_correction(
+ app.storage.archive.try_message_correction(
self._account,
message.jid,
- message.correct_id,
+ None,
message.message,
- message.is_groupchat)
+ message.correct_id,
+ KindConstant.CHAT_MSG_SENT)
return
app.storage.archive.insert_into_logs(
diff --git a/gajim/common/modules/util.py b/gajim/common/modules/util.py
index 1faafdedd..fcddc94b2 100644
--- a/gajim/common/modules/util.py
+++ b/gajim/common/modules/util.py
@@ -19,19 +19,25 @@ from __future__ import annotations
from typing import Any
from typing import Union
+import logging
from logging import LoggerAdapter
from functools import wraps
from functools import partial
import nbxmpp
+from nbxmpp.protocol import JID
from nbxmpp.protocol import Message
from nbxmpp.structs import EMEData
from nbxmpp.structs import MessageProperties
+from nbxmpp.const import MessageType
from nbxmpp.task import Task
from gajim.common import app
from gajim.common import types
from gajim.common.const import EME_MESSAGES
+from gajim.common.const import KindConstant
+from gajim.common.events import MessageUpdated
+from gajim.common.modules.misc import parse_correction
def from_xs_boolean(value: Union[str, bool]) -> bool:
@@ -115,3 +121,57 @@ def as_task(func):
task_.start()
return task_
return func_wrapper
+
+
+def check_if_message_correction(properties: MessageProperties,
+ account: str,
+ jid: JID,
+ msgtxt: str,
+ kind: KindConstant,
+ logger: LoggerAdapter[logging.Logger]) -> bool:
+
+ correct_id = parse_correction(properties)
+ if correct_id is None:
+ return False
+
+ if properties.type not in (MessageType.GROUPCHAT, MessageType.CHAT):
+ logger.warning('Ignore correction with message type: %s',
+ properties.type)
+ return False
+
+ nickname = None
+ if properties.type.is_groupchat:
+ if jid.is_bare:
+ logger.warning(
+ 'Ignore correction from bare groupchat jid: %s', jid)
+ return False
+
+ nickname = jid.resource
+ jid = jid.new_as_bare()
+
+ elif not properties.is_muc_pm:
+ jid = jid.new_as_bare()
+
+ successful = app.storage.archive.try_message_correction(
+ account,
+ jid,
+ nickname,
+ msgtxt,
+ correct_id,
+ kind)
+
+ if not successful:
+ logger.info('Message correction not successful')
+ return False
+
+ nickname = properties.muc_nickname or properties.nickname
+
+ event = MessageUpdated(account=account,
+ jid=jid,
+ msgtxt=msgtxt,
+ nickname=nickname,
+ properties=properties,
+ correct_id=correct_id)
+
+ app.ged.raise_event(event)
+ return True
diff --git a/gajim/common/storage/archive.py b/gajim/common/storage/archive.py
index 3520d38f3..14b213544 100644
--- a/gajim/common/storage/archive.py
+++ b/gajim/common/storage/archive.py
@@ -42,6 +42,7 @@ from nbxmpp.structs import MessageProperties
from gajim.common import app
from gajim.common import configpaths
from gajim.common.helpers import AdditionalDataDict
+from gajim.common.const import MAX_MESSAGE_CORRECTION_DELAY
from gajim.common.const import ShowConstant
from gajim.common.const import KindConstant
from gajim.common.const import JIDConstant
@@ -1008,29 +1009,57 @@ class MessageArchiveStorage(SqliteStorage):
tuple(jids) + (message_id, min_time)).fetchone()
@timeit
- def store_message_correction(self,
- account: str,
- jid: JID,
- correct_id: str,
- corrected_text: str,
- is_groupchat: bool) -> None:
- type_ = JIDConstant.NORMAL_TYPE
- if is_groupchat:
- type_ = JIDConstant.ROOM_TYPE
+ def try_message_correction(self,
+ account: str,
+ jid: JID,
+ nickname: Optional[str],
+ corrected_text: str,
+ correct_id: str,
+ kind: KindConstant) -> bool:
+
+ '''Try to correct a message
+
+ :param jid: This can be a full jid or bare jid. A full jid only if the
+ message is a MUC PM, otherwise a bare jid needs to be
+ passed. `nickname` should only be passed if the message
+ is a group chat message.
+ '''
- jid_id = self.get_jid_id(str(jid), type_=type_)
account_id = self.get_account_id(account)
- sql = '''
- SELECT log_line_id, message, additional_data
- FROM logs
- WHERE +jid_id = ?
- AND account_id = ?
- AND message_id = ?
- '''
- row = self._con.execute(
- sql, (jid_id, account_id, correct_id)).fetchone()
- if row is None:
- return
+ max_timestamp = time.time() - MAX_MESSAGE_CORRECTION_DELAY
+
+ self._log.debug(
+ 'Check if message is correctable, parameters: %s %s %s %s %s',
+ jid, account_id, nickname, correct_id, max_timestamp)
+
+ sql = '''SELECT log_line_id, message, additional_data
+ FROM logs
+ NATURAL JOIN jids jid_id
+ WHERE +jid = ?
+ AND account_id = ?
+ AND contact_name IS ?
+ AND message_id = ?
+ AND kind = ?
+ AND time > ?
+ '''
+
+ rows = self._con.execute(sql, (jid,
+ account_id,
+ nickname,
+ correct_id,
+ kind,
+ max_timestamp
+ )).fetchall()
+
+ if not rows:
+ self._log.debug('No correctable messages found')
+ return False
+
+ if len(rows) != 1:
+ self._log.warning('More than one correctable message found')
+ return False
+
+ row = rows[0]
if row.additional_data is None:
additional_data = AdditionalDataDict()
@@ -1052,6 +1081,8 @@ class MessageArchiveStorage(SqliteStorage):
self._con.execute(
sql, (corrected_text, serialized_dict, row.log_line_id))
+ return True
+
@timeit
def update_additional_data(self,
account: str,