1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414from typing import Dict , List , Set , Tuple
15+ from unittest .mock import Mock , patch
1516
1617from twisted .test .proto_helpers import MemoryReactor
1718
19+ from synapse .api .constants import UserTypes
20+ from synapse .appservice import ApplicationService
1821from synapse .rest import admin
19- from synapse .rest .client import login , room
22+ from synapse .rest .client import login , register , room
2023from synapse .server import HomeServer
2124from synapse .storage import DataStore
2225from synapse .util import Clock
@@ -64,6 +67,14 @@ async def get_users_who_share_private_rooms(self) -> List[Dict[str, str]]:
6467 ["user_id" , "other_user_id" , "room_id" ],
6568 )
6669
70+ async def get_users_in_user_directory (self ) -> Set [str ]:
71+ result = await self .store .db_pool .simple_select_list (
72+ "user_directory" ,
73+ None ,
74+ ["user_id" ],
75+ )
76+ return {row ["user_id" ] for row in result }
77+
6778
6879class UserDirectoryInitialPopulationTestcase (HomeserverTestCase ):
6980 """Ensure that rebuilding the directory writes the correct data to the DB.
@@ -74,10 +85,28 @@ class UserDirectoryInitialPopulationTestcase(HomeserverTestCase):
7485
7586 servlets = [
7687 login .register_servlets ,
77- admin .register_servlets_for_client_rest_resource ,
88+ admin .register_servlets ,
7889 room .register_servlets ,
90+ register .register_servlets ,
7991 ]
8092
93+ def make_homeserver (self , reactor : MemoryReactor , clock : Clock ) -> HomeServer :
94+ self .appservice = ApplicationService (
95+ token = "i_am_an_app_service" ,
96+ hostname = "test" ,
97+ id = "1234" ,
98+ namespaces = {"users" : [{"regex" : r"@as_user.*" , "exclusive" : True }]},
99+ sender = "@as:test" ,
100+ )
101+
102+ mock_load_appservices = Mock (return_value = [self .appservice ])
103+ with patch (
104+ "synapse.storage.databases.main.appservice.load_appservices" ,
105+ mock_load_appservices ,
106+ ):
107+ hs = super ().make_homeserver (reactor , clock )
108+ return hs
109+
81110 def prepare (self , reactor : MemoryReactor , clock : Clock , hs : HomeServer ) -> None :
82111 self .store = hs .get_datastore ()
83112 self .user_dir_helper = GetUserDirectoryTables (self .store )
@@ -204,6 +233,68 @@ def test_initial(self) -> None:
204233 {(u1 , u3 , private_room ), (u3 , u1 , private_room )},
205234 )
206235
236+ def test_population_excludes_support_user (self ) -> None :
237+ support = "@support1:test"
238+ self .get_success (
239+ self .store .register_user (
240+ user_id = support , password_hash = None , user_type = UserTypes .SUPPORT
241+ )
242+ )
243+ # Check the support user is not in the directory.
244+ users = self .get_success (self .user_dir_helper .get_users_in_user_directory ())
245+ self .assertEqual (users , set ())
246+
247+ # TODO add support user to a public and private room. Check that
248+ # users_in_public_rooms and users_who_share_private_rooms is empty.
249+
250+ # Rebuild the directory. It should still exclude the support user.
251+ self ._purge_and_rebuild_user_dir ()
252+ users = self .get_success (self .user_dir_helper .get_users_in_user_directory ())
253+ self .assertEqual (users , set ())
254+
255+ def test_population_excludes_deactivated_user (self ) -> None :
256+ user = self .register_user ("naughty" , "pass" )
257+ admin = self .register_user ("admin" , "pass" , admin = True )
258+ admin_token = self .login (admin , "pass" )
259+
260+ # Directory contains both users to start with.
261+ users = self .get_success (self .user_dir_helper .get_users_in_user_directory ())
262+ self .assertEqual (users , {admin , user })
263+
264+ # Deactivate the user.
265+ channel = self .make_request (
266+ "PUT" ,
267+ f"/_synapse/admin/v2/users/{ user } " ,
268+ access_token = admin_token ,
269+ content = {"deactivated" : True },
270+ )
271+ self .assertEqual (channel .code , 200 )
272+ self .assertEqual (channel .json_body ["deactivated" ], True )
273+
274+ # They should no longer be in the directory.
275+ users = self .get_success (self .user_dir_helper .get_users_in_user_directory ())
276+ self .assertEqual (users , {admin })
277+
278+ # Rebuild the user dir. The deactivated user should still be missing.
279+ self ._purge_and_rebuild_user_dir ()
280+ users = self .get_success (self .user_dir_helper .get_users_in_user_directory ())
281+ self .assertEqual (users , {admin })
282+
283+ def test_population_excludes_appservice_user (self ) -> None :
284+ # Register an AS user.
285+ self .register_appservice_user ("as_user_potato" , self .appservice .token )
286+ # TODO put this user in a public and private room with someone else
287+
288+ users = self .get_success (self .user_dir_helper .get_users_in_user_directory ())
289+ self .assertEqual (users , set ())
290+ # TODO assert the room sharing tables are as expected
291+
292+ self ._purge_and_rebuild_user_dir ()
293+
294+ # TODO assert the room sharing tables are as expected
295+ users = self .get_success (self .user_dir_helper .get_users_in_user_directory ())
296+ self .assertEqual (users , set ())
297+
207298
208299class UserDirectoryStoreTestCase (HomeserverTestCase ):
209300 def prepare (self , reactor : MemoryReactor , clock : Clock , hs : HomeServer ) -> None :
0 commit comments