11
11
from tests .integration .common_utils .test_models import DATestUser
12
12
13
13
14
- def test_multi_tenant_access_control (reset_multitenant : None ) -> None :
15
- # Creating an admin user (first user created is automatically an admin and also proviions the tenant
14
+ def setup_test_tenants (reset_multitenant : None ):
15
+ """Helper function to set up test tenants with documents and users."""
16
+ # Creating an admin user for Tenant 1
16
17
admin_user1 : DATestUser = UserManager .create (
17
18
18
19
)
19
-
20
20
assert UserManager .is_role (admin_user1 , UserRole .ADMIN )
21
21
22
22
# Create Tenant 2 and its Admin User
@@ -35,6 +35,16 @@ def test_multi_tenant_access_control(reset_multitenant: None) -> None:
35
35
api_key_1 .headers .update (admin_user1 .headers )
36
36
LLMProviderManager .create (user_performing_action = admin_user1 )
37
37
38
+ # Create connectors for Tenant 2
39
+ cc_pair_2 : DATestCCPair = CCPairManager .create_from_scratch (
40
+ user_performing_action = admin_user2 ,
41
+ )
42
+ api_key_2 : DATestAPIKey = APIKeyManager .create (
43
+ user_performing_action = admin_user2 ,
44
+ )
45
+ api_key_2 .headers .update (admin_user2 .headers )
46
+ LLMProviderManager .create (user_performing_action = admin_user2 )
47
+
38
48
# Seed documents for Tenant 1
39
49
cc_pair_1 .documents = []
40
50
doc1_tenant1 = DocumentManager .seed_doc_with_content (
@@ -49,16 +59,6 @@ def test_multi_tenant_access_control(reset_multitenant: None) -> None:
49
59
)
50
60
cc_pair_1 .documents .extend ([doc1_tenant1 , doc2_tenant1 ])
51
61
52
- # Create connectors for Tenant 2
53
- cc_pair_2 : DATestCCPair = CCPairManager .create_from_scratch (
54
- user_performing_action = admin_user2 ,
55
- )
56
- api_key_2 : DATestAPIKey = APIKeyManager .create (
57
- user_performing_action = admin_user2 ,
58
- )
59
- api_key_2 .headers .update (admin_user2 .headers )
60
- LLMProviderManager .create (user_performing_action = admin_user2 )
61
-
62
62
# Seed documents for Tenant 2
63
63
cc_pair_2 .documents = []
64
64
doc1_tenant2 = DocumentManager .seed_doc_with_content (
@@ -84,21 +84,36 @@ def test_multi_tenant_access_control(reset_multitenant: None) -> None:
84
84
user_performing_action = admin_user2
85
85
)
86
86
87
+ return {
88
+ "admin_user1" : admin_user1 ,
89
+ "admin_user2" : admin_user2 ,
90
+ "chat_session1" : chat_session1 ,
91
+ "chat_session2" : chat_session2 ,
92
+ "tenant1_doc_ids" : tenant1_doc_ids ,
93
+ "tenant2_doc_ids" : tenant2_doc_ids ,
94
+ }
95
+
96
+
97
+ def test_tenant1_can_access_own_documents (reset_multitenant : None ) -> None :
98
+ """Test that Tenant 1 can access its own documents but not Tenant 2's."""
99
+ test_data = setup_test_tenants (reset_multitenant )
100
+
87
101
# User 1 sends a message and gets a response
88
102
response1 = ChatSessionManager .send_message (
89
- chat_session_id = chat_session1 .id ,
103
+ chat_session_id = test_data [ " chat_session1" ] .id ,
90
104
message = "What is in Tenant 1's documents?" ,
91
- user_performing_action = admin_user1 ,
105
+ user_performing_action = test_data [ " admin_user1" ] ,
92
106
)
107
+
93
108
# Assert that the search tool was used
94
109
assert response1 .tool_name == "run_search"
95
110
96
111
response_doc_ids = {doc ["document_id" ] for doc in response1 .tool_result or []}
97
- assert tenant1_doc_ids .issubset (
112
+ assert test_data [ " tenant1_doc_ids" ] .issubset (
98
113
response_doc_ids
99
114
), "Not all Tenant 1 document IDs are in the response"
100
115
assert not response_doc_ids .intersection (
101
- tenant2_doc_ids
116
+ test_data [ " tenant2_doc_ids" ]
102
117
), "Tenant 2 document IDs should not be in the response"
103
118
104
119
# Assert that the contents are correct
@@ -107,21 +122,28 @@ def test_multi_tenant_access_control(reset_multitenant: None) -> None:
107
122
for doc in response1 .tool_result or []
108
123
), "Tenant 1 Document Content not found in any document"
109
124
125
+
126
+ def test_tenant2_can_access_own_documents (reset_multitenant : None ) -> None :
127
+ """Test that Tenant 2 can access its own documents but not Tenant 1's."""
128
+ test_data = setup_test_tenants (reset_multitenant )
129
+
110
130
# User 2 sends a message and gets a response
111
131
response2 = ChatSessionManager .send_message (
112
- chat_session_id = chat_session2 .id ,
132
+ chat_session_id = test_data [ " chat_session2" ] .id ,
113
133
message = "What is in Tenant 2's documents?" ,
114
- user_performing_action = admin_user2 ,
134
+ user_performing_action = test_data [ " admin_user2" ] ,
115
135
)
136
+
116
137
# Assert that the search tool was used
117
138
assert response2 .tool_name == "run_search"
139
+
118
140
# Assert that the tool_result contains Tenant 2's documents
119
141
response_doc_ids = {doc ["document_id" ] for doc in response2 .tool_result or []}
120
- assert tenant2_doc_ids .issubset (
142
+ assert test_data [ " tenant2_doc_ids" ] .issubset (
121
143
response_doc_ids
122
144
), "Not all Tenant 2 document IDs are in the response"
123
145
assert not response_doc_ids .intersection (
124
- tenant1_doc_ids
146
+ test_data [ " tenant1_doc_ids" ]
125
147
), "Tenant 1 document IDs should not be in the response"
126
148
127
149
# Assert that the contents are correct
@@ -130,28 +152,91 @@ def test_multi_tenant_access_control(reset_multitenant: None) -> None:
130
152
for doc in response2 .tool_result or []
131
153
), "Tenant 2 Document Content not found in any document"
132
154
155
+
156
+ def test_tenant1_cannot_access_tenant2_documents (reset_multitenant : None ) -> None :
157
+ """Test that Tenant 1 cannot access Tenant 2's documents."""
158
+ test_data = setup_test_tenants (reset_multitenant )
159
+
133
160
# User 1 tries to access Tenant 2's documents
134
161
response_cross = ChatSessionManager .send_message (
135
- chat_session_id = chat_session1 .id ,
162
+ chat_session_id = test_data [ " chat_session1" ] .id ,
136
163
message = "What is in Tenant 2's documents?" ,
137
- user_performing_action = admin_user1 ,
164
+ user_performing_action = test_data [ " admin_user1" ] ,
138
165
)
166
+
139
167
# Assert that the search tool was used
140
168
assert response_cross .tool_name == "run_search"
169
+
141
170
# Assert that the tool_result is empty or does not contain Tenant 2's documents
142
171
response_doc_ids = {doc ["document_id" ] for doc in response_cross .tool_result or []}
172
+
143
173
# Ensure none of Tenant 2's document IDs are in the response
144
- assert not response_doc_ids .intersection (tenant2_doc_ids )
174
+ assert not response_doc_ids .intersection (test_data ["tenant2_doc_ids" ])
175
+
176
+
177
+ def test_tenant2_cannot_access_tenant1_documents (reset_multitenant : None ) -> None :
178
+ """Test that Tenant 2 cannot access Tenant 1's documents."""
179
+ test_data = setup_test_tenants (reset_multitenant )
145
180
146
181
# User 2 tries to access Tenant 1's documents
147
182
response_cross2 = ChatSessionManager .send_message (
148
- chat_session_id = chat_session2 .id ,
183
+ chat_session_id = test_data [ " chat_session2" ] .id ,
149
184
message = "What is in Tenant 1's documents?" ,
150
- user_performing_action = admin_user2 ,
185
+ user_performing_action = test_data [ " admin_user2" ] ,
151
186
)
187
+
152
188
# Assert that the search tool was used
153
189
assert response_cross2 .tool_name == "run_search"
190
+
154
191
# Assert that the tool_result is empty or does not contain Tenant 1's documents
155
192
response_doc_ids = {doc ["document_id" ] for doc in response_cross2 .tool_result or []}
193
+
156
194
# Ensure none of Tenant 1's document IDs are in the response
157
- assert not response_doc_ids .intersection (tenant1_doc_ids )
195
+ assert not response_doc_ids .intersection (test_data ["tenant1_doc_ids" ])
196
+
197
+
198
+ def test_multi_tenant_access_control (reset_multitenant : None ) -> None :
199
+ """Legacy test for multi-tenant access control."""
200
+ test_data = setup_test_tenants (reset_multitenant )
201
+
202
+ # User 1 sends a message and gets a response with only Tenant 1's documents
203
+ response1 = ChatSessionManager .send_message (
204
+ chat_session_id = test_data ["chat_session1" ].id ,
205
+ message = "What is in Tenant 1's documents?" ,
206
+ user_performing_action = test_data ["admin_user1" ],
207
+ )
208
+ assert response1 .tool_name == "run_search"
209
+ response_doc_ids = {doc ["document_id" ] for doc in response1 .tool_result or []}
210
+ assert test_data ["tenant1_doc_ids" ].issubset (response_doc_ids )
211
+ assert not response_doc_ids .intersection (test_data ["tenant2_doc_ids" ])
212
+
213
+ # User 2 sends a message and gets a response with only Tenant 2's documents
214
+ response2 = ChatSessionManager .send_message (
215
+ chat_session_id = test_data ["chat_session2" ].id ,
216
+ message = "What is in Tenant 2's documents?" ,
217
+ user_performing_action = test_data ["admin_user2" ],
218
+ )
219
+ assert response2 .tool_name == "run_search"
220
+ response_doc_ids = {doc ["document_id" ] for doc in response2 .tool_result or []}
221
+ assert test_data ["tenant2_doc_ids" ].issubset (response_doc_ids )
222
+ assert not response_doc_ids .intersection (test_data ["tenant1_doc_ids" ])
223
+
224
+ # User 1 tries to access Tenant 2's documents and fails
225
+ response_cross = ChatSessionManager .send_message (
226
+ chat_session_id = test_data ["chat_session1" ].id ,
227
+ message = "What is in Tenant 2's documents?" ,
228
+ user_performing_action = test_data ["admin_user1" ],
229
+ )
230
+ assert response_cross .tool_name == "run_search"
231
+ response_doc_ids = {doc ["document_id" ] for doc in response_cross .tool_result or []}
232
+ assert not response_doc_ids .intersection (test_data ["tenant2_doc_ids" ])
233
+
234
+ # User 2 tries to access Tenant 1's documents and fails
235
+ response_cross2 = ChatSessionManager .send_message (
236
+ chat_session_id = test_data ["chat_session2" ].id ,
237
+ message = "What is in Tenant 1's documents?" ,
238
+ user_performing_action = test_data ["admin_user2" ],
239
+ )
240
+ assert response_cross2 .tool_name == "run_search"
241
+ response_doc_ids = {doc ["document_id" ] for doc in response_cross2 .tool_result or []}
242
+ assert not response_doc_ids .intersection (test_data ["tenant1_doc_ids" ])
0 commit comments