Kennedy Johnson Cursor commited on
Commit
a6b00c6
·
1 Parent(s): 877f148

Fix guest sign-in failing on invalid .local email.

Browse files

EmailStr rejected guest-*@guest.launchpad.local, so POST /auth/guest always returned 500.

Co-authored-by: Cursor <cursoragent@cursor.com>

multi_llm_chatbot_backend/app/api/routes/auth.py CHANGED
@@ -184,7 +184,10 @@ async def guest_login():
184
  try:
185
  db = get_database()
186
  guest_id = uuid.uuid4().hex[:12]
187
- email = f"guest-{guest_id}@guest.launchpad.local"
 
 
 
188
  user = User(
189
  firstName="Guest",
190
  lastName="Explorer",
 
184
  try:
185
  db = get_database()
186
  guest_id = uuid.uuid4().hex[:12]
187
+ # Must be a syntactically valid email: EmailStr / email-validator
188
+ # rejects reserved TLDs like `.local`, which previously made guest
189
+ # sign-in always 500.
190
+ email = f"guest-{guest_id}@guests.launchpad.ai"
191
  user = User(
192
  firstName="Guest",
193
  lastName="Explorer",
multi_llm_chatbot_backend/app/tests/unit/test_account_management.py CHANGED
@@ -16,6 +16,7 @@ from app.api.routes.auth import ( # noqa: E402
16
  UpdateProfileRequest,
17
  change_password,
18
  delete_account,
 
19
  update_profile,
20
  )
21
  from app.models.user import User # noqa: E402
@@ -205,6 +206,47 @@ class TestUpdateProfile(unittest.TestCase):
205
  self.assertIn("at least one field", str(ctx.exception).lower())
206
 
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  # ------------------------------------------------------------------
209
  # DELETE /auth/me
210
  # ------------------------------------------------------------------
 
16
  UpdateProfileRequest,
17
  change_password,
18
  delete_account,
19
+ guest_login,
20
  update_profile,
21
  )
22
  from app.models.user import User # noqa: E402
 
206
  self.assertIn("at least one field", str(ctx.exception).lower())
207
 
208
 
209
+ # ------------------------------------------------------------------
210
+ # POST /auth/guest
211
+ # ------------------------------------------------------------------
212
+
213
+
214
+ @patch("app.api.routes.auth.create_access_token", return_value="guest-token")
215
+ @patch("app.api.routes.auth.get_password_hash", return_value="hashed")
216
+ @patch("app.api.routes.auth.get_database")
217
+ class TestGuestLogin(unittest.TestCase):
218
+
219
+ def test_creates_guest_user_with_valid_email(self, mock_get_db, _hash, _token):
220
+ db = _mock_db()
221
+ db.users.insert_one = AsyncMock(return_value=MagicMock(inserted_id=FAKE_USER_ID))
222
+ db.user_profiles = MagicMock()
223
+ db.user_profiles.update_one = AsyncMock()
224
+ mock_get_db.return_value = db
225
+
226
+ result = asyncio.run(guest_login())
227
+
228
+ self.assertEqual(result.access_token, "guest-token")
229
+ self.assertEqual(result.token_type, "bearer")
230
+ self.assertTrue(result.user.is_guest)
231
+ self.assertTrue(result.user.email.endswith("@guests.launchpad.ai"))
232
+ self.assertFalse(result.user.email.endswith(".local"))
233
+ db.users.insert_one.assert_called_once()
234
+ inserted = db.users.insert_one.call_args.args[0]
235
+ self.assertTrue(inserted.get("is_guest"))
236
+ self.assertTrue(str(inserted.get("email", "")).endswith("@guests.launchpad.ai"))
237
+
238
+ def test_legacy_local_guest_email_is_rejected_by_model(self, *_mocks):
239
+ """Regression: EmailStr must not accept reserved .local guest addresses."""
240
+ with self.assertRaises(ValidationError):
241
+ User(
242
+ firstName="Guest",
243
+ lastName="Explorer",
244
+ email="guest-abc@guest.launchpad.local",
245
+ hashed_password="x",
246
+ is_guest=True,
247
+ )
248
+
249
+
250
  # ------------------------------------------------------------------
251
  # DELETE /auth/me
252
  # ------------------------------------------------------------------