Merge pull request #4896 from matrix-org/erikj/disable_room_directory

Add option to disable search room lists
This commit is contained in:
Erik Johnston 2019-03-21 10:16:54 +00:00 committed by GitHub
commit 09f991a63d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 97 additions and 3 deletions

1
changelog.d/4896.feature Normal file
View File

@ -0,0 +1 @@
Add option to disable searching of local and remote public room lists.

View File

@ -1049,6 +1049,12 @@ password_config:
# Uncomment to disable searching the public room list. When disabled
# blocks searching local and remote room lists for local and remote
# users by always returning an empty list for all queries.
#
#enable_room_list_search: false
# The `alias_creation` option controls who's allowed to create aliases # The `alias_creation` option controls who's allowed to create aliases
# on this server. # on this server.
# #

View File

@ -20,6 +20,10 @@ from ._base import Config, ConfigError
class RoomDirectoryConfig(Config): class RoomDirectoryConfig(Config):
def read_config(self, config): def read_config(self, config):
self.enable_room_list_search = config.get(
"enable_room_list_search", True,
)
alias_creation_rules = config.get("alias_creation_rules") alias_creation_rules = config.get("alias_creation_rules")
if alias_creation_rules is not None: if alias_creation_rules is not None:
@ -54,6 +58,12 @@ class RoomDirectoryConfig(Config):
def default_config(self, config_dir_path, server_name, **kwargs): def default_config(self, config_dir_path, server_name, **kwargs):
return """ return """
# Uncomment to disable searching the public room list. When disabled
# blocks searching local and remote room lists for local and remote
# users by always returning an empty list for all queries.
#
#enable_room_list_search: false
# The `alias_creation` option controls who's allowed to create aliases # The `alias_creation` option controls who's allowed to create aliases
# on this server. # on this server.
# #

View File

@ -44,6 +44,7 @@ class DirectoryHandler(BaseHandler):
self.appservice_handler = hs.get_application_service_handler() self.appservice_handler = hs.get_application_service_handler()
self.event_creation_handler = hs.get_event_creation_handler() self.event_creation_handler = hs.get_event_creation_handler()
self.config = hs.config self.config = hs.config
self.enable_room_list_search = hs.config.enable_room_list_search
self.federation = hs.get_federation_client() self.federation = hs.get_federation_client()
hs.get_federation_registry().register_query_handler( hs.get_federation_registry().register_query_handler(
@ -411,6 +412,13 @@ class DirectoryHandler(BaseHandler):
if visibility not in ["public", "private"]: if visibility not in ["public", "private"]:
raise SynapseError(400, "Invalid visibility setting") raise SynapseError(400, "Invalid visibility setting")
if visibility == "public" and not self.enable_room_list_search:
# The room list has been disabled.
raise AuthError(
403,
"This user is not permitted to publish rooms to the room list"
)
room = yield self.store.get_room(room_id) room = yield self.store.get_room(room_id)
if room is None: if room is None:
raise SynapseError(400, "Unknown room") raise SynapseError(400, "Unknown room")

View File

@ -44,6 +44,7 @@ EMPTY_THIRD_PARTY_ID = ThirdPartyInstanceID(None, None)
class RoomListHandler(BaseHandler): class RoomListHandler(BaseHandler):
def __init__(self, hs): def __init__(self, hs):
super(RoomListHandler, self).__init__(hs) super(RoomListHandler, self).__init__(hs)
self.enable_room_list_search = hs.config.enable_room_list_search
self.response_cache = ResponseCache(hs, "room_list") self.response_cache = ResponseCache(hs, "room_list")
self.remote_response_cache = ResponseCache(hs, "remote_room_list", self.remote_response_cache = ResponseCache(hs, "remote_room_list",
timeout_ms=30 * 1000) timeout_ms=30 * 1000)
@ -66,10 +67,17 @@ class RoomListHandler(BaseHandler):
appservice and network id to use an appservice specific one. appservice and network id to use an appservice specific one.
Setting to None returns all public rooms across all lists. Setting to None returns all public rooms across all lists.
""" """
if not self.enable_room_list_search:
return defer.succeed({
"chunk": [],
"total_room_count_estimate": 0,
})
logger.info( logger.info(
"Getting public room list: limit=%r, since=%r, search=%r, network=%r", "Getting public room list: limit=%r, since=%r, search=%r, network=%r",
limit, since_token, bool(search_filter), network_tuple, limit, since_token, bool(search_filter), network_tuple,
) )
if search_filter: if search_filter:
# We explicitly don't bother caching searches or requests for # We explicitly don't bother caching searches or requests for
# appservice specific lists. # appservice specific lists.
@ -441,6 +449,12 @@ class RoomListHandler(BaseHandler):
def get_remote_public_room_list(self, server_name, limit=None, since_token=None, def get_remote_public_room_list(self, server_name, limit=None, since_token=None,
search_filter=None, include_all_networks=False, search_filter=None, include_all_networks=False,
third_party_instance_id=None,): third_party_instance_id=None,):
if not self.enable_room_list_search:
defer.returnValue({
"chunk": [],
"total_room_count_estimate": 0,
})
if search_filter: if search_filter:
# We currently don't support searching across federation, so we have # We currently don't support searching across federation, so we have
# to do it manually without pagination # to do it manually without pagination

View File

@ -111,7 +111,7 @@ class TestCreateAliasACL(unittest.HomeserverTestCase):
servlets = [directory.register_servlets, room.register_servlets] servlets = [directory.register_servlets, room.register_servlets]
def prepare(self, hs, reactor, clock): def prepare(self, reactor, clock, hs):
# We cheekily override the config to add custom alias creation rules # We cheekily override the config to add custom alias creation rules
config = {} config = {}
config["alias_creation_rules"] = [ config["alias_creation_rules"] = [
@ -151,3 +151,60 @@ class TestCreateAliasACL(unittest.HomeserverTestCase):
) )
self.render(request) self.render(request)
self.assertEquals(200, channel.code, channel.result) self.assertEquals(200, channel.code, channel.result)
class TestRoomListSearchDisabled(unittest.HomeserverTestCase):
user_id = "@test:test"
servlets = [directory.register_servlets, room.register_servlets]
def prepare(self, reactor, clock, hs):
room_id = self.helper.create_room_as(self.user_id)
request, channel = self.make_request(
"PUT",
b"directory/list/room/%s" % (room_id.encode('ascii'),),
b'{}',
)
self.render(request)
self.assertEquals(200, channel.code, channel.result)
self.room_list_handler = hs.get_room_list_handler()
self.directory_handler = hs.get_handlers().directory_handler
return hs
def test_disabling_room_list(self):
self.room_list_handler.enable_room_list_search = True
self.directory_handler.enable_room_list_search = True
# Room list is enabled so we should get some results
request, channel = self.make_request(
"GET",
b"publicRooms",
)
self.render(request)
self.assertEquals(200, channel.code, channel.result)
self.assertTrue(len(channel.json_body["chunk"]) > 0)
self.room_list_handler.enable_room_list_search = False
self.directory_handler.enable_room_list_search = False
# Room list disabled so we should get no results
request, channel = self.make_request(
"GET",
b"publicRooms",
)
self.render(request)
self.assertEquals(200, channel.code, channel.result)
self.assertTrue(len(channel.json_body["chunk"]) == 0)
# Room list disabled so we shouldn't be allowed to publish rooms
room_id = self.helper.create_room_as(self.user_id)
request, channel = self.make_request(
"PUT",
b"directory/list/room/%s" % (room_id.encode('ascii'),),
b'{}',
)
self.render(request)
self.assertEquals(403, channel.code, channel.result)

View File

@ -280,7 +280,6 @@ def setup_test_homeserver(
db_config=config.database_config, db_config=config.database_config,
version_string="Synapse/tests", version_string="Synapse/tests",
database_engine=db_engine, database_engine=db_engine,
room_list_handler=object(),
tls_server_context_factory=Mock(), tls_server_context_factory=Mock(),
tls_client_options_factory=Mock(), tls_client_options_factory=Mock(),
reactor=reactor, reactor=reactor,
@ -351,7 +350,6 @@ def setup_test_homeserver(
config=config, config=config,
version_string="Synapse/tests", version_string="Synapse/tests",
database_engine=db_engine, database_engine=db_engine,
room_list_handler=object(),
tls_server_context_factory=Mock(), tls_server_context_factory=Mock(),
tls_client_options_factory=Mock(), tls_client_options_factory=Mock(),
reactor=reactor, reactor=reactor,