8000 added ChannelProvider (#451) · ericmicrofocus/botbuilder-python@e5254b6 · GitHub
[go: up one dir, main page]

Skip to content

Commit e5254b6

Browse files
authored
added ChannelProvider (microsoft#451)
1 parent 259493c commit e5254b6

File tree

8 files changed

+180
-27
lines changed

8 files changed

+180
-27
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
# regenerated.
1010
# --------------------------------------------------------------------------
1111
# pylint: disable=missing-docstring
12-
12+
from .government_constants import *
13+
from .channel_provider import *
14+
from .simple_channel_provider import *
1315
from .microsoft_app_credentials import *
1416
from .claims_identity import *
1517
from .jwt_token_validation import *
1618
from .credential_provider import *
1719
from .channel_validation import *
1820
from .emulator_validation import *
1921
from .jwt_token_extractor import *
20-
from .government_constants import *
2122
from .authentication_constants import *
2223
from .authentication_configuration import *
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from abc import ABC, abstractmethod
5+
6+
7+
class ChannelProvider(ABC):
8+
"""
9+
ChannelProvider interface. This interface allows Bots to provide their own
10+
implementation for the configuration parameters to connect to a Bot.
11+
Framework channel service.
12+
"""
13+
14+
@abstractmethod
15+
async def get_channel_service(self) -> str:
16+
raise NotImplementedError()
17+
18+
@abstractmethod
19+
def is_government(self) -> bool:
20+
raise NotImplementedError()
21+
22+
@abstractmethod
23+
def is_public_azure(self) -> bool:
24+
raise NotImplementedError()

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# Licensed under the MIT License.
33

44
import asyncio
5+
from typing import Union
6+
57
import jwt
68

79
from .jwt_token_extractor import JwtTokenExtractor
@@ -10,6 +12,7 @@
1012
from .credential_provider import CredentialProvider
1113
from .claims_identity import ClaimsIdentity
1214
from .government_constants import GovernmentConstants
15+
from .channel_provider import ChannelProvider
1316

1417

1518
class EmulatorValidation:
@@ -82,7 +85,7 @@ def is_token_from_emulator(auth_header: str) -> bool:
8285
async def authenticate_emulator_token(
8386
auth_header: str,
8487
credentials: CredentialProvider,
85-
channel_service: str,
88+
channel_service_or_provider: Union[str, ChannelProvider],
8689
channel_id: str,
8790
) -> ClaimsIdentity:
8891
""" Validate the incoming Auth Header
@@ -101,12 +104,14 @@ async def authenticate_emulator_token(
101104
# pylint: disable=import-outside-toplevel
102105
from .jwt_token_validation import JwtTokenValidation
103106

107+
if isinstance(channel_service_or_provider, ChannelProvider):
108+
is_gov = channel_service_or_provider.is_government()
109+
else:
110+
is_gov = JwtTokenValidation.is_government(channel_service_or_provider)
111+
104112
open_id_metadata = (
105113
GovernmentConstants.TO_BOT_FROM_EMULATOR_OPEN_ID_METADATA_URL
106-
if (
107-
channel_service is not None
108-
and JwtTokenValidation.is_government(channel_service)
109-
)
114+
if is_gov
110115
else Constants.TO_BOT_FROM_EMULATOR_OPEN_ID_METADATA_URL
111116
)
112117

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
# Licensed under the MIT License.
33

44
from abc import ABC
5+
from typing import Union
56

67
from .authentication_configuration import AuthenticationConfiguration
78
from .authentication_constants import AuthenticationConstants
89
from .channel_validation import ChannelValidation
10+
from .channel_provider import ChannelProvider
911
from .claims_identity import ClaimsIdentity
1012
from .credential_provider import CredentialProvider
1113
from .jwt_token_extractor import JwtTokenExtractor
@@ -26,9 +28,13 @@ async def authenticate_channel_token(
2628
auth_header: str,
2729
credentials: CredentialProvider,
2830
channel_id: str,
29-
channel_service: str,
31+
channel_service_or_provider: Union[str, ChannelProvider],
3032
auth_configuration: AuthenticationConfiguration = None,
3133
) -> ClaimsIdentity:
34+
channel_service = channel_service_or_provider
35+
if isinstance(channel_service_or_provider, ChannelProvider):
36+
channel_service = await channel_service_or_provider.get_channel_service()
37+
3238
endpoint = (
3339
ChannelValidation.open_id_metadata_endpoint
3440
if ChannelValidation.open_id_metadata_endpoint
@@ -55,11 +61,15 @@ async def authenticate_channel_token_with_service_url(
5561
credentials: CredentialProvider,
5662
service_url: str,
5763
channel_id: str,
58-
channel_service: str,
64+
channel_service_or_provider: Union[str, ChannelProvider],
5965
auth_configuration: AuthenticationConfiguration = None,
6066
) -> ClaimsIdentity:
6167
identity: ClaimsIdentity = await EnterpriseChannelValidation.authenticate_channel_token(
62-
auth_header, credentials, channel_id, channel_service, auth_configuration
68+
auth_header,
69+
credentials,
70+
channel_id,
71+
channel_service_or_provider,
72+
auth_configuration,
6373
)
6474

6575
service_url_claim: str = identity.get_claim_value(

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

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the MIT License.
3-
from typing import Dict, List
3+
from typing import Dict, List, Union
44

55
from botbuilder.schema import Activity
66

@@ -15,6 +15,7 @@
1515
from .government_constants import GovernmentConstants
1616
from .government_channel_validation import GovernmentChannelValidation
1717
from .skill_validation import SkillValidation
18+
from .channel_provider import ChannelProvider
1819

1920

2021
class JwtTokenValidation:
@@ -25,7 +26,7 @@ async def authenticate_request(
2526
activity: Activity,
2627
auth_header: str,
2728
credentials: CredentialProvider,
28-
channel_service: str = "",
29+
channel_service_or_provider: Union[str, ChannelProvider] = "",
2930
) -> ClaimsIdentity:
3031
"""Authenticates the request and sets the service url in the set of trusted urls.
3132
:param activity: The incoming Activity from the Bot Framework or the Emulator
@@ -51,7 +52,7 @@ async def authenticate_request(
5152
claims_identity = await JwtTokenValidation.validate_auth_header(
5253
auth_header,
5354
credentials,
54-
channel_service,
55+
channel_service_or_provider,
5556
activity.channel_id,
5657
activity.service_url,
5758
)
@@ -65,7 +66,7 @@ async def authenticate_request(
6566
async def validate_auth_header(
6667
auth_header: str,
6768
credentials: CredentialProvider,
68-
channel_service: str,
69+
channel_service_or_provider: Union[str, ChannelProvider],
6970
channel_id: str,
7071
service_url: str = None,
7172
auth_configuration: AuthenticationConfiguration = None,
@@ -78,18 +79,30 @@ async def get_claims() -> ClaimsIdentity:
7879
return await SkillValidation.authenticate_channel_token(
7980
auth_header,
8081
credentials,
81-
channel_service,
82+
channel_service_or_provider,
8283
channel_id,
8384
auth_configuration,
8485
)
8586

8687
if EmulatorValidation.is_token_from_emulator(auth_header):
8788
return await EmulatorValidation.authenticate_emulator_token(
88-
auth_header, credentials, channel_service, channel_id
89+
auth_header, credentials, channel_service_or_provider, channel_id
8990
)
9091

92+
is_public = (
93+
not channel_service_or_provider
94+
or isinstance(channel_service_or_provider, ChannelProvider)
95+
and channel_service_or_provider.is_public_azure()
96+
)
97+
is_gov = (
98+
isinstance(channel_service_or_provider, ChannelProvider)
99+
and channel_service_or_provider.is_public_azure()
100+
or isinstance(channel_service_or_provider, str)
101+
and JwtTokenValidation.is_government(channel_service_or_provider)
102+
)
103+
91104
# If the channel is Public Azure
92-
if not channel_service:
105+
if is_public:
93106
if service_url:
94107
return await ChannelValidation.authenticate_channel_token_with_service_url(
95108
auth_header,
@@ -103,7 +116,7 @@ async def get_claims() -> ClaimsIdentity:
103116
auth_header, credentials, channel_id, auth_configuration
104117
)
105118

106-
if JwtTokenValidation.is_government(channel_service):
119+
if is_gov:
107120
if service_url:
108121
return await GovernmentChannelValidation.authenticate_channel_token_with_service_url(
109122
auth_header,
@@ -124,15 +137,15 @@ async def get_claims() -> ClaimsIdentity:
124137
credentials,
125138
service_url,
126139
channel_id,
127-
channel_service,
140+
channel_service_or_provider,
128141
auth_configuration,
129142
)
130143

131144
return await EnterpriseChannelValidation.authenticate_channel_token(
132145
auth_header,
133146
credentials,
134147
channel_id,
135-
channel_service,
148+
channel_service_or_provider,
136149
auth_configuration,
137150
)
138151

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from .channel_provider import ChannelProvider
5+
from .government_constants import GovernmentConstants
6+
7+
8+
class SimpleChannelProvider(ChannelProvider):
9+
"""
10+
ChannelProvider interface. This interface allows Bots to provide their own
11+
implementation for the configuration parameters to connect to a Bot.
12+
Framework channel service.
13+
"""
14+
15+
def __init__(self, channel_service: str = None):
16+
self.channel_service = channel_service
17+
18+
async def get_channel_service(self) -> str:
19+
return self.channel_service
20+
21+
def is_government(self) -> bool:
22+
return self.channel_service == GovernmentConstants.CHANNEL_SERVICE
23+
24+
def is_public_azure(self) -> bool:
25+
return not self.channel_service

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Licensed under the MIT License.
33

44
from datetime import timedelta
5-
from typing import Dict
5+
from typing import Dict, Union
66

77
import jwt
88

@@ -13,6 +13,7 @@
1313
from .government_constants import GovernmentConstants
1414
from .verify_options import VerifyOptions
1515
from .jwt_token_extractor import JwtTokenExtractor
16+
from .channel_provider import ChannelProvider
1617

1718

1819
class SkillValidation:
@@ -88,7 +89,7 @@ def is_skill_claim(claims: Dict[str, object]) -> bool:
8889
async def authenticate_channel_token(
8990
auth_header: str,
9091
credentials: CredentialProvider,
91-
channel_service: str,
92+
channel_service_or_provider: Union[str, ChannelProvider],
9293
channel_id: str,
9394
auth_configuration: AuthenticationConfiguration,
9495
) -> ClaimsIdentity:
@@ -99,9 +100,14 @@ async def authenticate_channel_token(
99100

100101
from .jwt_token_validation import JwtTokenValidation
101102

103+
if isinstance(channel_service_or_provider, ChannelProvider):
104+
is_gov = channel_service_or_provider.is_government()
105+
else:
106+
is_gov = JwtTokenValidation.is_government(channel_service_or_provider)
107+
102108
open_id_metadata_url = (
103109
GovernmentConstants.TO_BOT_FROM_EMULATOR_OPEN_ID_METADATA_URL
104-
if channel_service and JwtTokenValidation.is_government(channel_service)
110+
if is_gov
105111
else AuthenticationConstants.TO_BOT_FROM_EMULATOR_OPEN_ID_METADATA_URL
106112
)
107113

0 commit comments

Comments
 (0)
0