Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Add knock information in admin exported data #11171

Merged
merged 9 commits into from
Oct 28, 2021
1 change: 1 addition & 0 deletions changelog.d/11171.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add knock information in admin export. Contributed by Rafael Gonçalves.
12 changes: 12 additions & 0 deletions synapse/app/admin_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ def write_invite(self, room_id, event, state):
for event in state.values():
print(json.dumps(event), file=f)

def write_knock(self, room_id, event, state):
self.write_events(room_id, [event])

room_directory = os.path.join(self.base_directory, "rooms", room_id)
squahtx marked this conversation as resolved.
Show resolved Hide resolved
os.makedirs(room_directory, exist_ok=True)

knock_state = os.path.join(room_directory, "knock_state")

with open(knock_state, "a") as f:
for event in state.values():
print(json.dumps(event), file=f)

def finished(self):
return self.base_directory

Expand Down
9 changes: 9 additions & 0 deletions synapse/handlers/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ async def export_user_data(self, user_id: str, writer: "ExfiltrationWriter") ->
Membership.LEAVE,
Membership.BAN,
Membership.INVITE,
Membership.KNOCK,
),
)

Expand Down Expand Up @@ -122,8 +123,16 @@ async def export_user_data(self, user_id: str, writer: "ExfiltrationWriter") ->
invited_state = invite.unsigned["invite_room_state"]
writer.write_invite(room_id, invite, invited_state)

if room.membership == Membership.KNOCK:
event_id = room.event_id
knock = await self.store.get_event(event_id, allow_none=True)
if knock:
knock_state = knock.unsigned["knock_room_state"]
writer.write_knock(room_id, knock, knock_state)

continue


squahtx marked this conversation as resolved.
Show resolved Hide resolved
# We only want to bother fetching events up to the last time they
# were joined. We estimate that point by looking at the
# stream_ordering of the last membership if it wasn't a join.
Expand Down
35 changes: 33 additions & 2 deletions tests/handlers/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@

import synapse.rest.admin
import synapse.storage
from synapse.api.constants import EventTypes
from synapse.rest.client import login, room
from synapse.api.constants import EventTypes, JoinRules
from synapse.api.room_versions import RoomVersions
from synapse.rest.client import login, room, knock

from tests import unittest

Expand All @@ -28,6 +29,7 @@ class ExfiltrateData(unittest.HomeserverTestCase):
synapse.rest.admin.register_servlets_for_client_rest_resource,
login.register_servlets,
room.register_servlets,
knock.register_servlets,
]

def prepare(self, reactor, clock, hs):
Expand Down Expand Up @@ -201,3 +203,32 @@ def test_invite(self):
self.assertEqual(args[0], room_id)
self.assertEqual(args[1].content["membership"], "invite")
self.assertTrue(args[2]) # Assert there is at least one bit of state

def test_knock(self):
"""Tests that knock get handled correctly."""
# create a knockable v7 room
room_id = self.helper.create_room_as(
self.user1, room_version=RoomVersions.V7.identifier, tok=self.token1
)
self.helper.send_state(
room_id,
EventTypes.JoinRules,
{"join_rule": JoinRules.KNOCK},
tok=self.token1,
)

self.helper.send(room_id, body="Hello!", tok=self.token1)
self.helper.knock(room_id, self.user2, tok=self.token2)

writer = Mock()

self.get_success(self.admin_handler.export_user_data(self.user2, writer))

writer.write_events.assert_not_called()
writer.write_state.assert_not_called()
writer.write_knock.assert_called_once()

args = writer.write_knock.call_args[0]
self.assertEqual(args[0], room_id)
self.assertEqual(args[1].content["membership"], "knock")
self.assertTrue(args[2])
squahtx marked this conversation as resolved.
Show resolved Hide resolved
29 changes: 29 additions & 0 deletions tests/rest/client/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,35 @@ def join(self, room=None, user=None, expect_code=200, tok=None):
expect_code=expect_code,
)


def knock(self, room=None, user=None, expect_code=200, tok=None):
temp_id = self.auth_user_id
self.auth_user_id = user
path = "/knock/%s" % room
if tok:
path = path + "?access_token=%s" % tok

data = {"membership": "knock"}
squahtx marked this conversation as resolved.
Show resolved Hide resolved

channel = make_request(
self.hs.get_reactor(),
self.site,
"POST",
path,
json.dumps(data).encode("utf8"),
)

assert (
int(channel.result["code"]) == expect_code
), "Expected: %d, got: %d, resp: %r" % (
expect_code,
int(channel.result["code"]),
channel.result["body"],
)

self.auth_user_id = temp_id


def leave(self, room=None, user=None, expect_code=200, tok=None):
self.change_membership(
room=room,
Expand Down