Skip to content
Snippets Groups Projects
Commit aa620d09 authored by Richard van der Hoff's avatar Richard van der Hoff Committed by GitHub
Browse files

Add a config option to block all room invites (#2457)

- allows sysadmins the ability to lock down their servers so that people can't
send their users room invites.
parent 2eabdf3f
No related branches found
No related tags found
No related merge requests found
...@@ -519,6 +519,14 @@ class Auth(object): ...@@ -519,6 +519,14 @@ class Auth(object):
) )
def is_server_admin(self, user): def is_server_admin(self, user):
""" Check if the given user is a local server admin.
Args:
user (str): mxid of user to check
Returns:
bool: True if the user is an admin
"""
return self.store.is_server_admin(user) return self.store.is_server_admin(user)
@defer.inlineCallbacks @defer.inlineCallbacks
......
...@@ -43,6 +43,12 @@ class ServerConfig(Config): ...@@ -43,6 +43,12 @@ class ServerConfig(Config):
self.filter_timeline_limit = config.get("filter_timeline_limit", -1) self.filter_timeline_limit = config.get("filter_timeline_limit", -1)
# Whether we should block invites sent to users on this server
# (other than those sent by local server admins)
self.block_non_admin_invites = config.get(
"block_non_admin_invites", False,
)
if self.public_baseurl is not None: if self.public_baseurl is not None:
if self.public_baseurl[-1] != '/': if self.public_baseurl[-1] != '/':
self.public_baseurl += '/' self.public_baseurl += '/'
...@@ -194,6 +200,10 @@ class ServerConfig(Config): ...@@ -194,6 +200,10 @@ class ServerConfig(Config):
# and sync operations. The default value is -1, means no upper limit. # and sync operations. The default value is -1, means no upper limit.
# filter_timeline_limit: 5000 # filter_timeline_limit: 5000
# Whether room invites to users on this server should be blocked
# (except those sent by local server admins). The default is False.
# block_non_admin_invites: True
# List of ports that Synapse should listen on, their purpose and their # List of ports that Synapse should listen on, their purpose and their
# configuration. # configuration.
listeners: listeners:
......
...@@ -1074,6 +1074,9 @@ class FederationHandler(BaseHandler): ...@@ -1074,6 +1074,9 @@ class FederationHandler(BaseHandler):
if is_blocked: if is_blocked:
raise SynapseError(403, "This room has been blocked on this server") raise SynapseError(403, "This room has been blocked on this server")
if self.hs.config.block_non_admin_invites:
raise SynapseError(403, "This server does not accept room invites")
membership = event.content.get("membership") membership = event.content.get("membership")
if event.type != EventTypes.Member or membership != Membership.INVITE: if event.type != EventTypes.Member or membership != Membership.INVITE:
raise SynapseError(400, "The event was not an m.room.member invite event") raise SynapseError(400, "The event was not an m.room.member invite event")
......
...@@ -191,6 +191,8 @@ class RoomMemberHandler(BaseHandler): ...@@ -191,6 +191,8 @@ class RoomMemberHandler(BaseHandler):
if action in ["kick", "unban"]: if action in ["kick", "unban"]:
effective_membership_state = "leave" effective_membership_state = "leave"
# if this is a join with a 3pid signature, we may need to turn a 3pid
# invite into a normal invite before we can handle the join.
if third_party_signed is not None: if third_party_signed is not None:
replication = self.hs.get_replication_layer() replication = self.hs.get_replication_layer()
yield replication.exchange_third_party_invite( yield replication.exchange_third_party_invite(
...@@ -208,6 +210,16 @@ class RoomMemberHandler(BaseHandler): ...@@ -208,6 +210,16 @@ class RoomMemberHandler(BaseHandler):
if is_blocked: if is_blocked:
raise SynapseError(403, "This room has been blocked on this server") raise SynapseError(403, "This room has been blocked on this server")
if (effective_membership_state == "invite" and
self.hs.config.block_non_admin_invites):
is_requester_admin = yield self.auth.is_server_admin(
requester.user,
)
if not is_requester_admin:
raise SynapseError(
403, "Invites have been disabled on this server",
)
latest_event_ids = yield self.store.get_latest_event_ids_in_room(room_id) latest_event_ids = yield self.store.get_latest_event_ids_in_room(room_id)
current_state_ids = yield self.state_handler.get_current_state_ids( current_state_ids = yield self.state_handler.get_current_state_ids(
room_id, latest_event_ids=latest_event_ids, room_id, latest_event_ids=latest_event_ids,
...@@ -471,6 +483,16 @@ class RoomMemberHandler(BaseHandler): ...@@ -471,6 +483,16 @@ class RoomMemberHandler(BaseHandler):
requester, requester,
txn_id txn_id
): ):
if self.hs.config.block_non_admin_invites:
is_requester_admin = yield self.auth.is_server_admin(
requester.user,
)
if not is_requester_admin:
raise SynapseError(
403, "Invites have been disabled on this server",
Codes.FORBIDDEN,
)
invitee = yield self._lookup_3pid( invitee = yield self._lookup_3pid(
id_server, medium, address id_server, medium, address
) )
......
...@@ -56,6 +56,7 @@ def setup_test_homeserver(name="test", datastore=None, config=None, **kargs): ...@@ -56,6 +56,7 @@ def setup_test_homeserver(name="test", datastore=None, config=None, **kargs):
config.worker_replication_url = "" config.worker_replication_url = ""
config.worker_app = None config.worker_app = None
config.email_enable_notifs = False config.email_enable_notifs = False
config.block_non_admin_invites = False
config.use_frozen_dicts = True config.use_frozen_dicts = True
config.database_config = {"name": "sqlite3"} config.database_config = {"name": "sqlite3"}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment