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

Commit

Permalink
Merge pull request #6004 from matrix-org/jaywink/autojoin-create-real…
Browse files Browse the repository at this point in the history
…-users
  • Loading branch information
anoadragon453 committed Feb 25, 2020
2 parents 6bedb3f + 63f9317 commit e75de41
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 10 deletions.
1 change: 1 addition & 0 deletions changelog.d/6004.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Only count real users when checking for auto-creation of auto-join room.
12 changes: 4 additions & 8 deletions synapse/handlers/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,16 +296,12 @@ def _auto_join_rooms(self, user_id):
fake_requester = create_requester(user_id)

# try to create the room if we're the first real user on the server. Note
# that an auto-generated support user is not a real user and will never be
# that an auto-generated support or bot user is not a real user and will never be
# the user to create the room
should_auto_create_rooms = False
is_support = yield self.store.is_support_user(user_id)
# There is an edge case where the first user is the support user, then
# the room is never created, though this seems unlikely and
# recoverable from given the support user being involved in the first
# place.
if self.hs.config.autocreate_auto_join_rooms and not is_support:
count = yield self.store.count_all_users()
is_real_user = yield self.store.is_real_user(user_id)
if self.hs.config.autocreate_auto_join_rooms and is_real_user:
count = yield self.store.count_real_users()
should_auto_create_rooms = count == 1
for r in self.hs.config.auto_join_rooms:
logger.info("Auto-joining %s to %s", user_id, r)
Expand Down
37 changes: 37 additions & 0 deletions synapse/storage/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,19 @@ def _query_for_auth(self, txn, token):

return None

@cachedInlineCallbacks()
def is_real_user(self, user_id):
"""Determines if the user is a real user, ie does not have a 'user_type'.
Args:
user_id (str): user id to test
Returns:
Deferred[bool]: True if user 'user_type' is null or empty string
"""
res = yield self.runInteraction("is_real_user", self.is_real_user_txn, user_id)
return res

@cachedInlineCallbacks()
def is_support_user(self, user_id):
"""Determines if the user is of type UserTypes.SUPPORT
Expand All @@ -359,6 +372,16 @@ def is_support_user(self, user_id):
)
return res

def is_real_user_txn(self, txn, user_id):
res = self._simple_select_one_onecol_txn(
txn=txn,
table="users",
keyvalues={"name": user_id},
retcol="user_type",
allow_none=True,
)
return res is None

def is_support_user_txn(self, txn, user_id):
res = self._simple_select_one_onecol_txn(
txn=txn,
Expand Down Expand Up @@ -443,6 +466,20 @@ def _count_users(txn):
ret = yield self.runInteraction("count_users", _count_users)
return ret

@defer.inlineCallbacks
def count_real_users(self):
"""Counts all users without a special user_type registered on the homeserver."""

def _count_users(txn):
txn.execute("SELECT COUNT(*) AS users FROM users where user_type is null")
rows = self.cursor_to_dict(txn)
if rows:
return rows[0]["users"]
return 0

ret = yield self.runInteraction("count_real_users", _count_users)
return ret

@defer.inlineCallbacks
def find_next_generated_user_id_localpart(self):
"""
Expand Down
29 changes: 27 additions & 2 deletions tests/handlers/test_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,18 +172,43 @@ def test_auto_create_auto_join_where_auto_create_is_false(self):
rooms = self.get_success(self.store.get_rooms_for_user(user_id))
self.assertEqual(len(rooms), 0)

def test_auto_create_auto_join_rooms_when_support_user_exists(self):
def test_auto_create_auto_join_rooms_when_user_is_not_a_real_user(self):
room_alias_str = "#room:test"
self.hs.config.auto_join_rooms = [room_alias_str]

self.store.is_support_user = Mock(return_value=True)
self.store.is_real_user = Mock(return_value=False)
user_id = self.get_success(self.handler.register_user(localpart="support"))
rooms = self.get_success(self.store.get_rooms_for_user(user_id))
self.assertEqual(len(rooms), 0)
directory_handler = self.hs.get_handlers().directory_handler
room_alias = RoomAlias.from_string(room_alias_str)
self.get_failure(directory_handler.get_association(room_alias), SynapseError)

def test_auto_create_auto_join_rooms_when_user_is_the_first_real_user(self):
room_alias_str = "#room:test"
self.hs.config.auto_join_rooms = [room_alias_str]

self.store.count_real_users = Mock(return_value=1)
self.store.is_real_user = Mock(return_value=True)
user_id = self.get_success(self.handler.register_user(localpart="real"))
rooms = self.get_success(self.store.get_rooms_for_user(user_id))
directory_handler = self.hs.get_handlers().directory_handler
room_alias = RoomAlias.from_string(room_alias_str)
room_id = self.get_success(directory_handler.get_association(room_alias))

self.assertTrue(room_id["room_id"] in rooms)
self.assertEqual(len(rooms), 1)

def test_auto_create_auto_join_rooms_when_user_is_not_the_first_real_user(self):
room_alias_str = "#room:test"
self.hs.config.auto_join_rooms = [room_alias_str]

self.store.count_real_users = Mock(return_value=2)
self.store.is_real_user = Mock(return_value=True)
user_id = self.get_success(self.handler.register_user(localpart="real"))
rooms = self.get_success(self.store.get_rooms_for_user(user_id))
self.assertEqual(len(rooms), 0)

def test_auto_create_auto_join_where_no_consent(self):
"""Test to ensure that the first user is not auto-joined to a room if
they have not given general consent.
Expand Down

0 comments on commit e75de41

Please sign in to comment.