@@ -165,6 +165,57 @@ def test_dashboard_create_workspace_succeeds_when_unbound(monkeypatch, tmp_path)
165165 assert response .json ()["created" ] is True
166166
167167
168+ def test_dashboard_preserves_hosted_principal_for_personal_access (
169+ monkeypatch , tmp_path ,
170+ ):
171+ import anyio
172+ import httpx
173+
174+ from engraphis .dashboard_app import create_app
175+ from engraphis .service import current_user , set_current_user
176+ from engraphis .service_context import bind_service
177+
178+ monkeypatch .setattr (settings , "db_path" , str (tmp_path / "hosted-dashboard.db" ))
179+ monkeypatch .setattr (settings , "embed_model" , "" )
180+ monkeypatch .setattr (settings , "embed_dim" , 384 )
181+ monkeypatch .setattr (settings , "allowed_workspaces" , [])
182+ monkeypatch .setattr (settings , "api_token" , "" )
183+ app = create_app ()
184+ hosted = MemoryService .create (":memory:" , extractor = "none" )
185+ owner = {"id" : "member_bob" , "email" : "bob@example.test" , "role" : "member" }
186+ principal = {"id" : "member_alice" , "email" : "alice@example.test" , "role" : "member" }
187+ set_current_user (owner )
188+ hosted .create_workspace ("bob-private" , visibility = "personal" )
189+ set_current_user (None )
190+
191+ @app .get ("/api/test-hosted-personal" , include_in_schema = False )
192+ def hosted_personal_probe ():
193+ from engraphis .routes .v2_api import service
194+ from engraphis .service import ValidationError
195+
196+ try :
197+ service ()._enforce_personal_access ("bob-private" )
198+ except ValidationError :
199+ allowed = False
200+ else :
201+ allowed = True
202+ return {"allowed" : allowed , "user" : current_user ()}
203+
204+ async def request_probe ():
205+ transport = httpx .ASGITransport (app = app , client = ("127.0.0.1" , 50000 ))
206+ async with httpx .AsyncClient (transport = transport , base_url = "http://test" ) as client :
207+ return await client .get ("/api/test-hosted-personal" )
208+
209+ try :
210+ with bind_service (hosted , principal = principal ):
211+ response = anyio .run (request_probe )
212+ assert response .status_code == 200 , response .text
213+ assert response .json () == {"allowed" : False , "user" : principal }
214+ finally :
215+ hosted .close ()
216+ app .state .service .close ()
217+
218+
168219def test_dashboard_ignores_legacy_workspace_binding_setting (monkeypatch , tmp_path ):
169220 monkeypatch .setattr (settings , "db_path" , str (tmp_path / "legacy-binding.db" ))
170221 monkeypatch .setattr (settings , "embed_model" , "" )
0 commit comments