diff --git a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py index 582704828..7309bdbef 100644 --- a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py +++ b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py @@ -38,6 +38,7 @@ from .bot_adapter import BotAdapter from .turn_context import TurnContext from .user_token_provider import UserTokenProvider +from .invoke_response import InvokeResponse from .conversation_reference_extension import get_continuation_activity USER_AGENT = f"Microsoft-BotFramework/3.1 (BotBuilder Python/{__version__})" @@ -263,7 +264,17 @@ async def process_activity(self, req, auth_header: str, logic: Callable): teams_channel_data["tenant"]["id"] ) - return await self.run_pipeline(context, logic) + await self.run_pipeline(context, logic) + + if activity.type == ActivityTypes.invoke: + invoke_response = context.turn_state.get( + BotFrameworkAdapter._INVOKE_RESPONSE_KEY # pylint: disable=protected-access + ) + if invoke_response is None: + return InvokeResponse(status=501) + return invoke_response.value + + return None async def authenticate_request( self, request: Activity, auth_header: str @@ -283,7 +294,7 @@ async def authenticate_request( ) if not claims.is_authenticated: - raise Exception("Unauthorized Access. Request is not authorized") + raise PermissionError("Unauthorized Access. Request is not authorized") return claims diff --git a/libraries/botbuilder-core/botbuilder/core/teams/__init__.py b/libraries/botbuilder-core/botbuilder/core/teams/__init__.py index 2e482ac88..9acc2a250 100644 --- a/libraries/botbuilder-core/botbuilder/core/teams/__init__.py +++ b/libraries/botbuilder-core/botbuilder/core/teams/__init__.py @@ -7,7 +7,7 @@ from .teams_activity_handler import TeamsActivityHandler from .teams_info import TeamsInfo -from .teams_helper import deserializer_helper +from .teams_helper import deserializer_helper, serializer_helper from .teams_activity_extensions import ( teams_get_channel_id, teams_get_team_info, @@ -21,4 +21,5 @@ "teams_get_channel_id", "teams_get_team_info", "teams_notify_user", + "serializer_helper", ] diff --git a/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py b/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py index ff7b3b1b8..174f7e9b8 100644 --- a/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py +++ b/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py @@ -5,8 +5,8 @@ from botbuilder.schema import Activity, ActivityTypes, ChannelAccount from botbuilder.core import ActivityHandler, InvokeResponse, BotFrameworkAdapter from botbuilder.core.turn_context import TurnContext +from botbuilder.core.teams.teams_helper import deserializer_helper, serializer_helper from botbuilder.core.teams.teams_info import TeamsInfo -from botbuilder.core.teams.teams_helper import deserializer_helper from botbuilder.schema.teams import ( AppBasedLinkQuery, TeamInfo, @@ -446,7 +446,7 @@ async def on_teams_channel_renamed_activity( # pylint: disable=unused-argument @staticmethod def _create_invoke_response(body: object = None) -> InvokeResponse: - return InvokeResponse(status=int(HTTPStatus.OK), body=body) + return InvokeResponse(status=int(HTTPStatus.OK), body=serializer_helper(body)) class _InvokeResponseException(Exception): diff --git a/libraries/botbuilder-core/botbuilder/core/teams/teams_helper.py b/libraries/botbuilder-core/botbuilder/core/teams/teams_helper.py index 2e11f2953..f9e8c65e8 100644 --- a/libraries/botbuilder-core/botbuilder/core/teams/teams_helper.py +++ b/libraries/botbuilder-core/botbuilder/core/teams/teams_helper.py @@ -2,7 +2,7 @@ from typing import Type from enum import Enum -from msrest.serialization import Model, Deserializer +from msrest.serialization import Model, Deserializer, Serializer import botbuilder.schema as schema import botbuilder.schema.teams as teams_schema @@ -22,3 +22,26 @@ def deserializer_helper(msrest_cls: Type[Model], dict_to_deserialize: dict) -> M dependencies_dict = {dependency.__name__: dependency for dependency in dependencies} deserializer = Deserializer(dependencies_dict) return deserializer(msrest_cls.__name__, dict_to_deserialize) + + +# TODO consolidate these two methods + + +def serializer_helper(object_to_serialize: Model) -> dict: + if object_to_serialize is None: + return None + + dependencies = [ + schema_cls + for key, schema_cls in getmembers(schema) + if isinstance(schema_cls, type) and issubclass(schema_cls, (Model, Enum)) + ] + dependencies += [ + schema_cls + for key, schema_cls in getmembers(teams_schema) + if isinstance(schema_cls, type) and issubclass(schema_cls, (Model, Enum)) + ] + dependencies_dict = {dependency.__name__: dependency for dependency in dependencies} + serializer = Serializer(dependencies_dict) + # pylint: disable=protected-access + return serializer._serialize(object_to_serialize) diff --git a/libraries/botbuilder-schema/botbuilder/schema/teams/_models.py b/libraries/botbuilder-schema/botbuilder/schema/teams/_models.py index 835846cb4..3cce195d6 100644 --- a/libraries/botbuilder-schema/botbuilder/schema/teams/_models.py +++ b/libraries/botbuilder-schema/botbuilder/schema/teams/_models.py @@ -1538,6 +1538,7 @@ class TeamsChannelAccount(ChannelAccount): "surname": {"key": "surname", "type": "str"}, "email": {"key": "email", "type": "str"}, "userPrincipalName": {"key": "userPrincipalName", "type": "str"}, + "aad_object_id": {"key": "objectId", "type": "str"}, } def __init__(self, **kwargs):