@@ -172,6 +172,18 @@ async def _get_conditional_access_policies(self):
172172 conditional_access_policies_list = (
173173 await self .client .identity .conditional_access .policies .get ()
174174 )
175+
176+ # TODO: Remove this workaround once microsoft/kiota-python#515 is
177+ # fixed and a new version of microsoft-kiota-serialization-json is
178+ # released (see PR microsoft/kiota-python#516). At that point, use
179+ # the SDK's native deserialization for authentication_flows instead.
180+ #
181+ # The SDK deserializer uses get_collection_of_enum_values for
182+ # transferMethods, but the Graph API returns it as a single string
183+ # (e.g., "deviceCodeFlow"), causing the SDK to return an empty list.
184+ # We fetch the raw JSON to correctly parse transferMethods.
185+ raw_auth_flows_map = await self ._get_raw_authentication_flows ()
186+
175187 for policy in conditional_access_policies_list .value :
176188 conditional_access_policies [policy .id ] = ConditionalAccessPolicy (
177189 id = policy .id ,
@@ -302,11 +314,7 @@ async def _get_conditional_access_policies(self):
302314 ],
303315 ),
304316 authentication_flows = self ._parse_authentication_flows (
305- getattr (
306- policy .conditions ,
307- "authentication_flows" ,
308- None ,
309- )
317+ raw_auth_flows_map .get (policy .id )
310318 ),
311319 ),
312320 grant_controls = GrantControls (
@@ -453,12 +461,55 @@ async def _get_default_app_management_policy(self):
453461 )
454462 return default_app_management_policy
455463
464+ async def _get_raw_authentication_flows (self ) -> dict :
465+ """Fetch authentication flows from the Graph API using a raw JSON request.
466+
467+ TODO: Remove this method once microsoft/kiota-python#515 is fixed and
468+ a new version of microsoft-kiota-serialization-json is released
469+ (see PR microsoft/kiota-python#516). At that point, revert to using
470+ the SDK's native deserialization via policy.conditions.authentication_flows.
471+
472+ The SDK deserializer incorrectly handles the transferMethods field
473+ (uses get_collection_of_enum_values for a single string value),
474+ so we fetch the raw JSON to correctly parse it.
475+
476+ Returns:
477+ A dict mapping policy ID to the raw authenticationFlows dict.
478+ """
479+ auth_flows_map = {}
480+ try :
481+ request_info = (
482+ self .client .identity .conditional_access .policies .to_get_request_information ()
483+ )
484+ request_info .headers .try_add ("Prefer" , "include-unknown-enum-members" )
485+ response = await self .client .request_adapter .send_primitive_async (
486+ request_info , "bytes" , {}
487+ )
488+ if response :
489+ data = json .loads (response )
490+ for policy in data .get ("value" , []):
491+ policy_id = policy .get ("id" )
492+ auth_flows = (
493+ policy .get ("conditions" , {}).get ("authenticationFlows" )
494+ )
495+ if policy_id and auth_flows :
496+ auth_flows_map [policy_id ] = auth_flows
497+ except Exception as error :
498+ logger .error (
499+ f"{ error .__class__ .__name__ } [{ error .__traceback__ .tb_lineno } ]: { error } "
500+ )
501+ return auth_flows_map
502+
456503 @staticmethod
457504 def _parse_authentication_flows (auth_flows ) -> "AuthenticationFlows | None" :
458- """Parse authentication flows conditions from the Graph API response.
505+ """Parse authentication flows from a raw JSON dict.
506+
507+ TODO: Remove this method once microsoft/kiota-python#515 is fixed and
508+ revert to parsing the SDK's ConditionalAccessAuthenticationFlows object
509+ directly (see PR microsoft/kiota-python#516).
459510
460511 Args:
461- auth_flows: The authentication flows object from the Graph API .
512+ auth_flows: A dict from the raw JSON response (e.g., {"transferMethods": "deviceCodeFlow"}) .
462513
463514 Returns:
464515 AuthenticationFlows object or None if not present.
@@ -467,15 +518,18 @@ def _parse_authentication_flows(auth_flows) -> "AuthenticationFlows | None":
467518 return None
468519
469520 transfer_methods = []
470- raw_methods = getattr (auth_flows , "transfer_methods" , None ) or []
471- for method in raw_methods :
472- method_value = method .value if hasattr (method , "value" ) else str (method )
473- try :
474- transfer_methods .append (TransferMethod (method_value ))
475- except ValueError :
476- logger .warning (
477- f"Unknown authentication flow transfer method: { method_value } "
478- )
521+ raw_value = auth_flows .get ("transferMethods" )
522+ if raw_value :
523+ # The API may return a single string or a comma-separated value
524+ methods = raw_value .split ("," ) if isinstance (raw_value , str ) else raw_value
525+ for method_str in methods :
526+ method_str = method_str .strip ()
527+ try :
528+ transfer_methods .append (TransferMethod (method_str ))
529+ except ValueError :
530+ logger .warning (
531+ f"Unknown authentication flow transfer method: { method_str } "
532+ )
479533
480534 return AuthenticationFlows (transfer_methods = transfer_methods )
481535
0 commit comments