mirror of
https://github.com/element-hq/synapse.git
synced 2024-11-29 15:39:00 +03:00
Fix redactions. Fix 'age' key
This commit is contained in:
parent
4d6af0dde3
commit
8cdebce470
6 changed files with 88 additions and 35 deletions
|
@ -97,6 +97,7 @@ class EventBase(object):
|
||||||
origin_server_ts = _event_dict_property("origin_server_ts")
|
origin_server_ts = _event_dict_property("origin_server_ts")
|
||||||
prev_events = _event_dict_property("prev_events")
|
prev_events = _event_dict_property("prev_events")
|
||||||
prev_state = _event_dict_property("prev_state")
|
prev_state = _event_dict_property("prev_state")
|
||||||
|
redacts = _event_dict_property("redacts")
|
||||||
room_id = _event_dict_property("room_id")
|
room_id = _event_dict_property("room_id")
|
||||||
sender = _event_dict_property("sender")
|
sender = _event_dict_property("sender")
|
||||||
state_key = _event_dict_property("state_key")
|
state_key = _event_dict_property("state_key")
|
||||||
|
|
|
@ -19,11 +19,18 @@ from synapse.types import EventID
|
||||||
|
|
||||||
from synapse.util.stringutils import random_string
|
from synapse.util.stringutils import random_string
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
|
|
||||||
class EventBuilder(EventBase):
|
class EventBuilder(EventBase):
|
||||||
def __init__(self, key_values={}):
|
def __init__(self, key_values={}):
|
||||||
|
signatures = copy.deepcopy(key_values.pop("signatures", {}))
|
||||||
|
unsigned = copy.deepcopy(key_values.pop("unsigned", {}))
|
||||||
|
|
||||||
super(EventBuilder, self).__init__(
|
super(EventBuilder, self).__init__(
|
||||||
key_values,
|
key_values,
|
||||||
|
signatures=signatures,
|
||||||
|
unsigned=unsigned
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_event_key(self, key, value):
|
def update_event_key(self, key, value):
|
||||||
|
@ -61,7 +68,7 @@ class EventBuilderFactory(object):
|
||||||
key_values.setdefault("origin", self.hostname)
|
key_values.setdefault("origin", self.hostname)
|
||||||
key_values.setdefault("origin_server_ts", time_now)
|
key_values.setdefault("origin_server_ts", time_now)
|
||||||
|
|
||||||
if "unsigned" in key_values:
|
key_values.setdefault("unsigned", {})
|
||||||
age = key_values["unsigned"].pop("age", 0)
|
age = key_values["unsigned"].pop("age", 0)
|
||||||
key_values["unsigned"].setdefault("age_ts", time_now - age)
|
key_values["unsigned"].setdefault("age_ts", time_now - age)
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,11 @@ def prune_event(event):
|
||||||
|
|
||||||
allowed_fields["content"] = new_content
|
allowed_fields["content"] = new_content
|
||||||
|
|
||||||
|
allowed_fields["unsigned"] = {}
|
||||||
|
|
||||||
|
if "age_ts" in event.unsigned:
|
||||||
|
allowed_fields["unsigned"]["age_ts"] = event.unsigned["age_ts"]
|
||||||
|
|
||||||
return type(event)(allowed_fields)
|
return type(event)(allowed_fields)
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,4 +102,20 @@ def serialize_event(hs, e):
|
||||||
|
|
||||||
d["user_id"] = d.pop("sender", None)
|
d["user_id"] = d.pop("sender", None)
|
||||||
|
|
||||||
|
if "redacted_because" in e.unsigned:
|
||||||
|
d["redacted_because"] = serialize_event(
|
||||||
|
hs, e.unsigned["redacted_because"]
|
||||||
|
)
|
||||||
|
|
||||||
|
del d["unsigned"]["redacted_because"]
|
||||||
|
|
||||||
|
if "redacted_by" in e.unsigned:
|
||||||
|
d["redacted_by"] = e.unsigned["redacted_by"]
|
||||||
|
del d["unsigned"]["redacted_by"]
|
||||||
|
|
||||||
|
del d["auth_events"]
|
||||||
|
del d["prev_events"]
|
||||||
|
del d["hashes"]
|
||||||
|
del d["signatures"]
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
|
@ -155,6 +155,12 @@ class StateHandler(object):
|
||||||
else:
|
else:
|
||||||
context.auth_events = {}
|
context.auth_events = {}
|
||||||
|
|
||||||
|
if event.is_state():
|
||||||
|
key = (event.type, event.state_key)
|
||||||
|
if key in context.current_state:
|
||||||
|
replaces = context.current_state[key]
|
||||||
|
event.unsigned["replaces_state"] = replaces.event_id
|
||||||
|
|
||||||
defer.returnValue([])
|
defer.returnValue([])
|
||||||
|
|
||||||
if event.is_state():
|
if event.is_state():
|
||||||
|
@ -177,6 +183,12 @@ class StateHandler(object):
|
||||||
prev_state
|
prev_state
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if event.is_state():
|
||||||
|
key = (event.type, event.state_key)
|
||||||
|
if key in context.current_state:
|
||||||
|
replaces = context.current_state[key]
|
||||||
|
event.unsigned["replaces_state"] = replaces.event_id
|
||||||
|
|
||||||
if hasattr(event, "auth_events") and event.auth_events:
|
if hasattr(event, "auth_events") and event.auth_events:
|
||||||
auth_ids = zip(*event.auth_events)[0]
|
auth_ids = zip(*event.auth_events)[0]
|
||||||
context.auth_events = {
|
context.auth_events = {
|
||||||
|
|
|
@ -444,38 +444,50 @@ class SQLBaseStore(object):
|
||||||
def _get_events_txn(self, txn, event_ids):
|
def _get_events_txn(self, txn, event_ids):
|
||||||
events = []
|
events = []
|
||||||
for e_id in event_ids:
|
for e_id in event_ids:
|
||||||
js = self._simple_select_one_onecol_txn(
|
ev = self._get_event_txn(txn, e_id)
|
||||||
txn,
|
|
||||||
table="event_json",
|
if ev:
|
||||||
keyvalues={"event_id": e_id},
|
events.append(ev)
|
||||||
retcol="json",
|
|
||||||
allow_none=True,
|
return events
|
||||||
|
|
||||||
|
def _get_event_txn(self, txn, event_id, check_redacted=True):
|
||||||
|
sql = (
|
||||||
|
"SELECT json, r.event_id FROM event_json as e "
|
||||||
|
"LEFT JOIN redactions as r ON e.event_id = r.redacts "
|
||||||
|
"WHERE e.event_id = ? "
|
||||||
|
"LIMIT 1 "
|
||||||
)
|
)
|
||||||
|
|
||||||
if not js:
|
txn.execute(sql, (event_id,))
|
||||||
# FIXME (erikj): What should we actually do here?
|
|
||||||
continue
|
res = txn.fetchone()
|
||||||
|
|
||||||
|
if not res:
|
||||||
|
return None
|
||||||
|
|
||||||
|
js, redacted = res
|
||||||
|
|
||||||
d = json.loads(js)
|
d = json.loads(js)
|
||||||
|
|
||||||
ev = FrozenEvent(d)
|
ev = FrozenEvent(d)
|
||||||
|
|
||||||
if hasattr(ev, "redacted") and ev.redacted:
|
if check_redacted and redacted:
|
||||||
# Get the redaction event.
|
ev = prune_event(ev)
|
||||||
select_event_sql = "SELECT * FROM events WHERE event_id = ?"
|
|
||||||
txn.execute(select_event_sql, (ev.redacted,))
|
|
||||||
|
|
||||||
del_evs = self._parse_events_txn(
|
ev.unsigned["redacted_by"] = redacted
|
||||||
txn, self.cursor_to_dict(txn)
|
# Get the redaction event.
|
||||||
|
|
||||||
|
because = self._get_event_txn(
|
||||||
|
txn,
|
||||||
|
redacted,
|
||||||
|
check_redacted=False
|
||||||
)
|
)
|
||||||
|
|
||||||
if del_evs:
|
if because:
|
||||||
ev = prune_event(ev)
|
ev.unsigned["redacted_because"] = because
|
||||||
ev.redacted_because = del_evs[0]
|
|
||||||
|
|
||||||
events.append(ev)
|
return ev
|
||||||
|
|
||||||
return events
|
|
||||||
|
|
||||||
def _parse_events(self, rows):
|
def _parse_events(self, rows):
|
||||||
return self.runInteraction(
|
return self.runInteraction(
|
||||||
|
|
|
@ -149,7 +149,7 @@ class RedactionTestCase(unittest.TestCase):
|
||||||
event,
|
event,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertFalse(hasattr(event, "redacted_because"))
|
self.assertFalse("redacted_because" in event.unsigned)
|
||||||
|
|
||||||
# Redact event
|
# Redact event
|
||||||
reason = "Because I said so"
|
reason = "Because I said so"
|
||||||
|
@ -179,7 +179,7 @@ class RedactionTestCase(unittest.TestCase):
|
||||||
event,
|
event,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(hasattr(event, "redacted_because"))
|
self.assertTrue("redacted_because" in event.unsigned)
|
||||||
|
|
||||||
self.assertObjectHasAttributes(
|
self.assertObjectHasAttributes(
|
||||||
{
|
{
|
||||||
|
@ -187,7 +187,7 @@ class RedactionTestCase(unittest.TestCase):
|
||||||
"user_id": self.u_alice.to_string(),
|
"user_id": self.u_alice.to_string(),
|
||||||
"content": {"reason": reason},
|
"content": {"reason": reason},
|
||||||
},
|
},
|
||||||
event.redacted_because,
|
event.unsigned["redacted_because"],
|
||||||
)
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
|
|
Loading…
Reference in a new issue