mirror of
https://github.com/element-hq/synapse.git
synced 2024-12-20 10:55:09 +03:00
Add 3PID invite support to spam checker
This commit is contained in:
parent
b7d7d20a38
commit
164798ec32
7 changed files with 51 additions and 18 deletions
|
@ -46,14 +46,19 @@ class SpamChecker(object):
|
||||||
|
|
||||||
return self.spam_checker.check_event_for_spam(event)
|
return self.spam_checker.check_event_for_spam(event)
|
||||||
|
|
||||||
def user_may_invite(self, inviter_userid, invitee_userid, room_id, new_room):
|
def user_may_invite(self, inviter_userid, invitee_userid, third_party_invite,
|
||||||
|
room_id, new_room):
|
||||||
"""Checks if a given user may send an invite
|
"""Checks if a given user may send an invite
|
||||||
|
|
||||||
If this method returns false, the invite will be rejected.
|
If this method returns false, the invite will be rejected.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
inviter_userid (str)
|
inviter_userid (str)
|
||||||
invitee_userid (str)
|
invitee_userid (str|None): The user ID of the invitee. Is None
|
||||||
|
if this is a third party invite and the 3PID is not bound to a
|
||||||
|
user ID.
|
||||||
|
invitee_userid (dict|None): If a third party invite then is a dict
|
||||||
|
containing the medium and address of the invitee.
|
||||||
room_id (str)
|
room_id (str)
|
||||||
new_room (bool): Wether the user is being invited to the room as
|
new_room (bool): Wether the user is being invited to the room as
|
||||||
part of a room creation, if so the invitee would have been
|
part of a room creation, if so the invitee would have been
|
||||||
|
@ -66,7 +71,7 @@ class SpamChecker(object):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return self.spam_checker.user_may_invite(
|
return self.spam_checker.user_may_invite(
|
||||||
inviter_userid, invitee_userid, room_id, new_room,
|
inviter_userid, invitee_userid, third_party_invite, room_id, new_room,
|
||||||
)
|
)
|
||||||
|
|
||||||
def user_may_create_room(self, userid, invite_list, third_party_invite_list,
|
def user_may_create_room(self, userid, invite_list, third_party_invite_list,
|
||||||
|
|
|
@ -1346,7 +1346,8 @@ class FederationHandler(BaseHandler):
|
||||||
raise SynapseError(403, "This server does not accept room invites")
|
raise SynapseError(403, "This server does not accept room invites")
|
||||||
|
|
||||||
if not self.spam_checker.user_may_invite(
|
if not self.spam_checker.user_may_invite(
|
||||||
event.sender, event.state_key, event.room_id, new_room=False,
|
event.sender, event.state_key, None,
|
||||||
|
room_id=event.room_id, new_room=False,
|
||||||
):
|
):
|
||||||
raise SynapseError(
|
raise SynapseError(
|
||||||
403, "This user is not permitted to send invites to this server/user"
|
403, "This user is not permitted to send invites to this server/user"
|
||||||
|
|
|
@ -661,6 +661,7 @@ class RoomCreationHandler(BaseHandler):
|
||||||
id_server,
|
id_server,
|
||||||
requester,
|
requester,
|
||||||
txn_id=None,
|
txn_id=None,
|
||||||
|
new_room=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
result = {"room_id": room_id}
|
result = {"room_id": room_id}
|
||||||
|
|
|
@ -425,7 +425,9 @@ class RoomMemberHandler(object):
|
||||||
block_invite = True
|
block_invite = True
|
||||||
|
|
||||||
if not self.spam_checker.user_may_invite(
|
if not self.spam_checker.user_may_invite(
|
||||||
requester.user.to_string(), target.to_string(), room_id,
|
requester.user.to_string(), target.to_string(),
|
||||||
|
third_party_invite=None,
|
||||||
|
room_id=room_id,
|
||||||
new_room=new_room,
|
new_room=new_room,
|
||||||
):
|
):
|
||||||
logger.info("Blocking invite due to spam checker")
|
logger.info("Blocking invite due to spam checker")
|
||||||
|
@ -728,7 +730,8 @@ class RoomMemberHandler(object):
|
||||||
address,
|
address,
|
||||||
id_server,
|
id_server,
|
||||||
requester,
|
requester,
|
||||||
txn_id
|
txn_id,
|
||||||
|
new_room=False,
|
||||||
):
|
):
|
||||||
if self.config.block_non_admin_invites:
|
if self.config.block_non_admin_invites:
|
||||||
is_requester_admin = yield self.auth.is_server_admin(
|
is_requester_admin = yield self.auth.is_server_admin(
|
||||||
|
@ -744,6 +747,20 @@ class RoomMemberHandler(object):
|
||||||
id_server, medium, address
|
id_server, medium, address
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not self.spam_checker.user_may_invite(
|
||||||
|
requester.user.to_string(), invitee,
|
||||||
|
third_party_invite={
|
||||||
|
"medium": medium,
|
||||||
|
"address": address,
|
||||||
|
},
|
||||||
|
room_id=room_id,
|
||||||
|
new_room=new_room,
|
||||||
|
):
|
||||||
|
logger.info("Blocking invite due to spam checker")
|
||||||
|
raise SynapseError(
|
||||||
|
403, "Invites have been disabled on this server",
|
||||||
|
)
|
||||||
|
|
||||||
if invitee:
|
if invitee:
|
||||||
yield self.update_membership(
|
yield self.update_membership(
|
||||||
requester,
|
requester,
|
||||||
|
|
|
@ -666,7 +666,8 @@ class RoomMembershipRestServlet(ClientV1RestServlet):
|
||||||
content["address"],
|
content["address"],
|
||||||
content["id_server"],
|
content["id_server"],
|
||||||
requester,
|
requester,
|
||||||
txn_id
|
txn_id,
|
||||||
|
new_room=False,
|
||||||
)
|
)
|
||||||
defer.returnValue((200, {}))
|
defer.returnValue((200, {}))
|
||||||
return
|
return
|
||||||
|
|
|
@ -74,13 +74,19 @@ class DomainRuleChecker(object):
|
||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def user_may_invite(self, inviter_userid, invitee_userid, room_id,
|
def user_may_invite(self, inviter_userid, invitee_userid, third_party_invite,
|
||||||
new_room):
|
room_id, new_room):
|
||||||
"""Implements synapse.events.SpamChecker.user_may_invite
|
"""Implements synapse.events.SpamChecker.user_may_invite
|
||||||
"""
|
"""
|
||||||
if self.can_only_invite_during_room_creation and not new_room:
|
if self.can_only_invite_during_room_creation and not new_room:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if not self.can_invite_by_third_party_id and third_party_invite:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if third_party_invite and not invitee_userid:
|
||||||
|
return True
|
||||||
|
|
||||||
inviter_domain = self._get_domain_from_id(inviter_userid)
|
inviter_domain = self._get_domain_from_id(inviter_userid)
|
||||||
invitee_domain = self._get_domain_from_id(invitee_userid)
|
invitee_domain = self._get_domain_from_id(invitee_userid)
|
||||||
|
|
||||||
|
|
|
@ -35,13 +35,15 @@ class DomainRuleCheckerTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
check = DomainRuleChecker(config)
|
check = DomainRuleChecker(config)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
check.user_may_invite("test:source_one", "test:target_one", "room", False)
|
check.user_may_invite(
|
||||||
|
"test:source_one", "test:target_one", None, "room", False,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
check.user_may_invite("test:source_one", "test:target_two", "room", False)
|
check.user_may_invite("test:source_one", "test:target_two", None, "room", False)
|
||||||
)
|
)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
check.user_may_invite("test:source_two", "test:target_two", "room", False)
|
check.user_may_invite("test:source_two", "test:target_two", None, "room", False)
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_disallowed(self):
|
def test_disallowed(self):
|
||||||
|
@ -55,16 +57,16 @@ class DomainRuleCheckerTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
check = DomainRuleChecker(config)
|
check = DomainRuleChecker(config)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
check.user_may_invite("test:source_one", "test:target_three", "room", False)
|
check.user_may_invite("test:source_one", "test:target_three", None, "room", False)
|
||||||
)
|
)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
check.user_may_invite("test:source_two", "test:target_three", "room", False)
|
check.user_may_invite("test:source_two", "test:target_three", None, "room", False)
|
||||||
)
|
)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
check.user_may_invite("test:source_two", "test:target_one", "room", False)
|
check.user_may_invite("test:source_two", "test:target_one", None, "room", False)
|
||||||
)
|
)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
check.user_may_invite("test:source_four", "test:target_one", "room", False)
|
check.user_may_invite("test:source_four", "test:target_one", None, "room", False)
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_default_allow(self):
|
def test_default_allow(self):
|
||||||
|
@ -77,7 +79,7 @@ class DomainRuleCheckerTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
check = DomainRuleChecker(config)
|
check = DomainRuleChecker(config)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
check.user_may_invite("test:source_three", "test:target_one", "room", False)
|
check.user_may_invite("test:source_three", "test:target_one", None, "room", False)
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_default_deny(self):
|
def test_default_deny(self):
|
||||||
|
@ -90,7 +92,7 @@ class DomainRuleCheckerTestCase(unittest.TestCase):
|
||||||
}
|
}
|
||||||
check = DomainRuleChecker(config)
|
check = DomainRuleChecker(config)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
check.user_may_invite("test:source_three", "test:target_one", "room", False)
|
check.user_may_invite("test:source_three", "test:target_one", None, "room", False)
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_config_parse(self):
|
def test_config_parse(self):
|
||||||
|
|
Loading…
Reference in a new issue