From d6827f971022855b3af003dc1ba332f7a9db0f3d Mon Sep 17 00:00:00 2001 From: tracyboehrer Date: Tue, 10 Sep 2024 08:19:27 -0500 Subject: [PATCH] Tracyboehrer/4.22.8 patch release (#6847) * Fix for Skills endorsement check (#6846) Co-authored-by: Tracy Boehrer * FederatedAppCredentials and factory * add token credential authentication to BlobsTranscriptStore (#6813) * [#6741] Remove .Net Core 3.1 from projects (#6819) * Remove netcoreapp3.1 and fix System.Text.Json issue * Fix System.Formats.Asn1 security issue * Fix remaining System.Text.Json issue * Removed unused argument from FederatedAuthenticator.CreateClientApplication * Fix Microsoft.Bcl.AsyncInterfaces warning (#6837) # Conflicts: # libraries/Microsoft.Bot.Builder.Azure/Microsoft.Bot.Builder.Azure.csproj * add code ql comment about TypeNameHandling.None (#6843) --------- Co-authored-by: Tracy Boehrer Co-authored-by: Jhonatan Sandoval Velasco <122501764+JhontSouth@users.noreply.github.com> Co-authored-by: Joel Mut <62260472+sw-joelmut@users.noreply.github.com> --- build/onebranch/ci-test-steps.yml | 15 +- build/onebranch/pr.yml | 16 --- build/yaml/botbuilder-dotnet-ci.yml | 16 --- build/yaml/ci-test-steps.yml | 15 +- .../content/.template.config/template.json | 4 - .../content/.template.config/template.json | 4 - .../content/.template.config/template.json | 4 - ...rosoft.Bot.AdaptiveExpressions.Core.csproj | 2 +- .../Microsoft.Bot.Builder.AI.Luis.csproj | 2 + .../Microsoft.Bot.Builder.AI.QnA.csproj | 2 + .../BlobsTranscriptStore.cs | 70 +++++++++ .../Microsoft.Bot.Builder.Azure.Blobs.csproj | 5 +- .../AzureQueueStorage.cs | 4 +- .../Microsoft.Bot.Builder.Azure.Queues.csproj | 2 + .../Microsoft.Bot.Builder.Azure.csproj | 4 +- ...ot.Builder.Dialogs.Adaptive.Runtime.csproj | 8 +- ...rosoft.Bot.Builder.Dialogs.Adaptive.csproj | 2 + ...oft.Bot.Builder.Dialogs.Declarative.csproj | 2 + .../Microsoft.Bot.Connector.Streaming.csproj | 3 - .../Authentication/FederatedAppCredentials.cs | 47 ++++++ .../Authentication/FederatedAuthenticator.cs | 134 ++++++++++++++++++ ...ederatedServiceClientCredentialsFactory.cs | 89 ++++++++++++ .../Authentication/JwtTokenExtractor.cs | 8 +- .../Microsoft.Bot.Connector.csproj | 1 + ...ntegration.ApplicationInsights.Core.csproj | 19 +-- ...egration.ApplicationInsights.WebApi.csproj | 2 +- ...Bot.Builder.Integration.AspNet.Core.csproj | 15 +- ...Bot.Builder.Adapters.Facebook.Tests.csproj | 3 +- ...ft.Bot.Builder.Adapters.Slack.Tests.csproj | 3 +- ...t.Bot.Builder.Adapters.Twilio.Tests.csproj | 3 +- ...ft.Bot.Builder.Adapters.Webex.Tests.csproj | 3 +- .../AdaptiveExpressions.Tests.csproj | 3 +- .../ExpressionParserTests.cs | 4 - ....Bot.AdaptiveExpressions.Core.Tests.csproj | 3 +- ...Microsoft.Bot.Builder.AI.Luis.Tests.csproj | 3 +- ...osoft.Bot.Builder.AI.Luis.TestUtils.csproj | 3 +- ...t.Bot.Builder.AI.Orchestrator.Tests.csproj | 3 +- .../Microsoft.Bot.Builder.AI.QnA.Tests.csproj | 3 +- ...crosoft.Bot.Builder.AI.LuisV3.Tests.csproj | 3 +- ...t.Builder.ApplicationInsights.Tests.csproj | 3 +- .../BlobsTranscriptStoreTests.cs | 18 +++ .../Microsoft.Bot.Builder.Azure.Tests.csproj | 3 +- ...lder.Dialogs.Adaptive.Runtime.Tests.csproj | 3 +- ...er.Dialogs.Adaptive.Templates.Tests.csproj | 3 +- ....Bot.Builder.Dialogs.Adaptive.Tests.csproj | 3 +- ...Bot.Builder.Dialogs.Debugging.Tests.csproj | 3 +- ...t.Builder.Dialogs.Declarative.Tests.csproj | 3 +- ...oft.Bot.Builder.Dialogs.Flows.Tests.csproj | 2 +- ...Microsoft.Bot.Builder.Dialogs.Tests.csproj | 3 +- ...ot.Builder.LanguageGeneration.Tests.csproj | 3 +- ...t.Bot.Builder.TemplateManager.Tests.csproj | 3 +- .../.vscode/launch.json | 2 +- ...Microsoft.Bot.Builder.TestBot.Tests.csproj | 3 +- ...Microsoft.Bot.Builder.Testing.Tests.csproj | 3 +- .../Microsoft.Bot.Builder.Tests.csproj | 3 +- ...osoft.Bot.Builder.Transcripts.Tests.csproj | 3 +- .../Microsoft.Bot.Configuration.Tests.csproj | 3 +- ...osoft.Bot.Connector.Streaming.Tests.csproj | 3 +- .../Authentication/JwtTokenExtractorTests.cs | 4 - .../Microsoft.Bot.Connector.Tests.csproj | 3 +- .../Microsoft.Bot.Schema.Tests.csproj | 3 +- .../Microsoft.Bot.Streaming.Tests.csproj | 3 +- ...rosoft.Bot.Builder.Parsers.LU.Tests.csproj | 3 +- ....Bot.ApplicationInsights.Core.Tests.csproj | 8 +- ...ilder.Integration.AspNet.Core.Tests.csproj | 3 +- 65 files changed, 434 insertions(+), 195 deletions(-) create mode 100644 libraries/Microsoft.Bot.Connector/Authentication/FederatedAppCredentials.cs create mode 100644 libraries/Microsoft.Bot.Connector/Authentication/FederatedAuthenticator.cs create mode 100644 libraries/Microsoft.Bot.Connector/Authentication/FederatedServiceClientCredentialsFactory.cs diff --git a/build/onebranch/ci-test-steps.yml b/build/onebranch/ci-test-steps.yml index e07b325b40..3484709eaa 100644 --- a/build/onebranch/ci-test-steps.yml +++ b/build/onebranch/ci-test-steps.yml @@ -20,21 +20,12 @@ steps: customCommand: 'install -g @microsoft/botframework-cli@next' - task: UseDotNet@2 - displayName: "Install .NET Core 3.1.415" + displayName: "Install .NET Core 6.0" continueOnError: true inputs: packageType: "sdk" - version: 3.1.415 - condition: and(succeeded(), eq(variables['BuildConfiguration'],'Release-Windows'), eq(variables['BuildTarget'],'netcoreapp31')) - -- task: DotNetCoreCLI@2 - displayName: 'dotnet test (release) 3.1' - inputs: - command: test - projects: | - Tests/**/*Tests.csproj - arguments: '-v n -f netcoreapp3.1 --configuration release --no-build --no-restore --filter "TestCategory!=IgnoreInAutomatedBuild&TestCategory!=FunctionalTests" --collect:"Code Coverage" --settings $(Build.SourcesDirectory)\CodeCoverage.runsettings' - condition: and(succeeded(), eq(variables['BuildConfiguration'],'Release-Windows'), eq(variables['BuildTarget'],'netcoreapp31')) + version: 6.x + condition: and(succeeded(), eq(variables['BuildConfiguration'],'Release-Windows'), eq(variables['BuildTarget'],'net6')) - task: DotNetCoreCLI@2 displayName: 'dotnet test (release) 6.0' diff --git a/build/onebranch/pr.yml b/build/onebranch/pr.yml index aaf5cbe04e..afd69e602c 100644 --- a/build/onebranch/pr.yml +++ b/build/onebranch/pr.yml @@ -42,14 +42,6 @@ variables: stages: - stage: Build jobs: - - job: Debug_Windows_Configuration_31 - variables: - BuildConfiguration: Debug-Windows - BuildTarget: 'netcoreapp31' # set the TargetFramework property for tests to use netcoreapp3.1 - steps: - - template: ci-build-steps.yml - - template: ci-test-steps.yml - - template: ci-component-detection-steps.yml - job: Debug_Windows_Configuration_6 variables: BuildConfiguration: Debug-Windows @@ -66,14 +58,6 @@ stages: - template: ci-build-steps.yml - template: ci-test-steps.yml - template: ci-component-detection-steps.yml - - job: Release_Windows_Configuration_31 - variables: - BuildConfiguration: Release-Windows - BuildTarget: 'netcoreapp31' # set the TargetFramework property for tests to use netcoreapp3.1 - steps: - - template: ci-build-steps.yml - - template: ci-test-steps.yml - - template: ci-component-detection-steps.yml - job: Release_Windows_Configuration_6 variables: BuildConfiguration: Release-Windows diff --git a/build/yaml/botbuilder-dotnet-ci.yml b/build/yaml/botbuilder-dotnet-ci.yml index 0eb70a982e..001d4dd577 100644 --- a/build/yaml/botbuilder-dotnet-ci.yml +++ b/build/yaml/botbuilder-dotnet-ci.yml @@ -42,14 +42,6 @@ variables: stages: - stage: Build jobs: - - job: Debug_Windows_Configuration_31 - variables: - BuildConfiguration: Debug-Windows - BuildTarget: 'netcoreapp31' # set the TargetFramework property for tests to use netcoreapp3.1 - steps: - - template: ci-build-steps.yml - - template: ci-test-steps.yml - - template: ci-component-detection-steps.yml - job: Debug_Windows_Configuration_6 variables: BuildConfiguration: Debug-Windows @@ -66,14 +58,6 @@ stages: - template: ci-build-steps.yml - template: ci-test-steps.yml - template: ci-component-detection-steps.yml - - job: Release_Windows_Configuration_31 - variables: - BuildConfiguration: Release-Windows - BuildTarget: 'netcoreapp31' # set the TargetFramework property for tests to use netcoreapp3.1 - steps: - - template: ci-build-steps.yml - - template: ci-test-steps.yml - - template: ci-component-detection-steps.yml - job: Release_Windows_Configuration_6 variables: BuildConfiguration: Release-Windows diff --git a/build/yaml/ci-test-steps.yml b/build/yaml/ci-test-steps.yml index e07b325b40..3484709eaa 100644 --- a/build/yaml/ci-test-steps.yml +++ b/build/yaml/ci-test-steps.yml @@ -20,21 +20,12 @@ steps: customCommand: 'install -g @microsoft/botframework-cli@next' - task: UseDotNet@2 - displayName: "Install .NET Core 3.1.415" + displayName: "Install .NET Core 6.0" continueOnError: true inputs: packageType: "sdk" - version: 3.1.415 - condition: and(succeeded(), eq(variables['BuildConfiguration'],'Release-Windows'), eq(variables['BuildTarget'],'netcoreapp31')) - -- task: DotNetCoreCLI@2 - displayName: 'dotnet test (release) 3.1' - inputs: - command: test - projects: | - Tests/**/*Tests.csproj - arguments: '-v n -f netcoreapp3.1 --configuration release --no-build --no-restore --filter "TestCategory!=IgnoreInAutomatedBuild&TestCategory!=FunctionalTests" --collect:"Code Coverage" --settings $(Build.SourcesDirectory)\CodeCoverage.runsettings' - condition: and(succeeded(), eq(variables['BuildConfiguration'],'Release-Windows'), eq(variables['BuildTarget'],'netcoreapp31')) + version: 6.x + condition: and(succeeded(), eq(variables['BuildConfiguration'],'Release-Windows'), eq(variables['BuildTarget'],'net6')) - task: DotNetCoreCLI@2 displayName: 'dotnet test (release) 6.0' diff --git a/generators/dotnet-templates/Microsoft.BotFramework.CSharp.CoreBot/content/.template.config/template.json b/generators/dotnet-templates/Microsoft.BotFramework.CSharp.CoreBot/content/.template.config/template.json index ab46bf3aeb..095256a34c 100644 --- a/generators/dotnet-templates/Microsoft.BotFramework.CSharp.CoreBot/content/.template.config/template.json +++ b/generators/dotnet-templates/Microsoft.BotFramework.CSharp.CoreBot/content/.template.config/template.json @@ -45,10 +45,6 @@ "description": "The target framework for the project.", "datatype": "choice", "choices": [ - { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" - }, { "choice": "net6.0", "description": "Target net6.0" diff --git a/generators/dotnet-templates/Microsoft.BotFramework.CSharp.EchoBot/content/.template.config/template.json b/generators/dotnet-templates/Microsoft.BotFramework.CSharp.EchoBot/content/.template.config/template.json index 642df55c6c..94fdc7fd5a 100644 --- a/generators/dotnet-templates/Microsoft.BotFramework.CSharp.EchoBot/content/.template.config/template.json +++ b/generators/dotnet-templates/Microsoft.BotFramework.CSharp.EchoBot/content/.template.config/template.json @@ -44,10 +44,6 @@ "description": "The target framework for the project.", "datatype": "choice", "choices": [ - { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" - }, { "choice": "net6.0", "description": "Target net6.0" diff --git a/generators/dotnet-templates/Microsoft.BotFramework.CSharp.EmptyBot/content/.template.config/template.json b/generators/dotnet-templates/Microsoft.BotFramework.CSharp.EmptyBot/content/.template.config/template.json index 7eeb345ce9..65651d121f 100644 --- a/generators/dotnet-templates/Microsoft.BotFramework.CSharp.EmptyBot/content/.template.config/template.json +++ b/generators/dotnet-templates/Microsoft.BotFramework.CSharp.EmptyBot/content/.template.config/template.json @@ -44,10 +44,6 @@ "description": "The target framework for the project.", "datatype": "choice", "choices": [ - { - "choice": "netcoreapp3.1", - "description": "Target netcoreapp3.1" - }, { "choice": "net6.0", "description": "Target net6.0" diff --git a/libraries/Microsoft.Bot.AdaptiveExpressions.Core/Microsoft.Bot.AdaptiveExpressions.Core.csproj b/libraries/Microsoft.Bot.AdaptiveExpressions.Core/Microsoft.Bot.AdaptiveExpressions.Core.csproj index 0a16fab13d..45a728fa15 100644 --- a/libraries/Microsoft.Bot.AdaptiveExpressions.Core/Microsoft.Bot.AdaptiveExpressions.Core.csproj +++ b/libraries/Microsoft.Bot.AdaptiveExpressions.Core/Microsoft.Bot.AdaptiveExpressions.Core.csproj @@ -40,7 +40,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/libraries/Microsoft.Bot.Builder.AI.LUIS/Microsoft.Bot.Builder.AI.Luis.csproj b/libraries/Microsoft.Bot.Builder.AI.LUIS/Microsoft.Bot.Builder.AI.Luis.csproj index 27c8b7797f..603929cbd2 100644 --- a/libraries/Microsoft.Bot.Builder.AI.LUIS/Microsoft.Bot.Builder.AI.Luis.csproj +++ b/libraries/Microsoft.Bot.Builder.AI.LUIS/Microsoft.Bot.Builder.AI.Luis.csproj @@ -31,6 +31,8 @@ + + diff --git a/libraries/Microsoft.Bot.Builder.AI.QnA/Microsoft.Bot.Builder.AI.QnA.csproj b/libraries/Microsoft.Bot.Builder.AI.QnA/Microsoft.Bot.Builder.AI.QnA.csproj index a8c4834f64..3c44873d2f 100644 --- a/libraries/Microsoft.Bot.Builder.AI.QnA/Microsoft.Bot.Builder.AI.QnA.csproj +++ b/libraries/Microsoft.Bot.Builder.AI.QnA/Microsoft.Bot.Builder.AI.QnA.csproj @@ -30,6 +30,8 @@ + + diff --git a/libraries/Microsoft.Bot.Builder.Azure.Blobs/BlobsTranscriptStore.cs b/libraries/Microsoft.Bot.Builder.Azure.Blobs/BlobsTranscriptStore.cs index 924c2d8c96..301daa3139 100644 --- a/libraries/Microsoft.Bot.Builder.Azure.Blobs/BlobsTranscriptStore.cs +++ b/libraries/Microsoft.Bot.Builder.Azure.Blobs/BlobsTranscriptStore.cs @@ -9,6 +9,7 @@ using System.Net; using System.Threading.Tasks; using Azure; +using Azure.Core; using Azure.Storage; using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; @@ -51,6 +52,22 @@ public BlobsTranscriptStore(string dataConnectionString, string containerName, J { } + /// + /// Initializes a new instance of the class. + /// + /// A Uri referencing the blob container that includes the name of the account and the name of the container. + /// The token credential to authenticate to the Azure storage. + /// Name of the Blob container where entities will be stored. + /// If passing in a custom JsonSerializer, we recommend the following settings: + /// jsonSerializer.TypeNameHandling = TypeNameHandling.None. + /// jsonSerializer.NullValueHandling = NullValueHandling.Include. + /// jsonSerializer.ContractResolver = new DefaultContractResolver(). + /// + public BlobsTranscriptStore(Uri blobServiceUri, TokenCredential tokenCredential, string containerName, JsonSerializer jsonSerializer = null) + : this(blobServiceUri, tokenCredential, containerName, default, jsonSerializer) + { + } + /// /// Initializes a new instance of the class. /// @@ -99,6 +116,59 @@ public BlobsTranscriptStore(string dataConnectionString, string containerName, S }, isThreadSafe: true); } + /// + /// Initializes a new instance of the class. + /// + /// A Uri referencing the blob container that includes the name of the account and the name of the container. + /// The token credential to authenticate to the Azure storage. + /// Name of the Blob container where entities will be stored. + /// Used for providing options for parallel transfers . + /// If passing in a custom JsonSerializer, we recommend the following settings: + /// jsonSerializer.TypeNameHandling = TypeNameHandling.None. + /// jsonSerializer.NullValueHandling = NullValueHandling.Include. + /// jsonSerializer.ContractResolver = new DefaultContractResolver(). + /// + public BlobsTranscriptStore(Uri blobServiceUri, TokenCredential tokenCredential, string containerName, StorageTransferOptions storageTransferOptions, JsonSerializer jsonSerializer = null) + { + if (blobServiceUri == null) + { + throw new ArgumentNullException(nameof(blobServiceUri)); + } + + if (tokenCredential == null) + { + throw new ArgumentNullException(nameof(tokenCredential)); + } + + if (string.IsNullOrEmpty(containerName)) + { + throw new ArgumentNullException(nameof(containerName)); + } + + _storageTransferOptions = storageTransferOptions; + + _jsonSerializer = jsonSerializer ?? JsonSerializer.Create(new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore, + Formatting = Formatting.Indented, + MaxDepth = null, + }); + + // Triggers a check for the existance of the container + _containerClient = new Lazy( + () => + { + var containerClient = new BlobContainerClient(blobServiceUri, tokenCredential); + if (!_checkedContainers.Contains(containerName)) + { + containerClient.CreateIfNotExistsAsync().Wait(); + _checkedContainers.Add(containerName); + } + + return containerClient; + }, isThreadSafe: true); + } + /// /// Initializes a new instance of the class. /// diff --git a/libraries/Microsoft.Bot.Builder.Azure.Blobs/Microsoft.Bot.Builder.Azure.Blobs.csproj b/libraries/Microsoft.Bot.Builder.Azure.Blobs/Microsoft.Bot.Builder.Azure.Blobs.csproj index 2ef8182e0f..681068f96f 100644 --- a/libraries/Microsoft.Bot.Builder.Azure.Blobs/Microsoft.Bot.Builder.Azure.Blobs.csproj +++ b/libraries/Microsoft.Bot.Builder.Azure.Blobs/Microsoft.Bot.Builder.Azure.Blobs.csproj @@ -21,9 +21,8 @@ - - - + + diff --git a/libraries/Microsoft.Bot.Builder.Azure.Queues/AzureQueueStorage.cs b/libraries/Microsoft.Bot.Builder.Azure.Queues/AzureQueueStorage.cs index ccac347b9d..52eead16de 100644 --- a/libraries/Microsoft.Bot.Builder.Azure.Queues/AzureQueueStorage.cs +++ b/libraries/Microsoft.Bot.Builder.Azure.Queues/AzureQueueStorage.cs @@ -45,7 +45,7 @@ public AzureQueueStorage(string queuesStorageConnectionString, string queueName, _jsonSettings = jsonSerializerSettings ?? new JsonSerializerSettings { - TypeNameHandling = TypeNameHandling.None, + TypeNameHandling = TypeNameHandling.None, // CODEQL [cs/unsafe-type-name-handling] We use None to prevent any type information from being serialized, ensuring that no arbitrary types are deserialized, which mitigates security risks. NullValueHandling = NullValueHandling.Ignore, MaxDepth = null }; @@ -67,7 +67,7 @@ internal AzureQueueStorage(QueueClient queueClient, JsonSerializerSettings jsonS _queueClient = queueClient; _jsonSettings = jsonSerializerSettings ?? new JsonSerializerSettings { - TypeNameHandling = TypeNameHandling.None, + TypeNameHandling = TypeNameHandling.None, // CODEQL [cs/unsafe-type-name-handling] We use None to prevent any type information from being serialized, ensuring that no arbitrary types are deserialized, which mitigates security risks. NullValueHandling = NullValueHandling.Ignore }; } diff --git a/libraries/Microsoft.Bot.Builder.Azure.Queues/Microsoft.Bot.Builder.Azure.Queues.csproj b/libraries/Microsoft.Bot.Builder.Azure.Queues/Microsoft.Bot.Builder.Azure.Queues.csproj index 98555be740..4d0b07b794 100644 --- a/libraries/Microsoft.Bot.Builder.Azure.Queues/Microsoft.Bot.Builder.Azure.Queues.csproj +++ b/libraries/Microsoft.Bot.Builder.Azure.Queues/Microsoft.Bot.Builder.Azure.Queues.csproj @@ -31,6 +31,8 @@ + + diff --git a/libraries/Microsoft.Bot.Builder.Azure/Microsoft.Bot.Builder.Azure.csproj b/libraries/Microsoft.Bot.Builder.Azure/Microsoft.Bot.Builder.Azure.csproj index d169ff9fe1..1733a929f9 100644 --- a/libraries/Microsoft.Bot.Builder.Azure/Microsoft.Bot.Builder.Azure.csproj +++ b/libraries/Microsoft.Bot.Builder.Azure/Microsoft.Bot.Builder.Azure.csproj @@ -36,7 +36,9 @@ - + + + diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.csproj b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.csproj index d91dc172cb..bceaa723a3 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.csproj +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.csproj @@ -10,7 +10,7 @@ - netstandard2.0;netcoreapp3.1;net6.0;net8.0 + netstandard2.0;net6.0;net8.0 Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime Library for building Adaptive Runtime bots using the Bot Framework SDK Library for building Adaptive Runtime bots using the Bot Framework SDK @@ -22,11 +22,6 @@ true - - - - - @@ -36,7 +31,6 @@ - diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Microsoft.Bot.Builder.Dialogs.Adaptive.csproj b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Microsoft.Bot.Builder.Dialogs.Adaptive.csproj index e6d6d1840e..874aa8f791 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Microsoft.Bot.Builder.Dialogs.Adaptive.csproj +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Microsoft.Bot.Builder.Dialogs.Adaptive.csproj @@ -39,6 +39,8 @@ + + diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Microsoft.Bot.Builder.Dialogs.Declarative.csproj b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Microsoft.Bot.Builder.Dialogs.Declarative.csproj index a41a4a414a..ae6fb39d2b 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Microsoft.Bot.Builder.Dialogs.Declarative.csproj +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Microsoft.Bot.Builder.Dialogs.Declarative.csproj @@ -36,6 +36,8 @@ + + diff --git a/libraries/Microsoft.Bot.Connector.Streaming/Microsoft.Bot.Connector.Streaming.csproj b/libraries/Microsoft.Bot.Connector.Streaming/Microsoft.Bot.Connector.Streaming.csproj index d235585250..7993456b6a 100644 --- a/libraries/Microsoft.Bot.Connector.Streaming/Microsoft.Bot.Connector.Streaming.csproj +++ b/libraries/Microsoft.Bot.Connector.Streaming/Microsoft.Bot.Connector.Streaming.csproj @@ -31,9 +31,6 @@ - - - diff --git a/libraries/Microsoft.Bot.Connector/Authentication/FederatedAppCredentials.cs b/libraries/Microsoft.Bot.Connector/Authentication/FederatedAppCredentials.cs new file mode 100644 index 0000000000..628ca236b1 --- /dev/null +++ b/libraries/Microsoft.Bot.Connector/Authentication/FederatedAppCredentials.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Net.Http; +using System.Threading; +using Microsoft.Extensions.Logging; + +namespace Microsoft.Bot.Connector.Authentication +{ + /// + /// Federated Credentials auth implementation. + /// + public class FederatedAppCredentials : AppCredentials + { + private readonly string _clientId; + + /// + /// Initializes a new instance of the class. + /// + /// App ID for the Application. + /// Client ID for the managed identity assigned to the bot. + /// Optional. The token tenant. + /// Optional. The scope for the token. + /// Optional to be used when acquiring tokens. + /// Optional to gather telemetry data while acquiring and managing credentials. + public FederatedAppCredentials(string appId, string clientId, string channelAuthTenant = null, string oAuthScope = null, HttpClient customHttpClient = null, ILogger logger = null) + : base(channelAuthTenant, customHttpClient, logger, oAuthScope) + { + if (string.IsNullOrWhiteSpace(appId)) + { + throw new ArgumentNullException(nameof(appId)); + } + + MicrosoftAppId = appId; + _clientId = clientId; + } + + /// + protected override Lazy BuildIAuthenticator() + { + return new Lazy( + () => new FederatedAuthenticator(MicrosoftAppId, _clientId, OAuthEndpoint, OAuthScope, CustomHttpClient, Logger), + LazyThreadSafetyMode.ExecutionAndPublication); + } + } +} diff --git a/libraries/Microsoft.Bot.Connector/Authentication/FederatedAuthenticator.cs b/libraries/Microsoft.Bot.Connector/Authentication/FederatedAuthenticator.cs new file mode 100644 index 0000000000..25ba359d80 --- /dev/null +++ b/libraries/Microsoft.Bot.Connector/Authentication/FederatedAuthenticator.cs @@ -0,0 +1,134 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Diagnostics; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Identity.Client; +using Microsoft.Identity.Web; + +namespace Microsoft.Bot.Connector.Authentication +{ + /// + /// Abstraction to acquire tokens from a Federated Credentials Application. + /// + internal class FederatedAuthenticator : IAuthenticator + { + private readonly string _authority; + private readonly string _scope; + private readonly string _clientId; + private readonly ILogger _logger; + private readonly IConfidentialClientApplication _clientApplication; + private readonly ManagedIdentityClientAssertion _managedIdentityClientAssertion; + + /// + /// Initializes a new instance of the class. + /// + /// App id for the Application. + /// Client id for the managed identity to be used for acquiring tokens. + /// Resource for which to acquire the token. + /// Login endpoint for request. + /// A customized instance of the HttpClient class. + /// The type used to perform logging. + public FederatedAuthenticator(string appId, string clientId, string authority, string scope, HttpClient customHttpClient = null, ILogger logger = null) + { + if (string.IsNullOrWhiteSpace(appId)) + { + throw new ArgumentNullException(nameof(appId)); + } + + if (string.IsNullOrWhiteSpace(scope)) + { + throw new ArgumentNullException(nameof(scope)); + } + + _authority = authority; + _scope = scope; + _clientId = clientId; + _logger = logger ?? NullLogger.Instance; + _clientApplication = CreateClientApplication(appId, customHttpClient); + _managedIdentityClientAssertion = new ManagedIdentityClientAssertion(_clientId); + } + + /// + public async Task GetTokenAsync(bool forceRefresh = false) + { + var watch = Stopwatch.StartNew(); + + var result = await Retry + .Run(() => AcquireTokenAsync(forceRefresh), HandleTokenProviderException) + .ConfigureAwait(false); + + watch.Stop(); + _logger.LogInformation($"GetTokenAsync: Acquired token using MSI in {watch.ElapsedMilliseconds}."); + + return result; + } + + private async Task AcquireTokenAsync(bool forceRefresh) + { + const string scopePostFix = "/.default"; + var scope = _scope; + + if (!scope.EndsWith(scopePostFix, StringComparison.OrdinalIgnoreCase)) + { + scope = $"{scope}{scopePostFix}"; + } + + _logger.LogDebug($"AcquireTokenAsync: authority={_authority}, scope={scope}"); + + var authResult = await _clientApplication + .AcquireTokenForClient(new[] { scope }) + .WithAuthority(_authority, true) + .WithForceRefresh(forceRefresh) + .ExecuteAsync() + .ConfigureAwait(false); + return new AuthenticatorResult + { + AccessToken = authResult.AccessToken, + ExpiresOn = authResult.ExpiresOn + }; + } + + private RetryParams HandleTokenProviderException(Exception e, int retryCount) + { + _logger.LogError(e, "Exception when trying to acquire token using Federated Credentials!"); + + if (e is MsalServiceException exception) + { + // stop retrying for all except for throttling response + if (exception.StatusCode != 429) + { + return RetryParams.StopRetrying; + } + } + + return RetryParams.DefaultBackOff(retryCount); + } + + private IConfidentialClientApplication CreateClientApplication(string appId, HttpClient customHttpClient = null) + { + _logger.LogDebug($"CreateClientApplication for appId={appId}"); + + var clientBuilder = ConfidentialClientApplicationBuilder + .Create(appId) + .WithClientAssertion((AssertionRequestOptions options) => FetchExternalTokenAsync()) + .WithCacheOptions(CacheOptions.EnableSharedCacheOptions); // for more cache options see https://learn.microsoft.com/entra/msal/dotnet/how-to/token-cache-serialization?tabs=msal + + if (customHttpClient != null) + { + clientBuilder.WithHttpClientFactory(new ConstantHttpClientFactory(customHttpClient)); + } + + return clientBuilder.Build(); + } + + private async Task FetchExternalTokenAsync() + { + return await _managedIdentityClientAssertion.GetSignedAssertion(default).ConfigureAwait(false); + } + } +} diff --git a/libraries/Microsoft.Bot.Connector/Authentication/FederatedServiceClientCredentialsFactory.cs b/libraries/Microsoft.Bot.Connector/Authentication/FederatedServiceClientCredentialsFactory.cs new file mode 100644 index 0000000000..66514607c4 --- /dev/null +++ b/libraries/Microsoft.Bot.Connector/Authentication/FederatedServiceClientCredentialsFactory.cs @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Rest; + +namespace Microsoft.Bot.Connector.Authentication +{ + /// + /// A Federated Credentials implementation of the interface. + /// + public class FederatedServiceClientCredentialsFactory : ServiceClientCredentialsFactory + { + private readonly string _appId; + private readonly string _clientId; + private readonly string _tenantId; + private readonly HttpClient _httpClient; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// Microsoft application Id. + /// Managed Identity Client Id. + /// The app tenant. + /// A custom httpClient to use. + /// A logger instance to use. + /// This enables authentication App Registration + Federated Credentials. + public FederatedServiceClientCredentialsFactory( + string appId, + string clientId, + string tenantId = null, + HttpClient httpClient = null, + ILogger logger = null) + : base() + { + if (string.IsNullOrWhiteSpace(appId)) + { + throw new ArgumentNullException(nameof(appId)); + } + + if (string.IsNullOrWhiteSpace(clientId)) + { + throw new ArgumentNullException(nameof(clientId)); + } + + _appId = appId; + _clientId = clientId; + _tenantId = tenantId; + _httpClient = httpClient; + _logger = logger; + } + + /// + public override Task IsValidAppIdAsync(string appId, CancellationToken cancellationToken) + { + return Task.FromResult(appId == _appId); + } + + /// + public override Task IsAuthenticationDisabledAsync(CancellationToken cancellationToken) + { + // Auth is always enabled for Certificate. + return Task.FromResult(false); + } + + /// + public override Task CreateCredentialsAsync( + string appId, string audience, string loginEndpoint, bool validateAuthority, CancellationToken cancellationToken) + { + if (appId != _appId) + { + throw new InvalidOperationException("Invalid App ID."); + } + + return Task.FromResult(new FederatedAppCredentials( + _appId, + _clientId, + channelAuthTenant: _tenantId, + oAuthScope: audience, + customHttpClient: _httpClient, + logger: _logger)); + } + } +} diff --git a/libraries/Microsoft.Bot.Connector/Authentication/JwtTokenExtractor.cs b/libraries/Microsoft.Bot.Connector/Authentication/JwtTokenExtractor.cs index 6e87659a27..0110de3388 100644 --- a/libraries/Microsoft.Bot.Connector/Authentication/JwtTokenExtractor.cs +++ b/libraries/Microsoft.Bot.Connector/Authentication/JwtTokenExtractor.cs @@ -264,7 +264,7 @@ private async Task ValidateTokenAsync(string jwtToken, string c var keyId = parsedToken.SigningKey.KeyId; var endorsements = await _endorsementsData.GetConfigurationAsync().ConfigureAwait(false); - // Note: On the Emulator Code Path, the endorsements collection is empty so the validation code + // Note: On the Emulator/Skills Code Path, the endorsements collection is empty so the validation code // below won't run. This is normal. if (!string.IsNullOrEmpty(keyId) && endorsements.TryGetValue(keyId, out var endorsementsForKey)) { @@ -287,10 +287,10 @@ private async Task ValidateTokenAsync(string jwtToken, string c } else { - // If we are to skip endorsement check, we want to double check we are in the emulator by explictly checking the token + // If we are to skip endorsement check, we want to double check we are in the emulator/skill by explicitly checking the token // Instead of assuming that the token is from the emulator based on the empty endorsements collection - var originalAuthHeader = "Bearer " + jwtToken; // We have to add the Bearer scheme back in for the Emulator check - if (!EmulatorValidation.IsTokenFromEmulator(originalAuthHeader)) + var originalAuthHeader = "Bearer " + jwtToken; // We have to add the Bearer scheme back in for the Emulator/Skill check + if (!EmulatorValidation.IsTokenFromEmulator(originalAuthHeader) && !SkillValidation.IsSkillToken(originalAuthHeader)) { throw new UnauthorizedAccessException("Could not validate endorsement key."); } diff --git a/libraries/Microsoft.Bot.Connector/Microsoft.Bot.Connector.csproj b/libraries/Microsoft.Bot.Connector/Microsoft.Bot.Connector.csproj index 9e2fdecb2c..1282bbbc15 100644 --- a/libraries/Microsoft.Bot.Connector/Microsoft.Bot.Connector.csproj +++ b/libraries/Microsoft.Bot.Connector/Microsoft.Bot.Connector.csproj @@ -31,6 +31,7 @@ + diff --git a/libraries/integration/Microsoft.Bot.Builder.Integration.ApplicationInsights.Core/Microsoft.Bot.Builder.Integration.ApplicationInsights.Core.csproj b/libraries/integration/Microsoft.Bot.Builder.Integration.ApplicationInsights.Core/Microsoft.Bot.Builder.Integration.ApplicationInsights.Core.csproj index 5549e02213..bf0620cd9b 100644 --- a/libraries/integration/Microsoft.Bot.Builder.Integration.ApplicationInsights.Core/Microsoft.Bot.Builder.Integration.ApplicationInsights.Core.csproj +++ b/libraries/integration/Microsoft.Bot.Builder.Integration.ApplicationInsights.Core/Microsoft.Bot.Builder.Integration.ApplicationInsights.Core.csproj @@ -9,7 +9,7 @@ - netstandard2.0;netcoreapp3.1;net6.0;net8.0 + netstandard2.0;net6.0;net8.0 Microsoft.Bot.Builder.Integration.ApplicationInsights.Core This library integrates the Microsoft Bot Builder SDK with Application Insights. This library provides integration between the Microsoft Bot Builder SDK and Application Insights. @@ -20,8 +20,7 @@ true - - + @@ -29,15 +28,7 @@ - - - - - - - - - + @@ -48,14 +39,14 @@ - - + + diff --git a/libraries/integration/Microsoft.Bot.Builder.Integration.ApplicationInsights.WebApi/Microsoft.Bot.Builder.Integration.ApplicationInsights.WebApi.csproj b/libraries/integration/Microsoft.Bot.Builder.Integration.ApplicationInsights.WebApi/Microsoft.Bot.Builder.Integration.ApplicationInsights.WebApi.csproj index 186a9c5dda..e3c7be3d16 100644 --- a/libraries/integration/Microsoft.Bot.Builder.Integration.ApplicationInsights.WebApi/Microsoft.Bot.Builder.Integration.ApplicationInsights.WebApi.csproj +++ b/libraries/integration/Microsoft.Bot.Builder.Integration.ApplicationInsights.WebApi/Microsoft.Bot.Builder.Integration.ApplicationInsights.WebApi.csproj @@ -57,7 +57,7 @@ - + diff --git a/libraries/integration/Microsoft.Bot.Builder.Integration.AspNet.Core/Microsoft.Bot.Builder.Integration.AspNet.Core.csproj b/libraries/integration/Microsoft.Bot.Builder.Integration.AspNet.Core/Microsoft.Bot.Builder.Integration.AspNet.Core.csproj index 58c39f2ae2..16041c0fc6 100644 --- a/libraries/integration/Microsoft.Bot.Builder.Integration.AspNet.Core/Microsoft.Bot.Builder.Integration.AspNet.Core.csproj +++ b/libraries/integration/Microsoft.Bot.Builder.Integration.AspNet.Core/Microsoft.Bot.Builder.Integration.AspNet.Core.csproj @@ -9,7 +9,7 @@ - netstandard2.0;netcoreapp3.1;net6.0;net8.0 + netstandard2.0;net6.0;net8.0 This library integrates the Microsoft Bot Builder SDK with ASP.NET Core. It offers idiomatic configuration APIs in addition to providing all the plumbing to direct incoming bot messages to a configured bot. This library provides integration between the Microsoft Bot Builder SDK and ASP.NET Core. @@ -19,22 +19,15 @@ true - - + - - - - - + - - @@ -45,6 +38,8 @@ + + diff --git a/tests/Adapters/Microsoft.Bot.Builder.Adapters.Facebook.Tests/Microsoft.Bot.Builder.Adapters.Facebook.Tests.csproj b/tests/Adapters/Microsoft.Bot.Builder.Adapters.Facebook.Tests/Microsoft.Bot.Builder.Adapters.Facebook.Tests.csproj index de76d54f30..145745d7fe 100644 --- a/tests/Adapters/Microsoft.Bot.Builder.Adapters.Facebook.Tests/Microsoft.Bot.Builder.Adapters.Facebook.Tests.csproj +++ b/tests/Adapters/Microsoft.Bot.Builder.Adapters.Facebook.Tests/Microsoft.Bot.Builder.Adapters.Facebook.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/Adapters/Microsoft.Bot.Builder.Adapters.Slack.Tests/Microsoft.Bot.Builder.Adapters.Slack.Tests.csproj b/tests/Adapters/Microsoft.Bot.Builder.Adapters.Slack.Tests/Microsoft.Bot.Builder.Adapters.Slack.Tests.csproj index 1a03ba8333..57ba5f841c 100644 --- a/tests/Adapters/Microsoft.Bot.Builder.Adapters.Slack.Tests/Microsoft.Bot.Builder.Adapters.Slack.Tests.csproj +++ b/tests/Adapters/Microsoft.Bot.Builder.Adapters.Slack.Tests/Microsoft.Bot.Builder.Adapters.Slack.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/Adapters/Microsoft.Bot.Builder.Adapters.Twilio.Tests/Microsoft.Bot.Builder.Adapters.Twilio.Tests.csproj b/tests/Adapters/Microsoft.Bot.Builder.Adapters.Twilio.Tests/Microsoft.Bot.Builder.Adapters.Twilio.Tests.csproj index eec3341a6a..d8d266b5df 100644 --- a/tests/Adapters/Microsoft.Bot.Builder.Adapters.Twilio.Tests/Microsoft.Bot.Builder.Adapters.Twilio.Tests.csproj +++ b/tests/Adapters/Microsoft.Bot.Builder.Adapters.Twilio.Tests/Microsoft.Bot.Builder.Adapters.Twilio.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/Adapters/Microsoft.Bot.Builder.Adapters.Webex.Tests/Microsoft.Bot.Builder.Adapters.Webex.Tests.csproj b/tests/Adapters/Microsoft.Bot.Builder.Adapters.Webex.Tests/Microsoft.Bot.Builder.Adapters.Webex.Tests.csproj index 06b8ffe65c..a1f25325c6 100644 --- a/tests/Adapters/Microsoft.Bot.Builder.Adapters.Webex.Tests/Microsoft.Bot.Builder.Adapters.Webex.Tests.csproj +++ b/tests/Adapters/Microsoft.Bot.Builder.Adapters.Webex.Tests/Microsoft.Bot.Builder.Adapters.Webex.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/AdaptiveExpressions.Tests/AdaptiveExpressions.Tests.csproj b/tests/AdaptiveExpressions.Tests/AdaptiveExpressions.Tests.csproj index 572ca47393..1ed4409807 100644 --- a/tests/AdaptiveExpressions.Tests/AdaptiveExpressions.Tests.csproj +++ b/tests/AdaptiveExpressions.Tests/AdaptiveExpressions.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/AdaptiveExpressions.Tests/ExpressionParserTests.cs b/tests/AdaptiveExpressions.Tests/ExpressionParserTests.cs index 3d3c642690..ac700f9447 100644 --- a/tests/AdaptiveExpressions.Tests/ExpressionParserTests.cs +++ b/tests/AdaptiveExpressions.Tests/ExpressionParserTests.cs @@ -1048,11 +1048,7 @@ public class ExpressionParserTests Test("lastIndexOf(newGuid(), '-')", 23), Test("lastIndexOf(hello, '-')", -1), Test("lastIndexOf(nullObj, '-')", -1), -#if NET5_0_OR_GREATER //There's a breaking change in .NET5 for this particular case. See https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/lastindexof-improved-handling-of-empty-values#change-description Test("lastIndexOf(hello, nullObj)", 5), -#else - Test("lastIndexOf(hello, nullObj)", 4), -#endif Test("lastIndexOf(json('[\"a\", \"b\", \"a\"]'), 'a')", 2), Test("lastIndexOf(json('[\"a\", \"b\"]'), 'c')", -1), Test("lastIndexOf(createArray('abc', 'def', 'ghi', 'def'), 'def')", 3), diff --git a/tests/Microsoft.Bot.AdaptiveExpressions.Core.Tests/Microsoft.Bot.AdaptiveExpressions.Core.Tests.csproj b/tests/Microsoft.Bot.AdaptiveExpressions.Core.Tests/Microsoft.Bot.AdaptiveExpressions.Core.Tests.csproj index 511537ff37..6da878a08f 100644 --- a/tests/Microsoft.Bot.AdaptiveExpressions.Core.Tests/Microsoft.Bot.AdaptiveExpressions.Core.Tests.csproj +++ b/tests/Microsoft.Bot.AdaptiveExpressions.Core.Tests/Microsoft.Bot.AdaptiveExpressions.Core.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net8.0 net6.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/Microsoft.Bot.Builder.AI.LUIS.Tests/Microsoft.Bot.Builder.AI.Luis.Tests.csproj b/tests/Microsoft.Bot.Builder.AI.LUIS.Tests/Microsoft.Bot.Builder.AI.Luis.Tests.csproj index 67c828e841..bd63fd7bed 100644 --- a/tests/Microsoft.Bot.Builder.AI.LUIS.Tests/Microsoft.Bot.Builder.AI.Luis.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.AI.LUIS.Tests/Microsoft.Bot.Builder.AI.Luis.Tests.csproj @@ -1,9 +1,8 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.AI.Luis.TestUtils/Microsoft.Bot.Builder.AI.Luis.TestUtils.csproj b/tests/Microsoft.Bot.Builder.AI.Luis.TestUtils/Microsoft.Bot.Builder.AI.Luis.TestUtils.csproj index bdd1ecba6c..b257e0cd6a 100644 --- a/tests/Microsoft.Bot.Builder.AI.Luis.TestUtils/Microsoft.Bot.Builder.AI.Luis.TestUtils.csproj +++ b/tests/Microsoft.Bot.Builder.AI.Luis.TestUtils/Microsoft.Bot.Builder.AI.Luis.TestUtils.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 Debug;Release diff --git a/tests/Microsoft.Bot.Builder.AI.Orchestrator.Tests/Microsoft.Bot.Builder.AI.Orchestrator.Tests.csproj b/tests/Microsoft.Bot.Builder.AI.Orchestrator.Tests/Microsoft.Bot.Builder.AI.Orchestrator.Tests.csproj index 94ad5fc8d7..f68f171902 100644 --- a/tests/Microsoft.Bot.Builder.AI.Orchestrator.Tests/Microsoft.Bot.Builder.AI.Orchestrator.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.AI.Orchestrator.Tests/Microsoft.Bot.Builder.AI.Orchestrator.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/Microsoft.Bot.Builder.AI.QnA.Tests.csproj b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/Microsoft.Bot.Builder.AI.QnA.Tests.csproj index 8aa1e604b9..2792d55300 100644 --- a/tests/Microsoft.Bot.Builder.AI.QnA.Tests/Microsoft.Bot.Builder.AI.QnA.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.AI.QnA.Tests/Microsoft.Bot.Builder.AI.QnA.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.Ai.LUISV3.tests/Microsoft.Bot.Builder.AI.LuisV3.Tests.csproj b/tests/Microsoft.Bot.Builder.Ai.LUISV3.tests/Microsoft.Bot.Builder.AI.LuisV3.Tests.csproj index c42b6f32d3..39d48be55a 100644 --- a/tests/Microsoft.Bot.Builder.Ai.LUISV3.tests/Microsoft.Bot.Builder.AI.LuisV3.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Ai.LUISV3.tests/Microsoft.Bot.Builder.AI.LuisV3.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.ApplicationInsights.Tests/Microsoft.Bot.Builder.ApplicationInsights.Tests.csproj b/tests/Microsoft.Bot.Builder.ApplicationInsights.Tests/Microsoft.Bot.Builder.ApplicationInsights.Tests.csproj index 0b02d86caa..2f6ef4bd28 100644 --- a/tests/Microsoft.Bot.Builder.ApplicationInsights.Tests/Microsoft.Bot.Builder.ApplicationInsights.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.ApplicationInsights.Tests/Microsoft.Bot.Builder.ApplicationInsights.Tests.csproj @@ -1,9 +1,8 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.Azure.Tests/BlobsTranscriptStoreTests.cs b/tests/Microsoft.Bot.Builder.Azure.Tests/BlobsTranscriptStoreTests.cs index 8818e52dfd..fe755ded97 100644 --- a/tests/Microsoft.Bot.Builder.Azure.Tests/BlobsTranscriptStoreTests.cs +++ b/tests/Microsoft.Bot.Builder.Azure.Tests/BlobsTranscriptStoreTests.cs @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Azure; +using Azure.Core; using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using Microsoft.Bot.Builder.Azure.Blobs; @@ -50,6 +51,13 @@ public void ConstructorValidation() "containerName", JsonSerializer.Create(new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All })); + var blobServiceUri = new Uri("https://storage.net/"); + + var mockCredential = new Mock(); + mockCredential + .Setup(c => c.GetTokenAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(new AccessToken("fake-token", DateTimeOffset.UtcNow.AddHours(1))); + // No dataConnectionString. Should throw. Assert.Throws(() => new BlobsTranscriptStore(null, "containerName")); Assert.Throws(() => new BlobsTranscriptStore(string.Empty, "containerName")); @@ -57,6 +65,16 @@ public void ConstructorValidation() // No containerName. Should throw. Assert.Throws(() => new BlobsTranscriptStore(ConnectionString, null)); Assert.Throws(() => new BlobsTranscriptStore(ConnectionString, string.Empty)); + + // No URI. Should throw. + Assert.Throws(() => new BlobsTranscriptStore(blobServiceUri: null, mockCredential.Object, "containerName")); + + // No tokenCredential. Should throw. + Assert.Throws(() => new BlobsTranscriptStore(blobServiceUri, null, "containerName")); + + // No containerName. Should throw. + Assert.Throws(() => new BlobsTranscriptStore(blobServiceUri, mockCredential.Object, null)); + Assert.Throws(() => new BlobsTranscriptStore(blobServiceUri, mockCredential.Object, string.Empty)); } [Fact] diff --git a/tests/Microsoft.Bot.Builder.Azure.Tests/Microsoft.Bot.Builder.Azure.Tests.csproj b/tests/Microsoft.Bot.Builder.Azure.Tests/Microsoft.Bot.Builder.Azure.Tests.csproj index 5292ec4326..b0c39a4474 100644 --- a/tests/Microsoft.Bot.Builder.Azure.Tests/Microsoft.Bot.Builder.Azure.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Azure.Tests/Microsoft.Bot.Builder.Azure.Tests.csproj @@ -1,9 +1,8 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Tests.csproj b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Tests.csproj index 0b861852b5..a61f05b810 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests.csproj b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests.csproj index 449efd36db..04d7684779 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Templates.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests.csproj b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests.csproj index e42a6c6823..8b1fae76ce 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests/Microsoft.Bot.Builder.Dialogs.Adaptive.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Debugging.Tests/Microsoft.Bot.Builder.Dialogs.Debugging.Tests.csproj b/tests/Microsoft.Bot.Builder.Dialogs.Debugging.Tests/Microsoft.Bot.Builder.Dialogs.Debugging.Tests.csproj index 110c54e814..bf1135fb03 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Debugging.Tests/Microsoft.Bot.Builder.Dialogs.Debugging.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Dialogs.Debugging.Tests/Microsoft.Bot.Builder.Dialogs.Debugging.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests.csproj b/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests.csproj index 4c2d30e3c6..62716eb9fd 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests/Microsoft.Bot.Builder.Dialogs.Declarative.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Flow.Tests/Microsoft.Bot.Builder.Dialogs.Flows.Tests.csproj b/tests/Microsoft.Bot.Builder.Dialogs.Flow.Tests/Microsoft.Bot.Builder.Dialogs.Flows.Tests.csproj index 7193c4e3ec..28a64b3bd7 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Flow.Tests/Microsoft.Bot.Builder.Dialogs.Flows.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Dialogs.Flow.Tests/Microsoft.Bot.Builder.Dialogs.Flows.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net8.0 false diff --git a/tests/Microsoft.Bot.Builder.Dialogs.Tests/Microsoft.Bot.Builder.Dialogs.Tests.csproj b/tests/Microsoft.Bot.Builder.Dialogs.Tests/Microsoft.Bot.Builder.Dialogs.Tests.csproj index 7e333ca2b1..55a395957f 100644 --- a/tests/Microsoft.Bot.Builder.Dialogs.Tests/Microsoft.Bot.Builder.Dialogs.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Dialogs.Tests/Microsoft.Bot.Builder.Dialogs.Tests.csproj @@ -1,9 +1,8 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.LanguageGeneration.Tests/Microsoft.Bot.Builder.LanguageGeneration.Tests.csproj b/tests/Microsoft.Bot.Builder.LanguageGeneration.Tests/Microsoft.Bot.Builder.LanguageGeneration.Tests.csproj index d0e8c9c513..d8f0eae754 100644 --- a/tests/Microsoft.Bot.Builder.LanguageGeneration.Tests/Microsoft.Bot.Builder.LanguageGeneration.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.LanguageGeneration.Tests/Microsoft.Bot.Builder.LanguageGeneration.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/Microsoft.Bot.Builder.TemplateManager/Microsoft.Bot.Builder.TemplateManager.Tests.csproj b/tests/Microsoft.Bot.Builder.TemplateManager/Microsoft.Bot.Builder.TemplateManager.Tests.csproj index b400149c06..c6372fafc9 100644 --- a/tests/Microsoft.Bot.Builder.TemplateManager/Microsoft.Bot.Builder.TemplateManager.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.TemplateManager/Microsoft.Bot.Builder.TemplateManager.Tests.csproj @@ -1,9 +1,8 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.TestBot.Json/.vscode/launch.json b/tests/Microsoft.Bot.Builder.TestBot.Json/.vscode/launch.json index 9d704d31fb..8598e71479 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Json/.vscode/launch.json +++ b/tests/Microsoft.Bot.Builder.TestBot.Json/.vscode/launch.json @@ -27,7 +27,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/bin/Debug/netcoreapp3.1/Microsoft.Bot.Builder.TestBot.Json.dll", + "program": "${workspaceFolder}/bin/Debug/net8.0/Microsoft.Bot.Builder.TestBot.Json.dll", "args": [], "cwd": "${workspaceFolder}", "stopAtEntry": false, diff --git a/tests/Microsoft.Bot.Builder.TestBot.Tests/Microsoft.Bot.Builder.TestBot.Tests.csproj b/tests/Microsoft.Bot.Builder.TestBot.Tests/Microsoft.Bot.Builder.TestBot.Tests.csproj index a335dc658f..1aa247443e 100644 --- a/tests/Microsoft.Bot.Builder.TestBot.Tests/Microsoft.Bot.Builder.TestBot.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.TestBot.Tests/Microsoft.Bot.Builder.TestBot.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false Microsoft.Bot.Builder.TestBot.Tests Microsoft.BotBuilderSamples.Tests diff --git a/tests/Microsoft.Bot.Builder.Testing.Tests/Microsoft.Bot.Builder.Testing.Tests.csproj b/tests/Microsoft.Bot.Builder.Testing.Tests/Microsoft.Bot.Builder.Testing.Tests.csproj index 7ec81bb29e..8e0449513d 100644 --- a/tests/Microsoft.Bot.Builder.Testing.Tests/Microsoft.Bot.Builder.Testing.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Testing.Tests/Microsoft.Bot.Builder.Testing.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.Tests/Microsoft.Bot.Builder.Tests.csproj b/tests/Microsoft.Bot.Builder.Tests/Microsoft.Bot.Builder.Tests.csproj index ca9b361686..b5f62a9fa2 100644 --- a/tests/Microsoft.Bot.Builder.Tests/Microsoft.Bot.Builder.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Tests/Microsoft.Bot.Builder.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Builder.Transcripts.Tests/Microsoft.Bot.Builder.Transcripts.Tests.csproj b/tests/Microsoft.Bot.Builder.Transcripts.Tests/Microsoft.Bot.Builder.Transcripts.Tests.csproj index f917bfd845..4756d23ea6 100644 --- a/tests/Microsoft.Bot.Builder.Transcripts.Tests/Microsoft.Bot.Builder.Transcripts.Tests.csproj +++ b/tests/Microsoft.Bot.Builder.Transcripts.Tests/Microsoft.Bot.Builder.Transcripts.Tests.csproj @@ -1,9 +1,8 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Configuration.Tests/Microsoft.Bot.Configuration.Tests.csproj b/tests/Microsoft.Bot.Configuration.Tests/Microsoft.Bot.Configuration.Tests.csproj index 98c8ad7e09..09f6e6f690 100644 --- a/tests/Microsoft.Bot.Configuration.Tests/Microsoft.Bot.Configuration.Tests.csproj +++ b/tests/Microsoft.Bot.Configuration.Tests/Microsoft.Bot.Configuration.Tests.csproj @@ -1,9 +1,8 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Connector.Streaming.Tests/Microsoft.Bot.Connector.Streaming.Tests.csproj b/tests/Microsoft.Bot.Connector.Streaming.Tests/Microsoft.Bot.Connector.Streaming.Tests.csproj index c5bc28057a..e2cbf7d3d4 100644 --- a/tests/Microsoft.Bot.Connector.Streaming.Tests/Microsoft.Bot.Connector.Streaming.Tests.csproj +++ b/tests/Microsoft.Bot.Connector.Streaming.Tests/Microsoft.Bot.Connector.Streaming.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Connector.Tests/Authentication/JwtTokenExtractorTests.cs b/tests/Microsoft.Bot.Connector.Tests/Authentication/JwtTokenExtractorTests.cs index d7b2cb6c2b..0796b7cc49 100644 --- a/tests/Microsoft.Bot.Connector.Tests/Authentication/JwtTokenExtractorTests.cs +++ b/tests/Microsoft.Bot.Connector.Tests/Authentication/JwtTokenExtractorTests.cs @@ -156,9 +156,7 @@ private static TokenValidationParameters CreateTokenValidationParameters(X509Cer }; } -#if NET5_0_OR_GREATER [SupportedOSPlatform("windows")] -#endif private static X509Certificate2 CreateSelfSignedCertificate(string cn, DateTimeOffset from, DateTimeOffset to) { var parameters = new CspParameters(24, "Microsoft Enhanced RSA and AES Cryptographic Provider") @@ -184,9 +182,7 @@ private static X509Certificate2 CreateSelfSignedCertificate(string cn, DateTimeO return cert; } -#if NET5_0_OR_GREATER [SupportedOSPlatform("windows")] -#endif private static void DeleteKeyContainer(string cn) { // %APPDATA%\Microsoft\Crypto\RSA diff --git a/tests/Microsoft.Bot.Connector.Tests/Microsoft.Bot.Connector.Tests.csproj b/tests/Microsoft.Bot.Connector.Tests/Microsoft.Bot.Connector.Tests.csproj index 5744635a8f..e242ef22ac 100644 --- a/tests/Microsoft.Bot.Connector.Tests/Microsoft.Bot.Connector.Tests.csproj +++ b/tests/Microsoft.Bot.Connector.Tests/Microsoft.Bot.Connector.Tests.csproj @@ -1,9 +1,8 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Schema.Tests/Microsoft.Bot.Schema.Tests.csproj b/tests/Microsoft.Bot.Schema.Tests/Microsoft.Bot.Schema.Tests.csproj index 6fa2c24ac0..8c9f5c7648 100644 --- a/tests/Microsoft.Bot.Schema.Tests/Microsoft.Bot.Schema.Tests.csproj +++ b/tests/Microsoft.Bot.Schema.Tests/Microsoft.Bot.Schema.Tests.csproj @@ -1,9 +1,8 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/Microsoft.Bot.Streaming.Tests/Microsoft.Bot.Streaming.Tests.csproj b/tests/Microsoft.Bot.Streaming.Tests/Microsoft.Bot.Streaming.Tests.csproj index 1f31578d2a..ae2fdb1cbe 100644 --- a/tests/Microsoft.Bot.Streaming.Tests/Microsoft.Bot.Streaming.Tests.csproj +++ b/tests/Microsoft.Bot.Streaming.Tests/Microsoft.Bot.Streaming.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false diff --git a/tests/Parsers/Microsoft.Bot.Builder.Parsers.LU.Tests/Microsoft.Bot.Builder.Parsers.LU.Tests.csproj b/tests/Parsers/Microsoft.Bot.Builder.Parsers.LU.Tests/Microsoft.Bot.Builder.Parsers.LU.Tests.csproj index b572dc143c..bd53dc6360 100644 --- a/tests/Parsers/Microsoft.Bot.Builder.Parsers.LU.Tests/Microsoft.Bot.Builder.Parsers.LU.Tests.csproj +++ b/tests/Parsers/Microsoft.Bot.Builder.Parsers.LU.Tests/Microsoft.Bot.Builder.Parsers.LU.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release diff --git a/tests/integration/Microsoft.Bot.ApplicationInsights.Core.Tests/Microsoft.Bot.ApplicationInsights.Core.Tests.csproj b/tests/integration/Microsoft.Bot.ApplicationInsights.Core.Tests/Microsoft.Bot.ApplicationInsights.Core.Tests.csproj index 9ed9fd71bd..ffb66a7ff2 100644 --- a/tests/integration/Microsoft.Bot.ApplicationInsights.Core.Tests/Microsoft.Bot.ApplicationInsights.Core.Tests.csproj +++ b/tests/integration/Microsoft.Bot.ApplicationInsights.Core.Tests/Microsoft.Bot.ApplicationInsights.Core.Tests.csproj @@ -1,20 +1,14 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release - - - - - diff --git a/tests/integration/Microsoft.Bot.Builder.Integration.AspNet.Core.Tests/Microsoft.Bot.Builder.Integration.AspNet.Core.Tests.csproj b/tests/integration/Microsoft.Bot.Builder.Integration.AspNet.Core.Tests/Microsoft.Bot.Builder.Integration.AspNet.Core.Tests.csproj index 4e003d1017..e9a0ba7564 100644 --- a/tests/integration/Microsoft.Bot.Builder.Integration.AspNet.Core.Tests/Microsoft.Bot.Builder.Integration.AspNet.Core.Tests.csproj +++ b/tests/integration/Microsoft.Bot.Builder.Integration.AspNet.Core.Tests/Microsoft.Bot.Builder.Integration.AspNet.Core.Tests.csproj @@ -1,10 +1,9 @@  - netcoreapp3.1 net6.0 net8.0 - netcoreapp3.1;net6.0;net8.0 + net6.0;net8.0 false false Debug;Release