Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@

from .channel_adapter_protocol import ChannelAdapterProtocol
from .turn_context_protocol import TurnContextProtocol
from ._load_configuration import load_configuration_from_env
from ._utils import (
load_configuration_from_env,
_raise_if_falsey,
_raise_if_none
)

__all__ = [
"AgentsModel",
Expand Down Expand Up @@ -194,6 +198,8 @@
"ConversationUpdateTypes",
"MessageUpdateTypes",
"load_configuration_from_env",
"_raise_if_falsey",
"_raise_if_none",
"ChannelAdapterProtocol",
"TurnContextProtocol",
"TokenOrSignInResourceResponse",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

from ._error_handling import (
_raise_if_falsey,
_raise_if_none,
)
from ._load_configuration import load_configuration_from_env

__all__ = [
"_raise_if_falsey",
"_raise_if_none",
"load_configuration_from_env",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

def _raise_if_none(label: str, **kwargs) -> None:
"""Raises an exception if any of the provided keyword arguments are None.

:param label: A label to include in the exception message.
:param kwargs: The keyword arguments to check.
:raises ValueError: If any of the provided keyword arguments are None.
"""

none_args = [name for name, value in kwargs.items() if value is None]
if none_args:
raise ValueError(
f"{label}: The following arguments must be set and non-None: {', '.join(none_args)}"
)

def _raise_if_falsey(label: str, **kwargs) -> None:
"""Raises an exception if any of the provided keyword arguments are falsey.

:param label: A label to include in the exception message.
:param kwargs: The keyword arguments to check.
:raises ValueError: If any of the provided keyword arguments are falsey.
"""

falsey_args = [name for name, value in kwargs.items() if not value]
if falsey_args:
raise ValueError(
f"{label}: The following arguments must be set and non-falsey (cannot be None or an empty string, for example): {', '.join(falsey_args)}"
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
# Licensed under the MIT License.

from ._flow_state import _FlowState, _FlowStateTag, _FlowErrorTag
from ._flow_storage_client import _FlowStorageClient
from ._oauth_flow import _OAuthFlow, _FlowResponse

__all__ = [
"_FlowState",
"_FlowStateTag",
"_FlowErrorTag",
"_FlowResponse",
"_FlowStorageClient",
"_OAuthFlow",
]

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@
_OAuthFlow,
_FlowResponse,
_FlowState,
_FlowStorageClient,
_FlowStateTag,
)
from microsoft_agents.hosting.core.storage import (
_ItemNamespace,
_Namespaces
)

from .._sign_in_response import _SignInResponse
from ._authorization_handler import _AuthorizationHandler

Expand All @@ -41,7 +45,7 @@ class _UserAuthorization(_AuthorizationHandler):

async def _load_flow(
self, context: TurnContext
) -> tuple[_OAuthFlow, _FlowStorageClient]:
) -> tuple[_OAuthFlow, _ItemNamespace[_FlowState]]:
"""Loads the OAuth flow for a specific auth handler.

A new flow is created in Storage if none exists for the channel, user, and handler
Expand Down Expand Up @@ -72,9 +76,13 @@ async def _load_flow(
ms_app_id = context.turn_state.get(context.adapter.AGENT_IDENTITY_KEY).claims[
"aud"
]

namespace = _Namespaces._USER_AUTHORIZATION.format(
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reference to '_Namespaces._USER_AUTHORIZATION' is incorrect. The attribute in _namespaces.py is defined as 'USER_AUTHORIZATION' (without underscore prefix), so this should be '_Namespaces.USER_AUTHORIZATION'.

Suggested change
namespace = _Namespaces._USER_AUTHORIZATION.format(
namespace = _Namespaces.USER_AUTHORIZATION.format(

Copilot uses AI. Check for mistakes.
channel_id=channel_id,
user_id=user_id,
Copy link

Copilot AI Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format string expects 'from_property_id' as a parameter (line 8 in _namespaces.py), but 'user_id' is being passed here. This will cause a KeyError when attempting to format the namespace string.

Copilot uses AI. Check for mistakes.
)
flow_storage_client = _ItemNamespace(namespace, self._storage, _FlowState)

# try to load existing state
flow_storage_client = _FlowStorageClient(channel_id, user_id, self._storage)
logger.info("Loading OAuth flow state from storage")
flow_state: _FlowState = await flow_storage_client.read(self._id)
if not flow_state:
Expand All @@ -86,7 +94,6 @@ async def _load_flow(
connection=self._handler.abs_oauth_connection_name,
ms_app_id=ms_app_id,
)
# await flow_storage_client.write(flow_state)

flow = _OAuthFlow(flow_state, user_token_client)
return flow, flow_storage_client
Expand Down
Loading
Loading