8000 SingleTenant support (#2055) · GitDakky/botbuilder-python@a078027 · GitHub
[go: up one dir, main page]

Skip to content

Commit a078027

Browse files
tracyboehrerTracy Boehrer
andauthored
SingleTenant support (microsoft#2055)
* SingleTenant support * Pylint corrections * Black correction * SingleTenant Gov correction * Ported Gov SingleTenant fixes from DotNet * Black correction * Pylint corrections * Black corrections for app_credentials * Corrected AppCredentials._should_set_token * Changed auth constant to match setting name * black corrections --------- Co-authored-by: Tracy Boehrer <trboehre@microsoft.com>
1 parent 184a2da commit a078027

25 files changed

+234
-233
lines changed

doc/SkillClaimsValidation.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,11 @@ ADAPTER = BotFrameworkAdapter(
4848
SETTINGS,
4949
)
5050
```
51+
52+
For SingleTenant type bots, the additional issuers must be added based on the tenant id:
53+
```python
54+
AUTH_CONFIG = AuthenticationConfiguration(
55+
claims_validator=AllowedSkillsClaimsValidator(CONFIG).claims_validator,
56+
tenant_id=the_tenant_id
57+
)
58+
```

libraries/botbuilder-adapters-slack/tests/test_slack_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import requests
1313
import pytest
1414

15-
SKIP = os.getenv("SlackChannel") == ''
15+
SKIP = os.getenv("SlackChannel") == ""
1616

1717

1818
class SlackClient(aiounittest.AsyncTestCase):

libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -279,19 +279,6 @@ async def continue_conversation(
279279
context.turn_state[BotAdapter.BOT_CALLBACK_HANDLER_KEY] = callback
280280
context.turn_state[BotAdapter.BOT_OAUTH_SCOPE_KEY] = audience
281281

282-
# If we receive a valid app id in the incoming token claims, add the channel service URL to the
283-
# trusted services list so we can send messages back.
284-
# The service URL for skills is trusted because it is applied by the SkillHandler based on the original
285-
# request received by the root bot
286-
app_id_from_claims = JwtTokenValidation.get_app_id_from_claims(
287-
claims_identity.claims
288-
)
289-
if app_id_from_claims:
290-
if SkillValidation.is_skill_claim(
291-
claims_identity.claims
292-
) or await self._credential_provider.is_valid_appid(app_id_from_claims):
293-
AppCredentials.trust_service_url(reference.service_url)
294-
295282
client = await self.create_connector_client(
296283
reference.service_url, claims_identity, audience
297284
)

libraries/botbuilder-core/botbuilder/core/configuration_service_client_credentials_factory.py

Lines changed: 0 additions & 19 deletions
This file was deleted.

libraries/botbuilder-core/tests/test_bot_framework_adapter.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -621,14 +621,8 @@ async def callback(context: TurnContext):
621621
scope = context.turn_state[BotFrameworkAdapter.BOT_OAUTH_SCOPE_KEY]
622622
assert AuthenticationConstants.TO_CHANNEL_FROM_BOT_OAUTH_SCOPE == scope
623623

624-
# Ensure the serviceUrl was added to the trusted hosts
625-
assert AppCredentials.is_trusted_service(channel_service_url)
626-
627624
refs = ConversationReference(service_url=channel_service_url)
628625

629-
# Ensure the serviceUrl is NOT in the trusted hosts
630-
assert not AppCredentials.is_trusted_service(channel_service_url)
631-
632626
await adapter.continue_conversation(
633627
refs, callback, claims_identity=skills_identity
634628
)
@@ -694,14 +688,8 @@ async def callback(context: TurnContext):
694688
scope = context.turn_state[BotFrameworkAdapter.BOT_OAUTH_SCOPE_KEY]
695689
assert skill_2_app_id == scope
696690

697-
# Ensure the serviceUrl was added to the trusted hosts
698-
assert AppCredentials.is_trusted_service(skill_2_service_url)
699-
700691
refs = ConversationReference(service_url=skill_2_service_url)
701692

702-
# Ensure the serviceUrl is NOT in the trusted hosts
703-
assert not AppCredentials.is_trusted_service(skill_2_service_url)
704-
705693
await adapter.continue_conversation(
706694
refs, callback, claims_identity=skills_identity, audience=skill_2_app_id
707695
)

libraries/botbuilder-integration-aiohttp/botbuilder/integration/aiohttp/bot_framework_http_adapter.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,6 @@ async def _http_authenticate_request(self, request: Request) -> bool:
188188
)
189189
)
190190

191-
# Add ServiceURL to the cache of trusted sites in order to allow token refreshing.
192-
self._credentials.trust_service_url(
193-
claims_identity.claims.get(
194-
AuthenticationConstants.SERVICE_URL_CLAIM
195-
)
196-
)
197191
self.claims_identity = claims_identity
198192
return True
199193
except Exception as error:

libraries/botbuilder-integration-aiohttp/botbuilder/integration/aiohttp/configuration_service_client_credential_factory.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,38 @@ class ConfigurationServiceClientCredentialFactory(
1111
PasswordServiceClientCredentialFactory
1212
):
1313
def __init__(self, configuration: Any, *, logger: Logger = None) -> None:
14-
super().__init__(
15-
app_id=getattr(configuration, "APP_ID", None),
16-
password=getattr(configuration, "APP_PASSWORD", None),
17-
logger=logger,
14+
app_type = (
15+
configuration.APP_TYPE
16+
if hasattr(configuration, "APP_TYPE")
17+
else "MultiTenant"
1818
)
19+
app_id = configuration.APP_ID if hasattr(configuration, "APP_ID") else None
20+
app_password = (
21+
configuration.APP_PASSWORD
22+
if hasattr(configuration, "APP_PASSWORD")
23+
else None
24+
)
25+
app_tenantid = None
26+
27+
if app_type == "UserAssignedMsi":
28+
raise Exception("UserAssignedMsi APP_TYPE is not supported")
29+
30+
if app_type == "SingleTenant":
31+
app_tenantid = (
32+
configuration.APP_TENANTID
33+
if hasattr(configuration, "APP_TENANTID")
34+
else None
35+
)
36+
37+
if not app_id:
38+
raise Exception("Property 'APP_ID' is expected in configuration object")
39+
if not app_password:
40+
raise Exception(
41+
"Property 'APP_PASSWORD' is expected in configuration object"
42+
)
43+
if not app_tenantid:
44+
raise Exception(
45+
"Property 'APP_TENANTID' is expected in configuration object"
46+
)
47+
48+
super().__init__(app_id, app_password, app_tenantid, logger=logger)

libraries/botframework-connector/botframework/connector/auth/_bot_framework_client_impl.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ async def post_activity(
4848
conversation_id: str,
4949
activity: Activity,
5050
) -> InvokeResponse:
51-
if not from_bot_id:
52-
raise TypeError("from_bot_id")
53-
if not to_bot_id:
54-
raise TypeError("to_bot_id")
5551
if not to_url:
5652
raise TypeError("to_url")
5753
if not service_url:
@@ -100,6 +96,7 @@ async def post_activity(
10096

10197
headers_dict = {
10298
"Content-type": "application/json; charset=utf-8",
99+
"x-ms-conversation-id": conversation_id,
103100
}
104101
if token:
105102
headers_dict.update(

libraries/botframework-connector/botframework/connector/auth/_built_in_bot_framework_authentication.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ async def create_user_token_client(
166166

167167
credentials = await self._credentials_factory.create_credentials(
168168
app_id,
169-
audience=self._to_channel_from_bot_oauth_scope,
169+
oauth_scope=self._to_channel_from_bot_oauth_scope,
170170
login_endpoint=self._login_endpoint,
171171
validate_authority=True,
172172
)

libraries/botframework-connector/botframework/connector/auth/_government_cloud_bot_framework_authentication.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def __init__(
2424
):
2525
super(_GovernmentCloudBotFrameworkAuthentication, self).__init__(
2626
GovernmentConstants.TO_CHANNEL_FROM_BOT_OAUTH_SCOPE,
27-
GovernmentConstants.TO_CHANNEL_FROM_BOT_LOGIN_URL,
27+
GovernmentConstants.TO_CHANNEL_FROM_BOT_LOGIN_URL_PREFIX,
2828
CallerIdConstants.us_gov_channel,
2929
GovernmentConstants.CHANNEL_SERVICE,
3030
GovernmentConstants.OAUTH_URL_GOV,

0 commit comments

Comments
 (0)
0