async def _intercept_oauth_cards( self, activities: List[Activity], turn_context: TurnContext, ) -> bool: if not activities: return False activity = activities[0] if activity.attachments: for attachment in filter(lambda att: att.content_type == CardFactory.content_types.oauth_card, activity.attachments): oauth_card: OAuthCard = OAuthCard().from_dict(attachment.content) oauth_card.token_exchange_resource: TokenExchangeResource = TokenExchangeResource().from_dict( oauth_card.token_exchange_resource) if oauth_card.token_exchange_resource: token_exchange_provider: BotFrameworkAdapter = turn_context.adapter result = await token_exchange_provider.exchange_token( turn_context, self._connection_name, turn_context.activity.from_property.id, TokenExchangeRequest(uri=oauth_card.token_exchange_resource.uri) ) if result.token: return await self._send_token_exchange_invoke_to_skill( turn_context, activity, oauth_card.token_exchange_resource.id, result.token ) return False
def create_oauth_card_attachment_activity(uri: str) -> Activity: oauth_card = OAuthCard(token_exchange_resource=TokenExchangeResource(uri=uri)) attachment = Attachment( content_type=ContentTypes.oauth_card, content=oauth_card, ) attachment_activity = MessageFactory.attachment(attachment) attachment_activity.conversation = ConversationAccount(id=str(uuid.uuid4())) attachment_activity.from_property = ChannelAccount(id="blah", name="name") return attachment_activity
async def send_oauth_card(self, context: TurnContext, prompt: Union[Activity, str] = None): if not isinstance(prompt, Activity): prompt = MessageFactory.text(prompt or "", None, InputHints.accepting_input) else: prompt.input_hint = prompt.input_hint or InputHints.accepting_input prompt.attachments = prompt.attachments or [] if self._channel_suppports_oauth_card(context.activity.channel_id): if not any(att.content_type == CardFactory.content_types.oauth_card for att in prompt.attachments): prompt.attachments.append( CardFactory.oauth_card( OAuthCard( text=self._settings.text, connection_name=self._settings.connection_name, buttons=[ CardAction( title=self._settings.title, text=self._settings.text, type=ActionTypes.signin, ) ], ))) else: if not any( att.content_type == CardFactory.content_types.signin_card for att in prompt.attachments): if not hasattr(context.adapter, "get_oauth_sign_in_link"): raise Exception( "OAuthPrompt.send_oauth_card(): get_oauth_sign_in_link() not supported by the current adapter" ) link = await context.adapter.get_oauth_sign_in_link( context, self._settings.connection_name) prompt.attachments.append( CardFactory.signin_card( SigninCard( text=self._settings.text, buttons=[ CardAction( title=self._settings.title, value=link, type=ActionTypes.signin, ) ], ))) # Send prompt await context.send_activity(prompt)
def test_should_create_oauth_card_attachment(self): button = CardAction(type=ActionTypes.signin, title='test', value='https://example.org/signin') card = OAuthCard(text='sign in', connection_name='test.com', buttons=[button]) attachment = CardFactory.oauth_card(card) assert_attachment(attachment, CardFactory.content_types.oauth_card) assert_actions(attachment.content.buttons, 1, ['test']) assert attachment.content.text == 'sign in', 'wrong text' assert attachment.content.connection_name == 'test.com', 'wrong connection_name'
def create_oauth_card(self) -> Attachment: card = OAuthCard( text="BotFramework OAuth Card", connection_name="OAuth connection", # Replace it with the name of your Azure AD connection. buttons=[ CardAction( type=ActionTypes.signin, title="Sign in", value="https://example.org/signin", ) ], ) return CardFactory.oauth_card(card)
def test_should_create_oauth_card_attachment(self): button = CardAction(type=ActionTypes.signin, title="test", value="https://example.org/signin") card = OAuthCard(text="sign in", connection_name="test.com", buttons=[button]) attachment = CardFactory.oauth_card(card) assert_attachment(attachment, CardFactory.content_types.oauth_card) assert_actions(attachment.content.buttons, 1, ["test"]) assert attachment.content.text == "sign in", "wrong text" assert attachment.content.connection_name == "test.com", "wrong connection_name"
async def _send_oauth_card(self, context: TurnContext, prompt: Union[Activity, str] = None): if not isinstance(prompt, Activity): prompt = MessageFactory.text(prompt or "", None, InputHints.accepting_input) else: prompt.input_hint = prompt.input_hint or InputHints.accepting_input prompt.attachments = prompt.attachments or [] if OAuthPrompt._channel_suppports_oauth_card( context.activity.channel_id): if not any(att.content_type == CardFactory.content_types.oauth_card for att in prompt.attachments): adapter: ExtendedUserTokenProvider = context.adapter card_action_type = ActionTypes.signin sign_in_resource: SignInUrlResponse = await adapter.get_sign_in_resource_from_user_and_credentials( context, self._settings.oath_app_credentials, self._settings.connection_name, context.activity.from_property.id, ) link = sign_in_resource.sign_in_link bot_identity: ClaimsIdentity = context.turn_state.get( BotAdapter.BOT_IDENTITY_KEY) # use the SignInLink when in speech channel or bot is a skill or # an extra OAuthAppCredentials is being passed in if ((bot_identity and SkillValidation.is_skill_claim(bot_identity.claims)) or not context.activity.service_url.startswith("http") or self._settings.oath_app_credentials): if context.activity.channel_id == Channels.emulator: card_action_type = ActionTypes.open_url elif not OAuthPrompt._channel_requires_sign_in_link( context.activity.channel_id): link = None json_token_ex_resource = ( sign_in_resource.token_exchange_resource.as_dict() if sign_in_resource.token_exchange_resource else None) prompt.attachments.append( CardFactory.oauth_card( OAuthCard( text=self._settings.text, connection_name=self._settings.connection_name, buttons=[ CardAction( title=self._settings.title, text=self._settings.text, type=card_action_type, value=link, ) ], token_exchange_resource=json_token_ex_resource, ))) else: if not any( att.content_type == CardFactory.content_types.signin_card for att in prompt.attachments): if not hasattr(context.adapter, "get_oauth_sign_in_link"): raise Exception( "OAuthPrompt._send_oauth_card(): get_oauth_sign_in_link() not supported by the current adapter" ) link = await context.adapter.get_oauth_sign_in_link( context, self._settings.connection_name, None, self._settings.oath_app_credentials, ) prompt.attachments.append( CardFactory.signin_card( SigninCard( text=self._settings.text, buttons=[ CardAction( title=self._settings.title, value=link, type=ActionTypes.signin, ) ], ))) # Send prompt await context.send_activity(prompt)
async def _send_oauth_card(self, context: TurnContext, prompt: Union[Activity, str] = None): if not isinstance(prompt, Activity): prompt = MessageFactory.text(prompt or "", None, InputHints.accepting_input) else: prompt.input_hint = prompt.input_hint or InputHints.accepting_input prompt.attachments = prompt.attachments or [] if OAuthPrompt._channel_suppports_oauth_card( context.activity.channel_id): if not any(att.content_type == CardFactory.content_types.oauth_card for att in prompt.attachments): link = None card_action_type = ActionTypes.signin bot_identity: ClaimsIdentity = context.turn_state.get( "BotIdentity") # check if it's from streaming connection if not context.activity.service_url.startswith("http"): if not hasattr(context.adapter, "get_oauth_sign_in_link"): raise Exception( "OAuthPrompt: get_oauth_sign_in_link() not supported by the current adapter" ) link = await context.adapter.get_oauth_sign_in_link( context, self._settings.connection_name, None, self._settings.oath_app_credentials, ) elif bot_identity and SkillValidation.is_skill_claim( bot_identity.claims): link = await context.adapter.get_oauth_sign_in_link( context, self._settings.connection_name, None, self._settings.oath_app_credentials, ) card_action_type = ActionTypes.open_url prompt.attachments.append( CardFactory.oauth_card( OAuthCard( text=self._settings.text, connection_name=self._settings.connection_name, buttons=[ CardAction( title=self._settings.title, text=self._settings.text, type=card_action_type, value=link, ) ], ))) else: if not any( att.content_type == CardFactory.content_types.signin_card for att in prompt.attachments): if not hasattr(context.adapter, "get_oauth_sign_in_link"): raise Exception( "OAuthPrompt.send_oauth_card(): get_oauth_sign_in_link() not supported by the current adapter" ) link = await context.adapter.get_oauth_sign_in_link( context, self._settings.connection_name, None, self._settings.oath_app_credentials, ) prompt.attachments.append( CardFactory.signin_card( SigninCard( text=self._settings.text, buttons=[ CardAction( title=self._settings.title, value=link, type=ActionTypes.signin, ) ], ))) # Send prompt await context.send_activity(prompt)