3232app = cors (app , allow_origin = "*" )
3333
3434
35+ # ==================== Authentication Helper ====================
36+
37+ def get_authenticated_user ():
38+ """
39+ Get the authenticated user from EasyAuth headers.
40+
41+ In production (with App Service Auth), the X-Ms-Client-Principal-Id header
42+ contains the user's ID. In development mode, returns empty/None values.
43+ """
44+ user_principal_id = request .headers .get ("X-Ms-Client-Principal-Id" , "" )
45+ user_name = request .headers .get ("X-Ms-Client-Principal-Name" , "" )
46+ auth_provider = request .headers .get ("X-Ms-Client-Principal-Idp" , "" )
47+
48+ return {
49+ "user_principal_id" : user_principal_id or "" ,
50+ "user_name" : user_name or "" ,
51+ "auth_provider" : auth_provider or "" ,
52+ "is_authenticated" : bool (user_principal_id )
53+ }
54+
55+
3556# ==================== Health Check ====================
3657
3758@app .route ("/health" , methods = ["GET" ])
@@ -44,6 +65,19 @@ async def health_check():
4465 })
4566
4667
68+ # ==================== User Info Endpoint ====================
69+
70+ @app .route ("/api/user" , methods = ["GET" ])
71+ async def get_current_user ():
72+ """
73+ Get the current authenticated user info.
74+
75+ Returns user details from EasyAuth headers, or empty values if not authenticated.
76+ """
77+ user = get_authenticated_user ()
78+ return jsonify (user )
79+
80+
4781# ==================== Chat Endpoints ====================
4882
4983@app .route ("/api/chat" , methods = ["POST" ])
@@ -341,7 +375,7 @@ async def generate():
341375 user_id = user_id ,
342376 message = {
343377 "role" : "assistant" ,
344- "content" : f"Content generated successfully! { f' Headline: " { headline } "' if headline else '' } " ,
378+ "content" : f"Content generated successfully!{ ' Headline: ' + headline if headline else '' } " ,
345379 "agent" : "ContentAgent" ,
346380 "timestamp" : datetime .now (timezone .utc ).isoformat ()
347381 }
@@ -544,15 +578,17 @@ async def list_conversations():
544578 """
545579 List conversations for a user.
546580
581+ Uses authenticated user from EasyAuth headers. In development mode
582+ (when not authenticated), returns conversations where user_id is empty/null.
583+
547584 Query params:
548- user_id: User identifier (required)
549585 limit: Max number of results (default 20)
550586 """
551- user_id = request .args .get ("user_id" )
552- limit = int (request .args .get ("limit" , 20 ))
587+ # Get authenticated user from headers
588+ auth_user = get_authenticated_user ()
589+ user_id = auth_user ["user_principal_id" ] # Empty string if not authenticated
553590
554- if not user_id :
555- return jsonify ({"error" : "user_id is required" }), 400
591+ limit = int (request .args .get ("limit" , 20 ))
556592
557593 cosmos_service = await get_cosmos_service ()
558594 conversations = await cosmos_service .get_user_conversations (user_id , limit )
@@ -568,13 +604,10 @@ async def get_conversation(conversation_id: str):
568604 """
569605 Get a specific conversation.
570606
571- Query params:
572- user_id: User identifier (required)
607+ Uses authenticated user from EasyAuth headers.
573608 """
574- user_id = request .args .get ("user_id" )
575-
576- if not user_id :
577- return jsonify ({"error" : "user_id is required" }), 400
609+ auth_user = get_authenticated_user ()
610+ user_id = auth_user ["user_principal_id" ]
578611
579612 cosmos_service = await get_cosmos_service ()
580613 conversation = await cosmos_service .get_conversation (conversation_id , user_id )
@@ -590,13 +623,10 @@ async def delete_conversation(conversation_id: str):
590623 """
591624 Delete a specific conversation.
592625
593- Query params:
594- user_id: User identifier (required)
626+ Uses authenticated user from EasyAuth headers.
595627 """
596- user_id = request .args .get ("user_id" )
597-
598- if not user_id :
599- return jsonify ({"error" : "user_id is required" }), 400
628+ auth_user = get_authenticated_user ()
629+ user_id = auth_user ["user_principal_id" ]
600630
601631 try :
602632 cosmos_service = await get_cosmos_service ()
0 commit comments