Added ConfigureAwait and refactored the service communications class
This commit is contained in:
Родитель
3ff892ac83
Коммит
0c7291dbba
|
@ -43,6 +43,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Images", "Images", "{B55A74
|
|||
docs\Images\qnaservice03.png = docs\Images\qnaservice03.png
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bot.Services", "src\Bot.Services\Bot.Services.csproj", "{DD1B3FF6-0FAC-41F6-843C-183676F55AD4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bot.Models", "src\Bot.Models\Bot.Models.csproj", "{72CF9064-499F-456D-B879-E1335B2BD6CA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -53,6 +57,14 @@ Global
|
|||
{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DD1B3FF6-0FAC-41F6-843C-183676F55AD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DD1B3FF6-0FAC-41F6-843C-183676F55AD4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DD1B3FF6-0FAC-41F6-843C-183676F55AD4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DD1B3FF6-0FAC-41F6-843C-183676F55AD4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{72CF9064-499F-456D-B879-E1335B2BD6CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{72CF9064-499F-456D-B879-E1335B2BD6CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{72CF9064-499F-456D-B879-E1335B2BD6CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{72CF9064-499F-456D-B879-E1335B2BD6CA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -60,6 +72,8 @@ Global
|
|||
GlobalSection(NestedProjects) = preSolution
|
||||
{A8BA1066-5695-4D71-ABB4-65E5A5E0C3D4} = {07FC2994-6ECD-42BC-9CF3-77CE505216AA}
|
||||
{B55A743C-BA04-491F-9C64-E7339C30684F} = {BAD9B155-1FCF-4735-A8EC-D8ECCDAB9136}
|
||||
{DD1B3FF6-0FAC-41F6-843C-183676F55AD4} = {07FC2994-6ECD-42BC-9CF3-77CE505216AA}
|
||||
{72CF9064-499F-456D-B879-E1335B2BD6CA} = {07FC2994-6ECD-42BC-9CF3-77CE505216AA}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {D966732D-8A63-4571-81B5-ED6624F0B40E}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Adding New Intents
|
||||
The [Language Understanding Intelligent Service (LUIS)](http://luis.ai) provides the ability to process conversational information
|
||||
and extract an intent from that information. This ability enables us to map sentences received to a particular function defined with in the
|
||||
[_ActionDialog_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Dialogs/ActionDialog.cs) class. As an example if an authenticated
|
||||
The [Language Understanding Intelligent Service (LUIS)](http://luis.ai) provides the ability to process conversational information and extract an intent from that information. This ability enables us to map sentences received to a particular function defined within the
|
||||
[_ActionDialog_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Dialogs/ActionDialog.cs) class. As an example, if an authenticated
|
||||
user sends _list customers_ this will be processed by LUIS and eventually mapped to the [_ExecuteAsync_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Intents/ListCustomersIntent.cs#L61)
|
||||
function defined in the [_ListCustomerIntnent_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Intents/ListCustomersIntent.cs) class.
|
||||
|
||||
|
@ -17,18 +16,18 @@ The following logic is utilized to properly route the intent to the appropriate
|
|||
```csharp
|
||||
key = result.TopScoringIntent.Intent.ToCamelCase();
|
||||
|
||||
principal = await context.GetCustomerPrincipalAsync(this.service);
|
||||
principal = await context.GetCustomerPrincipalAsync(this.service).ConfigureAwait(false);
|
||||
|
||||
if (principal == null)
|
||||
{
|
||||
await this.HelpAsync(context);
|
||||
await this.HelpAsync(context).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (principal.AvailableIntents.ContainsKey(key))
|
||||
{
|
||||
await principal.AvailableIntents[key]
|
||||
.ExecuteAsync(context, message, result, this.service);
|
||||
.ExecuteAsync(context, message, result, this.service).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -37,8 +36,7 @@ else
|
|||
```
|
||||
|
||||
First the code will verify that the user has successfully authenticated. This is accomplished by extracting the [_CustomerPrincipal_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Security/CustomerPrincipal.cs)
|
||||
from the private conversation data. If that object is not present in the private conversation data that means the user has not authenticated. Second the code will verify the intent exists in the dictionary of available intents for the
|
||||
authenticated user. The dictionary of availalbe intents is generated in the [_GetCustomerPrincipalAsync_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Controllers/OAuthCallbackController.cs#L191) function
|
||||
from the private conversation data. If that object is not present in the private conversation data that means the user has not authenticated. Second, the code will verify the intent exists in the dictionary of available intents for the authenticated user. The dictionary of available intents is generated in the [_GetCustomerPrincipalAsync_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Controllers/OAuthCallbackController.cs#L191) function
|
||||
defined in the [_OAuthCallbackController_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Controllers/OAuthCallbackController.cs#L191) class.
|
||||
|
||||
```csharp
|
||||
|
@ -52,10 +50,10 @@ AvailableIntents = (from intent in this.Service.Intent.Intents
|
|||
This LINQ statement will create a dictionary that contains a reference to classes that implement the [_IIntent_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Intents/IIntent.cs) interface where the user has the appropriate privileges.
|
||||
|
||||
## Creating A New Intent
|
||||
New intents will need to be defined within the LUIS application and then through code. Perform the following tasksto create a new intent within LUIS
|
||||
New intents will need to be defined within the LUIS application and then through code. Perform the following tasks to create a new intent within LUIS
|
||||
|
||||
1. Login into the [LUIS portal](http://luis.ai) and import the [_Partner-Center-Bot_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/Partner-Center-Bot.json) application if you have not already
|
||||
2. Select the _Partner-Center-Bot_ application and then click the _Intents_ link found on the left hand size of the dashboard
|
||||
1. Login to the [LUIS portal](http://luis.ai) and import the [_Partner-Center-Bot_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/Partner-Center-Bot.json) application if you have not already
|
||||
2. Select the _Partner-Center-Bot_ application and then click the _Intents_ link found on the left-hand side of the dashboard
|
||||
3. Click the _Add Intent_ button and then specify an appropriate name and then click _Save_
|
||||
|
||||
![Add a new intent](Images/luis01.png)
|
||||
|
@ -64,9 +62,8 @@ New intents will need to be defined within the LUIS application and then through
|
|||
|
||||
![Adding utterances to an intent](Images/luis02.png)
|
||||
|
||||
If you would like to learn more about the various configurations then check out [_Add Intents_](https://github.com/Microsoft/Cognitive-Documentation/blob/master/Content/en-us/LUIS/Add-intents.md) from the LUIS documentation. Next you will need add a new class to the [_Intent_](https://github.com/Microsoft/Partner-Center-Bot/tree/master/src/Bot/Intents) directory that implements the
|
||||
[_IIntent_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Intents/IIntent.cs) interface. By doing this all of the required functions and properties will
|
||||
be defined. The following code is a sample of what the new intent should look like.
|
||||
If you would like to learn more about the various configurations then check out [_Add Intents_](https://github.com/Microsoft/Cognitive-Documentation/blob/master/Content/en-us/LUIS/Add-intents.md) from the LUIS documentation. Next, you will need to add a new class to the [_Intent_](https://github.com/Microsoft/Partner-Center-Bot/tree/master/src/Bot/Intents) directory that implements the
|
||||
[_IIntent_](https://github.com/Microsoft/Partner-Center-Bot/blob/master/src/Bot/Intents/IIntent.cs) interface. By doing this all of the required functions and properties will be defined. The following code is a sample of what the new intent should look like.
|
||||
|
||||
```csharp
|
||||
// -----------------------------------------------------------------------
|
||||
|
@ -145,11 +142,11 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
correlationId = Guid.NewGuid();
|
||||
response = context.MakeMessage();
|
||||
|
||||
principal = await context.GetCustomerPrincipalAsync(service);
|
||||
principal = await context.GetCustomerPrincipalAsync(service).ConfigureAwait(false);
|
||||
|
||||
response.Text = "This is sample intent.";
|
||||
|
||||
await context.PostAsync(response);
|
||||
await context.PostAsync(response).ConfigureAwait(false);
|
||||
|
||||
// Capture the request for the customer summary for analysis.
|
||||
eventProperties = new Dictionary<string, string>
|
||||
|
|
|
@ -35,7 +35,7 @@ The bot requires an Azure AD application that grants privileges to Azure AD and
|
|||
|
||||
3. Click _+ Add_ to start the new application wizard
|
||||
4. Specify an appropriate name for the bot, select _Web app / API_ for the application, an appropriate value for the sign-on URL, and then click _Create_
|
||||
5. Click _Required permissions_ found on the settings blade for the the application and then click _+ Add_
|
||||
5. Click _Required permissions_ found on the settings blade for the application and then click _+ Add_
|
||||
6. Add the _Microsoft Graph_ API and grant it the _Read directory data_ application permission
|
||||
7. Add the _Partner Center API_ and grant it the _Access Partner Center PPE_ delegated permission
|
||||
|
||||
|
@ -93,10 +93,6 @@ The following table provides details for the appropriate value for each of the p
|
|||
| Application Id | Identifier for the application created in the Azure AD Application section |
|
||||
| Application Secret | Secret key create in the step 9 of the Azure AD application section |
|
||||
| Application Tenant Id | Identifier for the tenant where the application from the Azure AD Application was created |
|
||||
| Key Vault App Cert Thumbprint | Thumbprint of the certificated created in the Azure Key Vault section |
|
||||
| Key Vault App Id | Identifier for the Azure AD application created in the Azure Key Vault section |
|
||||
| Key Vault Name | Name for the Key Vault. This name should not contain any special characters or spaces |
|
||||
| Key Vault Tenant Id | Identifier for the tenant where the instance of Azure Key Vault is being created |
|
||||
| LUIS App Id | Identifier for the LUIS application created in the *Create a New LUIS Application* section |
|
||||
| LUIS App Key | Key for the LUIS application created in the *Create a New LUIS Application* section |
|
||||
| Microsoft App Id | Identifier of the application created in the *Register With the Bot Framework* section |
|
||||
|
@ -106,26 +102,3 @@ The following table provides details for the appropriate value for each of the p
|
|||
| Partner Center Application Tenat Id | Account ID value obtained from the Partner Center Azure AD Application section |
|
||||
| QnA Knowledgebase Id | Identifier for the knowledgebase created in the *Create a New Instance of the QnA Service* section |
|
||||
| QnA Subscription Key | Subscription key for the knowledgebase created in the *Create a New Instance of the QnA Service* section |
|
||||
|
||||
## Configure Azure Key Vault Access Policy
|
||||
Now that the instance of Azure Key Vault has been provisioned you can add the access policy that will
|
||||
enable the Azure AD application the ability to create, delete, and read secrets. Perform the following
|
||||
to create the access policy
|
||||
|
||||
1. Open PowerShell and install the [Azure AD PowerShell cmdlets](https://docs.microsoft.com/en-us/powershell/azure/install-adv2?view=azureadps-2.0)
|
||||
if you necessary
|
||||
2. Update the following cmdlets and then invoke them
|
||||
|
||||
```powershell
|
||||
Connect-AzureAD
|
||||
Login-AzureRmAccount
|
||||
|
||||
## Update these variable before invoking the rest of the cmdlets
|
||||
|
||||
# The value for the AppId should be the application identifier for the Azure AD application created for Key Vault
|
||||
$spn = Get-AzureADServicePrincipal | ? {$_.AppId -eq 'b6b84568-6c01-4981-a80f-09da9a20bbed'}
|
||||
$resourceGroupName = "ResourceGroupName"
|
||||
$vaultName = "VaultName"
|
||||
|
||||
Set-AzureRmKeyVaultAccessPolicy -VaultName $vaultName -ObjectId $spn.Id -PermissionsToSecrets delete,get,set -ResourceGroupName $resourceGroupName
|
||||
```
|
|
@ -1,14 +1,12 @@
|
|||
# Pre-consent
|
||||
Azure Active Directory utilizes a consent framework that is based on a user or an administrator giving consent to an application
|
||||
that asks to be registered in their directory, which may involve accessing directory data. This framework presents two primary
|
||||
Azure Active Directory utilizes a consent framework that is based on a user or an administrator giving consent to an application that asks to be registered in their directory, which may involve accessing directory data. This framework presents two primary
|
||||
problems for Cloud Solution Provider (CSP) partners
|
||||
|
||||
1. Getting all customers to consent to an application can prove to be difficult task.
|
||||
1. Getting all customers to consent to an application can prove to be a difficult task.
|
||||
2. There might be a need to perform an operation against a newly provisioned tenant before access has been granted to the customer.
|
||||
Which means the customer will not be able to consent to the application.
|
||||
|
||||
In order to overcome these issues CSP partners can configure an for pre-consent. This configuration takes advantage of the
|
||||
delegated administrative permissions that are granted to CSP partner over a customer associated with their reseller. Perform
|
||||
In order to overcome these issues, CSP partners can configure an for pre-consent. This configuration takes advantage of the delegated administrative permissions that are granted to CSP partner over a customer associated with their reseller. Perform
|
||||
the following steps to configure the application that will be used to access the Partner Center API for pre-consent
|
||||
|
||||
1. Install Azure AD PowerShell Module (instruction available [here](https://docs.microsoft.com/en-us/powershell/azuread/)).
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<AssemblyName>Microsoft.Store.PartnerCenter.Bot.Models</AssemblyName>
|
||||
<RootNamespace>Microsoft.Store.PartnerCenter.Bot.Models</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -1,17 +1,14 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="HealthEvent.cs" company="Microsoft">
|
||||
// <copyright file="OfficeHealthEvent.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Logic.Office
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Models
|
||||
{
|
||||
using System;
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a health event obtained from Office 365 Service Communications API.
|
||||
/// </summary>
|
||||
public class HealthEvent
|
||||
public class OfficeHealthEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{DD1B3FF6-0FAC-41F6-843C-183676F55AD4}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.Store.PartnerCenter.Bot.Services</RootNamespace>
|
||||
<AssemblyName>Microsoft.Store.PartnerCenter.Bot.Services</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.19.2.6005, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.2\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.19.2.6005, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.2\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Rest.ClientRuntime.2.3.11\lib\net452\Microsoft.Rest.ClientRuntime.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="IServiceCommuncations.cs" />
|
||||
<Compile Include="ODataResponse.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ServiceCommunications.cs" />
|
||||
<Compile Include="ServiceCredentials.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Bot.Models\Bot.Models.csproj">
|
||||
<Project>{72cf9064-499f-456d-b879-e1335b2bd6ca}</Project>
|
||||
<Name>Bot.Models</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -0,0 +1,30 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="IServiceCommunications.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Services
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Rest;
|
||||
using Models;
|
||||
|
||||
public interface IServiceCommuncations
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the credentials used when accessing resources.
|
||||
/// </summary>
|
||||
ServiceClientCredentials Credentials { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the address of the resource being accessed.
|
||||
/// </summary>
|
||||
Uri Endpoint { get; }
|
||||
|
||||
Task<List<OfficeHealthEvent>> GetHealthEventsAsync(string customerId, CancellationToken cancellationToken = default(CancellationToken));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ODataResponse.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Services
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
internal class ODataResponse<T> where T: class
|
||||
{
|
||||
public List<T> Value { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Bot.Services")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Bot.Services")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("dd1b3ff6-0fac-41f6-843c-183676f55ad4")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,75 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ServiceCommunications.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Services
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Models;
|
||||
using Newtonsoft.Json;
|
||||
using Rest;
|
||||
|
||||
public class ServiceCommunications : ServiceClient<ServiceCommunications>, IServiceCommuncations
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServiceCommunications" /> class.
|
||||
/// </summary>
|
||||
/// <param name="credentials">Credentials used when accessing resources.</param>
|
||||
/// <param name="handlers">List of handlers from top to bottom (outer handler is the first in the list)</param>
|
||||
public ServiceCommunications(ServiceClientCredentials credentials, params DelegatingHandler[] handlers) : base(handlers)
|
||||
{
|
||||
Credentials = credentials;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServiceCommunications" /> class.
|
||||
/// </summary>
|
||||
/// <param name="endpoint">Address of the resource being accessed.</param>
|
||||
/// <param name="credentials">Credentials used when accessing resources.</param>
|
||||
/// <param name="handlers">List of handlers from top to bottom (outer handler is the first in the list)</param>
|
||||
public ServiceCommunications(Uri endpoint, ServiceClientCredentials credentials, params DelegatingHandler[] handlers) : base(handlers)
|
||||
{
|
||||
Credentials = credentials;
|
||||
Endpoint = endpoint;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the credentials used when accessing resources.
|
||||
/// </summary>
|
||||
public ServiceClientCredentials Credentials { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the address of the resource being accessed.
|
||||
/// </summary>
|
||||
public Uri Endpoint { get; private set; }
|
||||
|
||||
public async Task<List<OfficeHealthEvent>> GetHealthEventsAsync(string customerId, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
HttpResponseMessage response = null;
|
||||
string content;
|
||||
|
||||
try
|
||||
{
|
||||
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(Endpoint, $"/api/v1.0/{customerId}/ServiceComms/CurrentStatus")))
|
||||
{
|
||||
await Credentials.ProcessHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
response = await HttpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);
|
||||
content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
|
||||
return JsonConvert.DeserializeObject<ODataResponse<OfficeHealthEvent>>(content).Value;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
response = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ServiceCredentials.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Services
|
||||
{
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using IdentityModel.Clients.ActiveDirectory;
|
||||
using Rest;
|
||||
|
||||
public sealed class ServiceCredentials : ServiceClientCredentials
|
||||
{
|
||||
/// <summary>
|
||||
/// The authentication scheme utilized by the request.
|
||||
/// </summary>
|
||||
private const string AuthenticationScheme = "Bearer";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServiceCredentials" /> class.
|
||||
/// </summary>
|
||||
/// <param name="clientId">
|
||||
/// The client identifer to be used when requesting an access token.
|
||||
/// </param>
|
||||
/// <param name="clientSecret">
|
||||
/// The client secret to be used when requesting an access token.
|
||||
/// </param>
|
||||
/// <param name="resource">
|
||||
/// Identifier of the target resource that is the recipient of the requested token.
|
||||
/// </param>
|
||||
/// <param name="tenantId">
|
||||
/// The tenant identifier to be used when requesting an access token.
|
||||
/// </param>
|
||||
public ServiceCredentials(string clientId, string clientSecret, string resource, string tenantId)
|
||||
{
|
||||
ClientId = clientId;
|
||||
ClientSecret = clientSecret;
|
||||
Resource = resource;
|
||||
TenantId = tenantId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the client identifier.
|
||||
/// </summary>
|
||||
public string ClientId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the client secret.
|
||||
/// </summary>
|
||||
public string ClientSecret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the identity of the target resource that is the recipient of the requested token.
|
||||
/// </summary>
|
||||
public string Resource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the tenant identifier.
|
||||
/// </summary>
|
||||
public string TenantId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Applies the credentials to the HTTP request.
|
||||
/// </summary>
|
||||
/// <param name="request">
|
||||
/// The HTTP request message
|
||||
/// </param>
|
||||
/// <param name="cancellationToken">
|
||||
/// The cancellation token to monitor.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An instance of the <see cref="Task"/> class that represents the asynchronous operation.
|
||||
/// </returns>
|
||||
public override async Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
AuthenticationContext authContext;
|
||||
AuthenticationResult authResult;
|
||||
|
||||
try
|
||||
{
|
||||
authContext = new AuthenticationContext($"https://login.microsoftonline.com/{TenantId}");
|
||||
|
||||
authResult = await authContext.AcquireTokenAsync(
|
||||
Resource,
|
||||
new ClientCredential(
|
||||
ClientId,
|
||||
ClientSecret)).ConfigureAwait(false);
|
||||
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue(AuthenticationScheme, authResult.AccessToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
authContext = null;
|
||||
authResult = null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetTokenAsync()
|
||||
{
|
||||
AuthenticationContext authContext;
|
||||
AuthenticationResult authResult;
|
||||
|
||||
try
|
||||
{
|
||||
authContext = new AuthenticationContext($"https://login.microsoftonline.com/{TenantId}");
|
||||
|
||||
authResult = await authContext.AcquireTokenAsync(
|
||||
Resource,
|
||||
new ClientCredential(
|
||||
ClientId,
|
||||
ClientSecret)).ConfigureAwait(false);
|
||||
|
||||
return authResult.AccessToken;
|
||||
}
|
||||
finally
|
||||
{
|
||||
authContext = null;
|
||||
authResult = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.2" targetFramework="net461" />
|
||||
<package id="Microsoft.Rest.ClientRuntime" version="2.3.11" targetFramework="net461" />
|
||||
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" />
|
||||
</packages>
|
|
@ -1,5 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\Text.Analyzers.2.6.0\build\Text.Analyzers.props" Condition="Exists('..\..\packages\Text.Analyzers.2.6.0\build\Text.Analyzers.props')" />
|
||||
<Import Project="..\..\packages\Microsoft.NetFramework.Analyzers.2.6.0\build\Microsoft.NetFramework.Analyzers.props" Condition="Exists('..\..\packages\Microsoft.NetFramework.Analyzers.2.6.0\build\Microsoft.NetFramework.Analyzers.props')" />
|
||||
<Import Project="..\..\packages\Microsoft.NetCore.Analyzers.2.6.0\build\Microsoft.NetCore.Analyzers.props" Condition="Exists('..\..\packages\Microsoft.NetCore.Analyzers.2.6.0\build\Microsoft.NetCore.Analyzers.props')" />
|
||||
<Import Project="..\..\packages\Microsoft.CodeQuality.Analyzers.2.6.0\build\Microsoft.CodeQuality.Analyzers.props" Condition="Exists('..\..\packages\Microsoft.CodeQuality.Analyzers.2.6.0\build\Microsoft.CodeQuality.Analyzers.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
|
@ -161,8 +165,8 @@
|
|||
<Reference Include="Microsoft.Store.PartnerCenter.Models, Version=1.7.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Store.PartnerCenter.1.7.1\lib\Net45\Microsoft.Store.PartnerCenter.Models.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.WindowsAzure.Storage, Version=9.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\WindowsAzure.Storage.9.1.0\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
|
||||
<Reference Include="Microsoft.WindowsAzure.Storage, Version=9.1.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\WindowsAzure.Storage.9.1.1\lib\net45\Microsoft.WindowsAzure.Storage.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
|
@ -223,10 +227,6 @@
|
|||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Content\Images\azure-logo.png" />
|
||||
<Content Include="Content\Images\dynamics-logo.png" />
|
||||
<Content Include="Content\Images\microsoft-logo.png" />
|
||||
<Content Include="Content\Images\office-logo.png" />
|
||||
<Content Include="default.htm" />
|
||||
<Content Include="Global.asax" />
|
||||
<Content Include="Web.config">
|
||||
|
@ -246,7 +246,6 @@
|
|||
<Compile Include="Providers\ConfigurationProvider.cs" />
|
||||
<Compile Include="Providers\IConfigurationProvider.cs" />
|
||||
<Compile Include="Controllers\BaseApiController.cs" />
|
||||
<Compile Include="Controllers\ImageController.cs" />
|
||||
<Compile Include="Controllers\MessagesController.cs" />
|
||||
<Compile Include="Controllers\OAuthCallbackController.cs" />
|
||||
<Compile Include="Dialogs\ActionDialog.cs" />
|
||||
|
@ -268,12 +267,7 @@
|
|||
<Compile Include="Intents\SelectCustomerIntent.cs" />
|
||||
<Compile Include="Intents\SelectSubscriptionIntent.cs" />
|
||||
<Compile Include="Logic\AiExceptionLogger.cs" />
|
||||
<Compile Include="Logic\CommunicationException.cs" />
|
||||
<Compile Include="Logic\IPartnerOperations.cs" />
|
||||
<Compile Include="Logic\Office\HealthEvent.cs" />
|
||||
<Compile Include="Logic\Office\IServiceCommunications.cs" />
|
||||
<Compile Include="Logic\Office\ODataResponse.cs" />
|
||||
<Compile Include="Logic\Office\ServiceCommunications.cs" />
|
||||
<Compile Include="Logic\OperationContext.cs" />
|
||||
<Compile Include="Logic\PartnerOperations.cs" />
|
||||
<Compile Include="Models\ApplicationCredential.cs" />
|
||||
|
@ -286,7 +280,7 @@
|
|||
<Compile Include="Providers\KeyVaultProvider.cs" />
|
||||
<Compile Include="Providers\RedisCacheprovider.cs" />
|
||||
<Compile Include="Security\AuthenticationProvider.cs" />
|
||||
<Compile Include="Security\CustomBotAuthentication.cs" />
|
||||
<Compile Include="Security\CustomBotAuthenticationAttribute.cs" />
|
||||
<Compile Include="Security\CustomerPrincipal.cs" />
|
||||
<Compile Include="Security\Permissions.cs" />
|
||||
<Compile Include="Security\UserRoles.cs" />
|
||||
|
@ -326,7 +320,16 @@
|
|||
<ItemGroup>
|
||||
<WCFMetadata Include="Connected Services\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Analyzer Include="..\..\packages\Microsoft.CodeQuality.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.CodeQuality.Analyzers.dll" />
|
||||
<Analyzer Include="..\..\packages\Microsoft.CodeQuality.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.CodeQuality.CSharp.Analyzers.dll" />
|
||||
<Analyzer Include="..\..\packages\Microsoft.NetCore.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.NetCore.Analyzers.dll" />
|
||||
<Analyzer Include="..\..\packages\Microsoft.NetCore.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.NetCore.CSharp.Analyzers.dll" />
|
||||
<Analyzer Include="..\..\packages\Microsoft.NetFramework.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.NetFramework.Analyzers.dll" />
|
||||
<Analyzer Include="..\..\packages\Microsoft.NetFramework.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.NetFramework.CSharp.Analyzers.dll" />
|
||||
<Analyzer Include="..\..\packages\Text.Analyzers.2.6.0\analyzers\dotnet\cs\Text.Analyzers.dll" />
|
||||
<Analyzer Include="..\..\packages\Text.Analyzers.2.6.0\analyzers\dotnet\cs\Text.CSharp.Analyzers.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources.es.resx" />
|
||||
<EmbeddedResource Include="Resources.fr.resx" />
|
||||
|
@ -336,6 +339,16 @@
|
|||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Bot.Models\Bot.Models.csproj">
|
||||
<Project>{72cf9064-499f-456d-b879-e1335b2bd6ca}</Project>
|
||||
<Name>Bot.Models</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Bot.Services\Bot.Services.csproj">
|
||||
<Project>{dd1b3ff6-0fac-41f6-843c-183676f55ad4}</Project>
|
||||
<Name>Bot.Services</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
@ -372,6 +385,10 @@
|
|||
<Error Condition="!Exists('..\..\packages\Microsoft.Azure.Services.AppAuthentication.1.1.0-preview\build\Microsoft.Azure.Services.AppAuthentication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Azure.Services.AppAuthentication.1.1.0-preview\build\Microsoft.Azure.Services.AppAuthentication.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.21.1\build\Microsoft.Azure.DocumentDB.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Azure.DocumentDB.1.21.1\build\Microsoft.Azure.DocumentDB.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.2.1\build\Microsoft.ApplicationInsights.SnapshotCollector.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.2.1\build\Microsoft.ApplicationInsights.SnapshotCollector.targets'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.CodeQuality.Analyzers.2.6.0\build\Microsoft.CodeQuality.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.CodeQuality.Analyzers.2.6.0\build\Microsoft.CodeQuality.Analyzers.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.NetCore.Analyzers.2.6.0\build\Microsoft.NetCore.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.NetCore.Analyzers.2.6.0\build\Microsoft.NetCore.Analyzers.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.NetFramework.Analyzers.2.6.0\build\Microsoft.NetFramework.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.NetFramework.Analyzers.2.6.0\build\Microsoft.NetFramework.Analyzers.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\Text.Analyzers.2.6.0\build\Text.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Text.Analyzers.2.6.0\build\Text.Analyzers.props'))" />
|
||||
</Target>
|
||||
<Import Project="..\..\packages\Microsoft.Azure.DocumentDB.1.21.1\build\Microsoft.Azure.DocumentDB.targets" Condition="Exists('..\..\packages\Microsoft.Azure.DocumentDB.1.21.1\build\Microsoft.Azure.DocumentDB.targets')" />
|
||||
<Import Project="..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.2.1\build\Microsoft.ApplicationInsights.SnapshotCollector.targets" Condition="Exists('..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.2.1\build\Microsoft.ApplicationInsights.SnapshotCollector.targets')" />
|
||||
|
|
Двоичные данные
src/Bot/Content/Images/azure-logo.png
Двоичные данные
src/Bot/Content/Images/azure-logo.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 3.2 KiB |
Двоичные данные
src/Bot/Content/Images/dynamics-logo.png
Двоичные данные
src/Bot/Content/Images/dynamics-logo.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 5.1 KiB |
Двоичные данные
src/Bot/Content/Images/microsoft-logo.png
Двоичные данные
src/Bot/Content/Images/microsoft-logo.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 3.3 KiB |
Двоичные данные
src/Bot/Content/Images/office-logo.png
Двоичные данные
src/Bot/Content/Images/office-logo.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 4.1 KiB |
|
@ -1,78 +0,0 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ImageController.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Controllers
|
||||
{
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Web.Http;
|
||||
using Logic;
|
||||
using Providers;
|
||||
|
||||
/// <summary>
|
||||
/// Provides the ability to dynamically generate images.
|
||||
/// </summary>
|
||||
[RoutePrefix("api/images")]
|
||||
public class ImageController : BaseApiController
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ImageController"/> class.
|
||||
/// </summary>
|
||||
/// <param name="provider">Provides access to core services.</param>
|
||||
public ImageController(IBotProvider provider) : base(provider)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dynamically generates an image.
|
||||
/// </summary>
|
||||
/// <param name="value">A <see cref="string>"/> that will be used to generate the image.</param>
|
||||
/// <returns>A dynamically generated image.</returns>
|
||||
[HttpGet]
|
||||
[Route("dynamic")]
|
||||
public HttpResponseMessage GetImage(string value)
|
||||
{
|
||||
HttpResponseMessage response;
|
||||
|
||||
using (Bitmap bmp = new Bitmap(65, 65, PixelFormat.Format32bppArgb))
|
||||
{
|
||||
bmp.MakeTransparent();
|
||||
|
||||
using (Brush brush = new SolidBrush(Color.FromArgb(255, 0, 127, 255)))
|
||||
{
|
||||
using (Graphics graphic = Graphics.FromImage(bmp))
|
||||
{
|
||||
graphic.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
graphic.FillEllipse(brush, 0, 0, 24, 24);
|
||||
|
||||
graphic.DrawString(value.Substring(0, 1).ToUpper(), new Font("Calibri (Body)", 16, FontStyle.Bold), Brushes.White, 0, 0);
|
||||
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
bmp.Save(stream, ImageFormat.Png);
|
||||
stream.Position = 0;
|
||||
|
||||
response = new HttpResponseMessage(HttpStatusCode.OK)
|
||||
{
|
||||
Content = new ByteArrayContent(stream.ToArray())
|
||||
};
|
||||
|
||||
response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
|
||||
response.Content.Headers.ContentLength = stream.Length;
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -67,13 +67,13 @@ namespace Microsoft.Store.PartnerCenter.Bot.Controllers
|
|||
Provider.Configuration.MicrosoftAppId,
|
||||
Provider.Configuration.MicrosoftAppPassword.ToUnsecureString()));
|
||||
|
||||
await client.Conversations.ReplyToActivityAsync(activity.CreateReply(Resources.Welcome));
|
||||
await client.Conversations.ReplyToActivityAsync(activity.CreateReply(Resources.Welcome)).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (activity.Type == ActivityTypes.Message)
|
||||
{
|
||||
await Conversation.SendAsync(activity, () => new ActionDialog(Provider));
|
||||
await Conversation.SendAsync(activity, () => new ActionDialog(Provider)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// Capture the request for the customer summary for analysis.
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Controllers
|
|||
using (ILifetimeScope scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
|
||||
{
|
||||
botData = scope.Resolve<IBotData>();
|
||||
await botData.LoadAsync(cancellationToken);
|
||||
await botData.LoadAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!Validate(botData, stateData))
|
||||
{
|
||||
|
@ -103,12 +103,14 @@ namespace Microsoft.Store.PartnerCenter.Bot.Controllers
|
|||
new InvalidOperationException(Resources.InvalidAuthenticationException));
|
||||
}
|
||||
|
||||
principal = await GetCustomerPrincipalAsync(code);
|
||||
principal = await GetCustomerPrincipalAsync(
|
||||
new Uri($"{Request.RequestUri.Scheme}://{Request.RequestUri.Host}:{Request.RequestUri.Port}/{BotConstants.CallbackPath}"),
|
||||
code).ConfigureAwait(false);
|
||||
|
||||
if (principal == null)
|
||||
{
|
||||
message.Text = Resources.NoRelationshipException;
|
||||
await Conversation.ResumeAsync(conversationReference, message, cancellationToken);
|
||||
await Conversation.ResumeAsync(conversationReference, message, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return Request.CreateErrorResponse(
|
||||
HttpStatusCode.BadRequest,
|
||||
|
@ -117,8 +119,8 @@ namespace Microsoft.Store.PartnerCenter.Bot.Controllers
|
|||
|
||||
botData.PrivateConversationData.SetValue(BotConstants.CustomerPrincipalKey, principal);
|
||||
|
||||
await botData.FlushAsync(cancellationToken);
|
||||
await Conversation.ResumeAsync(conversationReference, message, cancellationToken);
|
||||
await botData.FlushAsync(cancellationToken).ConfigureAwait(false);
|
||||
await Conversation.ResumeAsync(conversationReference, message, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// Capture the request for the customer summary for analysis.
|
||||
eventProperties = new Dictionary<string, string>
|
||||
|
@ -164,41 +166,38 @@ namespace Microsoft.Store.PartnerCenter.Bot.Controllers
|
|||
/// <summary>
|
||||
/// Obtain an instance of <see cref="CustomerPrincipal"/> that represents the authenticated user.
|
||||
/// </summary>
|
||||
/// <param name="redirectUri">Address to return to upon receiving a response from the authority.</param>
|
||||
/// <param name="code">The authorization code that was requested.</param>
|
||||
/// <returns>An instance of <see cref="CustomerPrincipal"/> that represents the authenticated user.</returns>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// <paramref name="code"/> is empty or null.
|
||||
/// </exception>
|
||||
private async Task<CustomerPrincipal> GetCustomerPrincipalAsync(string code)
|
||||
private async Task<CustomerPrincipal> GetCustomerPrincipalAsync(Uri redirectUri, string code)
|
||||
{
|
||||
AuthenticationResult authResult;
|
||||
CustomerPrincipal principal;
|
||||
IGraphClient client;
|
||||
List<RoleModel> roles;
|
||||
Uri redirectUri;
|
||||
|
||||
code.AssertNotEmpty(nameof(code));
|
||||
|
||||
try
|
||||
{
|
||||
redirectUri =
|
||||
new Uri($"{HttpContext.Current.Request.Url.Scheme}://{HttpContext.Current.Request.Url.Host}:{HttpContext.Current.Request.Url.Port}/{BotConstants.CallbackPath}");
|
||||
|
||||
authResult = await Provider.AccessToken.AcquireTokenByAuthorizationCodeAsync(
|
||||
$"{Provider.Configuration.ActiveDirectoryEndpoint}/{BotConstants.AuthorityEndpoint}",
|
||||
code,
|
||||
new ApplicationCredential
|
||||
{
|
||||
ApplicationId = Provider.Configuration.ApplicationId,
|
||||
ApplicationSecret = Provider.Configuration.ApplicationSecret,
|
||||
ApplicationId = Provider.Configuration.ApplicationId,
|
||||
ApplicationSecret = Provider.Configuration.ApplicationSecret,
|
||||
UseCache = true
|
||||
},
|
||||
redirectUri,
|
||||
Provider.Configuration.GraphEndpoint);
|
||||
Provider.Configuration.GraphEndpoint).ConfigureAwait(false);
|
||||
|
||||
client = new GraphClient(Provider, authResult.TenantId);
|
||||
|
||||
roles = await client.GetDirectoryRolesAsync(authResult.UserInfo.UniqueId);
|
||||
roles = await client.GetDirectoryRolesAsync(authResult.UserInfo.UniqueId).ConfigureAwait(false);
|
||||
|
||||
principal = new CustomerPrincipal
|
||||
{
|
||||
|
@ -219,7 +218,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Controllers
|
|||
authResult.TenantId,
|
||||
StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
await Provider.PartnerOperations.GetCustomerAsync(principal, authResult.TenantId);
|
||||
await Provider.PartnerOperations.GetCustomerAsync(principal, authResult.TenantId).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return principal;
|
||||
|
@ -236,6 +235,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Controllers
|
|||
finally
|
||||
{
|
||||
authResult = null;
|
||||
client = null;
|
||||
roles = null;
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Controllers
|
|||
/// or
|
||||
/// <paramref name="stateData"/> is null.
|
||||
/// </exception>
|
||||
private bool Validate(IBotData botData, IDictionary<string, string> stateData)
|
||||
private static bool Validate(IBotData botData, IDictionary<string, string> stateData)
|
||||
{
|
||||
string uniqueId;
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Dialogs
|
|||
{
|
||||
message = context.MakeMessage();
|
||||
|
||||
principal = await context.GetCustomerPrincipalAsync(provider);
|
||||
principal = await context.GetCustomerPrincipalAsync(provider).ConfigureAwait(false);
|
||||
|
||||
if (principal == null)
|
||||
{
|
||||
|
@ -81,7 +81,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Dialogs
|
|||
message.Text = builder.ToString();
|
||||
}
|
||||
|
||||
await context.PostAsync(message);
|
||||
await context.PostAsync(message).ConfigureAwait(false);
|
||||
context.Wait(MessageReceived);
|
||||
}
|
||||
finally
|
||||
|
@ -113,22 +113,22 @@ namespace Microsoft.Store.PartnerCenter.Bot.Dialogs
|
|||
{
|
||||
key = result.TopScoringIntent.Intent.ToCamelCase();
|
||||
|
||||
principal = await context.GetCustomerPrincipalAsync(provider);
|
||||
principal = await context.GetCustomerPrincipalAsync(provider).ConfigureAwait(false);
|
||||
|
||||
if (principal == null)
|
||||
{
|
||||
await HelpAsync(context);
|
||||
await HelpAsync(context).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (principal.AvailableIntents.ContainsKey(key))
|
||||
{
|
||||
await principal.AvailableIntents[key]
|
||||
.ExecuteAsync(context, message, result, provider);
|
||||
.ExecuteAsync(context, message, result, provider).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await HelpAsync(context);
|
||||
await HelpAsync(context).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
@ -157,15 +157,15 @@ namespace Microsoft.Store.PartnerCenter.Bot.Dialogs
|
|||
new AuthDialog(provider, message),
|
||||
ResumeAfterAuth,
|
||||
message,
|
||||
CancellationToken.None);
|
||||
CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
else if (message.Text.Equals(Resources.Help, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
await HelpAsync(context);
|
||||
await HelpAsync(context).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await base.MessageReceived(context, item);
|
||||
await base.MessageReceived(context, item).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
@ -191,9 +191,9 @@ namespace Microsoft.Store.PartnerCenter.Bot.Dialogs
|
|||
result.AssertNotNull(nameof(result));
|
||||
|
||||
string message = await result;
|
||||
await context.PostAsync(message);
|
||||
await context.PostAsync(message).ConfigureAwait(false);
|
||||
|
||||
await HelpAsync(context);
|
||||
await HelpAsync(context).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -64,7 +64,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Dialogs
|
|||
public async Task StartAsync(IDialogContext context)
|
||||
{
|
||||
context.AssertNotNull(nameof(context));
|
||||
await AuthenticateAsync(context);
|
||||
await AuthenticateAsync(context).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -123,14 +123,14 @@ namespace Microsoft.Store.PartnerCenter.Bot.Dialogs
|
|||
provider.Configuration.GraphEndpoint,
|
||||
provider.Configuration.ApplicationId,
|
||||
redirectUri,
|
||||
state);
|
||||
state).ConfigureAwait(false);
|
||||
|
||||
message = context.MakeMessage();
|
||||
|
||||
message.Attachments.Add(SigninCard.Create(
|
||||
Resources.SigninCardText, Resources.LoginCaptial, authUrl).ToAttachment());
|
||||
|
||||
await context.PostAsync(message);
|
||||
await context.PostAsync(message).ConfigureAwait(false);
|
||||
context.Wait(MessageReceivedAsync);
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Dialogs
|
|||
|
||||
if (!string.IsNullOrEmpty(message?.Text))
|
||||
{
|
||||
result = await QnAService.QueryServiceAsync(message.Text);
|
||||
result = await QnAService.QueryServiceAsync(message.Text).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
message = context.MakeMessage();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Extensions
|
||||
{
|
||||
using Logic.Office;
|
||||
using Models;
|
||||
using Microsoft.Bot.Connector;
|
||||
|
||||
public static class HealthEventExtensions
|
||||
|
@ -16,7 +16,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Extensions
|
|||
/// </summary>
|
||||
/// <param name="healthEvent">An instance of <see cref="HealthEvent"/> to be transformed.</param>
|
||||
/// <returns>An instance of <see cref="Attachment"/> that represents the health event.</returns>
|
||||
public static Attachment ToAttachment(this HealthEvent healthEvent)
|
||||
public static Attachment ToAttachment(this OfficeHealthEvent healthEvent)
|
||||
{
|
||||
HeroCard card = new HeroCard
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
namespace Microsoft.Store.PartnerCenter.Bot.Extensions
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Web;
|
||||
using System.Globalization;
|
||||
using Microsoft.Bot.Connector;
|
||||
using PartnerCenter.Models.Subscriptions;
|
||||
|
||||
|
@ -20,21 +20,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Extensions
|
|||
/// <returns>An instance <see cref="Attachment"/> that represents the subscription.</returns>
|
||||
public static Attachment ToAttachment(this Subscription subscription)
|
||||
{
|
||||
string imageUrl;
|
||||
string offerName = subscription.OfferName.ToLower();
|
||||
|
||||
if (offerName.Contains("azure") || offerName.Contains("active directory"))
|
||||
{
|
||||
imageUrl = $"{HttpContext.Current.Request.Url.Scheme}://{HttpContext.Current.Request.Url.Host}:{HttpContext.Current.Request.Url.Port}/content/images/azure-logo.png";
|
||||
}
|
||||
else if (offerName.Contains("office") || offerName.Contains("365"))
|
||||
{
|
||||
imageUrl = $"{HttpContext.Current.Request.Url.Scheme}://{HttpContext.Current.Request.Url.Host}:{HttpContext.Current.Request.Url.Port}/content/images/office-logo.png";
|
||||
}
|
||||
else
|
||||
{
|
||||
imageUrl = $"{HttpContext.Current.Request.Url.Scheme}://{HttpContext.Current.Request.Url.Host}:{HttpContext.Current.Request.Url.Port}/content/images/microsoft-logo.png";
|
||||
}
|
||||
string offerName = subscription.OfferName.ToLower(CultureInfo.CurrentCulture);
|
||||
|
||||
HeroCard card = new HeroCard
|
||||
{
|
||||
|
@ -47,13 +33,6 @@ namespace Microsoft.Store.PartnerCenter.Bot.Extensions
|
|||
Value = $"select subscription {subscription.Id}"
|
||||
}
|
||||
},
|
||||
Images = new List<CardImage>
|
||||
{
|
||||
new CardImage
|
||||
{
|
||||
Url = imageUrl
|
||||
}
|
||||
},
|
||||
Subtitle = subscription.Id,
|
||||
Title = subscription.FriendlyName
|
||||
};
|
||||
|
|
|
@ -10,14 +10,13 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Extensions;
|
||||
using Microsoft.Bot.Builder.Dialogs;
|
||||
using Microsoft.Bot.Builder.Luis.Models;
|
||||
using Microsoft.Bot.Connector;
|
||||
using PartnerCenter.Models.Customers;
|
||||
using Security;
|
||||
using Providers;
|
||||
using Security;
|
||||
|
||||
/// <summary>
|
||||
/// Processes the request to list customers.
|
||||
|
@ -76,9 +75,9 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
|
||||
principal = await context.GetCustomerPrincipalAsync(provider);
|
||||
principal = await context.GetCustomerPrincipalAsync(provider).ConfigureAwait(false);
|
||||
|
||||
customers = await provider.PartnerOperations.GetCustomersAsync(principal);
|
||||
customers = await provider.PartnerOperations.GetCustomersAsync(principal).ConfigureAwait(false);
|
||||
|
||||
response = context.MakeMessage();
|
||||
response.AttachmentLayout = AttachmentLayoutTypes.Carousel;
|
||||
|
@ -94,18 +93,11 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
Value = $"select customer {c.Id}"
|
||||
}
|
||||
},
|
||||
Images = new List<CardImage>
|
||||
{
|
||||
new CardImage
|
||||
{
|
||||
Url = $"{HttpContext.Current.Request.Url.Scheme}://{HttpContext.Current.Request.Url.Host}:{HttpContext.Current.Request.Url.Port}/api/images/dynamic?value={HttpUtility.UrlEncode(c.CompanyProfile.CompanyName)}"
|
||||
}
|
||||
},
|
||||
Subtitle = c.CompanyProfile.Domain,
|
||||
Title = c.CompanyProfile.CompanyName
|
||||
}).ToAttachment()).ToList();
|
||||
|
||||
await context.PostAsync(response);
|
||||
await context.PostAsync(response).ConfigureAwait(false);
|
||||
|
||||
// Capture the request for the customer summary for analysis.
|
||||
eventProperties = new Dictionary<string, string>
|
||||
|
|
|
@ -76,24 +76,24 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
|
||||
principal = await context.GetCustomerPrincipalAsync(provider);
|
||||
principal = await context.GetCustomerPrincipalAsync(provider).ConfigureAwait(false);
|
||||
|
||||
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterAccountId))
|
||||
{
|
||||
customer = await provider.PartnerOperations.GetCustomerAsync(principal);
|
||||
customer = await provider.PartnerOperations.GetCustomerAsync(principal).ConfigureAwait(false);
|
||||
|
||||
response = context.MakeMessage();
|
||||
response.Text = string.Format(Resources.SubscriptionRequestMessage, customer.CompanyProfile.CompanyName);
|
||||
await context.PostAsync(response);
|
||||
await context.PostAsync(response).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
subscriptions = await provider.PartnerOperations.GetSubscriptionsAsync(principal);
|
||||
subscriptions = await provider.PartnerOperations.GetSubscriptionsAsync(principal).ConfigureAwait(false);
|
||||
|
||||
response = context.MakeMessage();
|
||||
response.AttachmentLayout = AttachmentLayoutTypes.Carousel;
|
||||
response.Attachments = subscriptions.Select(s => s.ToAttachment()).ToList();
|
||||
|
||||
await context.PostAsync(response);
|
||||
await context.PostAsync(response).ConfigureAwait(false);
|
||||
|
||||
// Track the event measurements for analysis.
|
||||
eventMetrics = new Dictionary<string, double>
|
||||
|
|
|
@ -12,10 +12,10 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
using System.Threading.Tasks;
|
||||
using Extensions;
|
||||
using IdentityModel.Clients.ActiveDirectory;
|
||||
using Logic.Office;
|
||||
using Microsoft.Bot.Builder.Dialogs;
|
||||
using Microsoft.Bot.Builder.Luis.Models;
|
||||
using Microsoft.Bot.Connector;
|
||||
using Services;
|
||||
using Models;
|
||||
using Providers;
|
||||
using Security;
|
||||
|
@ -60,13 +60,13 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
/// </exception>
|
||||
public async Task ExecuteAsync(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result, IBotProvider provider)
|
||||
{
|
||||
AuthenticationResult authResult;
|
||||
CustomerPrincipal principal;
|
||||
DateTime startTime;
|
||||
Dictionary<string, double> eventMetrics;
|
||||
Dictionary<string, string> eventProperties;
|
||||
IMessageActivity response;
|
||||
List<HealthEvent> healthEvents;
|
||||
List<OfficeHealthEvent> healthEvents;
|
||||
ServiceCommunications serviceComm;
|
||||
string authority;
|
||||
string customerId;
|
||||
|
||||
|
@ -79,7 +79,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
|
||||
principal = await context.GetCustomerPrincipalAsync(provider);
|
||||
principal = await context.GetCustomerPrincipalAsync(provider).ConfigureAwait(false);
|
||||
|
||||
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterAccountId, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
|
@ -94,25 +94,21 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
customerId = principal.CustomerId;
|
||||
}
|
||||
|
||||
authResult = await provider.AccessToken.GetAccessTokenAsync(
|
||||
$"{provider.Configuration.ActiveDirectoryEndpoint}/{principal.Operation.CustomerId}",
|
||||
provider.Configuration.OfficeManagementEndpoint,
|
||||
new ApplicationCredential
|
||||
{
|
||||
ApplicationId = provider.Configuration.ApplicationId,
|
||||
ApplicationSecret = provider.Configuration.ApplicationSecret,
|
||||
UseCache = true
|
||||
});
|
||||
serviceComm = new ServiceCommunications(
|
||||
new Uri(provider.Configuration.OfficeManagementEndpoint),
|
||||
new ServiceCredentials(
|
||||
provider.Configuration.ApplicationId,
|
||||
provider.Configuration.ApplicationSecret.ToUnsecureString(),
|
||||
provider.Configuration.OfficeManagementEndpoint,
|
||||
principal.Operation.CustomerId));
|
||||
|
||||
healthEvents = await provider.ServiceCommunications.GetCurrentStatusAsync(
|
||||
customerId,
|
||||
authResult.AccessToken);
|
||||
healthEvents = await serviceComm.GetHealthEventsAsync(principal.Operation.CustomerId).ConfigureAwait(false);
|
||||
|
||||
response = context.MakeMessage();
|
||||
response.AttachmentLayout = AttachmentLayoutTypes.Carousel;
|
||||
response.Attachments = healthEvents.Select(e => e.ToAttachment()).ToList();
|
||||
|
||||
await context.PostAsync(response);
|
||||
await context.PostAsync(response).ConfigureAwait(false);
|
||||
|
||||
// Track the event measurements for analysis.
|
||||
eventMetrics = new Dictionary<string, double>
|
||||
|
@ -139,7 +135,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
|
||||
provider.Telemetry.TrackException(ex);
|
||||
|
||||
await context.PostAsync(response);
|
||||
await context.PostAsync(response).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -147,6 +143,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
eventProperties = null;
|
||||
principal = null;
|
||||
response = null;
|
||||
serviceComm = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
new QuestionDialog(provider),
|
||||
ResumeAfterQnA,
|
||||
messageActivity,
|
||||
CancellationToken.None);
|
||||
CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -92,7 +92,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
try
|
||||
{
|
||||
messageActivity = await result;
|
||||
await context.PostAsync(messageActivity);
|
||||
await context.PostAsync(messageActivity).ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -77,7 +77,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
startTime = DateTime.Now;
|
||||
response = context.MakeMessage();
|
||||
|
||||
principal = await context.GetCustomerPrincipalAsync(provider);
|
||||
principal = await context.GetCustomerPrincipalAsync(provider).ConfigureAwait(false);
|
||||
|
||||
if (result.TryFindEntity("identifier", out indentifierEntity))
|
||||
{
|
||||
|
@ -93,11 +93,11 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
}
|
||||
else
|
||||
{
|
||||
customer = await provider.PartnerOperations.GetCustomerAsync(principal, customerId);
|
||||
customer = await provider.PartnerOperations.GetCustomerAsync(principal, customerId).ConfigureAwait(false);
|
||||
response.Text = $"{Resources.CustomerContext} {customer.CompanyProfile.CompanyName}";
|
||||
}
|
||||
|
||||
await context.PostAsync(response);
|
||||
await context.PostAsync(response).ConfigureAwait(false);
|
||||
|
||||
// Capture the request for the customer summary for analysis.
|
||||
eventProperties = new Dictionary<string, string>
|
||||
|
|
|
@ -77,14 +77,14 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
startTime = DateTime.Now;
|
||||
response = context.MakeMessage();
|
||||
|
||||
principal = await context.GetCustomerPrincipalAsync(provider);
|
||||
principal = await context.GetCustomerPrincipalAsync(provider).ConfigureAwait(false);
|
||||
|
||||
if (result.TryFindEntity("identifier", out indentifierEntity))
|
||||
{
|
||||
subscriptionId = indentifierEntity.Entity.Replace(" ", string.Empty);
|
||||
principal.Operation.SubscriptionId = subscriptionId;
|
||||
|
||||
subscription = await provider.PartnerOperations.GetSubscriptionAsync(principal);
|
||||
subscription = await provider.PartnerOperations.GetSubscriptionAsync(principal).ConfigureAwait(false);
|
||||
|
||||
if (subscription == null)
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Intents
|
|||
response.Text = $"{Resources.SubscriptionContext} {subscriptionId}";
|
||||
}
|
||||
|
||||
await context.PostAsync(response);
|
||||
await context.PostAsync(response).ConfigureAwait(false);
|
||||
|
||||
// Track the event measurements for analysis.
|
||||
eventMetrics = new Dictionary<string, double>
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="CommunicationException.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
||||
{
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// User defined exception type that is thrown when an error is encountered communication with the Partner Center API.
|
||||
/// </summary>
|
||||
/// <seealso cref="Exception" />
|
||||
/// <seealso cref="ISerializable" />
|
||||
[Serializable]
|
||||
public class CommunicationException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CommunicationException"/> class.
|
||||
/// </summary>
|
||||
public CommunicationException()
|
||||
{
|
||||
HttpStatusCode = HttpStatusCode.InternalServerError;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CommunicationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
public CommunicationException(string message) : base(message)
|
||||
{
|
||||
HttpStatusCode = HttpStatusCode.BadRequest;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CommunicationException" /> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The message that describes the error.</param>
|
||||
/// <param name="httpStatusCode">The HTTP status code that was encountered with the error.</param>
|
||||
public CommunicationException(string message, HttpStatusCode httpStatusCode) : base(message)
|
||||
{
|
||||
HttpStatusCode = httpStatusCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CommunicationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
|
||||
public CommunicationException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CommunicationException" /> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
|
||||
/// <param name="httpStatusCode">The HTTP status code that was encountered with the error.</param>
|
||||
public CommunicationException(string message, Exception innerException, HttpStatusCode httpStatusCode)
|
||||
: base(message, innerException)
|
||||
{
|
||||
HttpStatusCode = httpStatusCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CommunicationException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> that holds the serialized object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" /> that contains contextual information about the source or destination.</param>
|
||||
protected CommunicationException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP status code associated with the exception.
|
||||
/// </summary>
|
||||
public HttpStatusCode HttpStatusCode { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// When overridden in a derived class, sets the <see cref="T:System.Runtime.Serialization.SerializationInfo" /> with information about the exception.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> that holds the serialized object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" /> that contains contextual information about the source or destination.</param>
|
||||
/// <PermissionSet>
|
||||
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Read="*AllFiles*" PathDiscovery="*AllFiles*" />
|
||||
/// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter" />
|
||||
/// </PermissionSet>
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(info));
|
||||
}
|
||||
|
||||
info.AddValue("HttpStatusCode", (int)HttpStatusCode);
|
||||
|
||||
base.GetObjectData(info, context);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -102,7 +102,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
|
||||
directoryGroups = await client.Users[objectId].MemberOf.Request().GetAsync();
|
||||
directoryGroups = await client.Users[objectId].MemberOf.Request().GetAsync().ConfigureAwait(false);
|
||||
roles = new List<RoleModel>();
|
||||
|
||||
do
|
||||
|
@ -118,7 +118,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
}));
|
||||
}
|
||||
|
||||
if (customerId.Equals(provider.Configuration.PartnerCenterAccountId))
|
||||
if (customerId.Equals(provider.Configuration.PartnerCenterAccountId, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
groups = directoryGroups.CurrentPage.OfType<Group>().Where(
|
||||
g => g.DisplayName.Equals("AdminAgents") || g.DisplayName.Equals("HelpdeskAgents") || g.DisplayName.Equals("SalesAgent")).ToList();
|
||||
|
@ -137,7 +137,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
|
||||
if (morePages)
|
||||
{
|
||||
directoryGroups = await directoryGroups.NextPageRequest.GetAsync();
|
||||
directoryGroups = await directoryGroups.NextPageRequest.GetAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
while (morePages);
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="IServiceCommunications.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Logic.Office
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the ability to interact with Office 365 Service Communications API.
|
||||
/// </summary>
|
||||
public interface IServiceCommunications
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current status information for the specified customer.
|
||||
/// </summary>
|
||||
/// <param name="customerId">Identifier for the customer.</param>
|
||||
/// <param name="token">Access token to be utilized in the request.</param>
|
||||
/// <returns>A list of <see cref="HealthEvent"/> objects that represent the current health events for the specified customer.</returns>
|
||||
Task<List<HealthEvent>> GetCurrentStatusAsync(string customerId, string token);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ODataResponse.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Logic.Office
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a response from an OData endpoint.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type returned from the API.</typeparam>
|
||||
internal class ODataResponse<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the value returned from the API.
|
||||
/// </summary>
|
||||
public List<T> Value { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ServiceCommunications.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
namespace Microsoft.Store.PartnerCenter.Bot.Logic.Office
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using Extensions;
|
||||
using Newtonsoft.Json;
|
||||
using Providers;
|
||||
|
||||
/// <summary>
|
||||
/// Provides the ability to interact with Office 365 Service Communications API.
|
||||
/// </summary>
|
||||
public class ServiceCommunications : IServiceCommunications
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to core services.
|
||||
/// </summary>
|
||||
private readonly IBotProvider provider;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServiceCommunications" /> class.
|
||||
/// </summary>
|
||||
/// <param name="provider">Provides access to core services.</param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="provider"/> is null.
|
||||
/// </exception>
|
||||
public ServiceCommunications(IBotProvider provider)
|
||||
{
|
||||
provider.AssertNotNull(nameof(provider));
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current status information for the specified customer.
|
||||
/// </summary>
|
||||
/// <param name="customerId">Identifier for the customer.</param>
|
||||
/// <param name="token">Access token to be utilized in the request.</param>
|
||||
/// <returns>A list of <see cref="HealthEvent"/> objects that represent the current health events for the specified customer.</returns>
|
||||
public async Task<List<HealthEvent>> GetCurrentStatusAsync(string customerId, string token)
|
||||
{
|
||||
DateTime startTime;
|
||||
Dictionary<string, double> eventMetrics;
|
||||
Dictionary<string, string> eventProperties;
|
||||
HttpResponseMessage response;
|
||||
ODataResponse<HealthEvent> odataResponse;
|
||||
string content;
|
||||
string requestUri;
|
||||
|
||||
try
|
||||
{
|
||||
startTime = DateTime.Now;
|
||||
|
||||
using (HttpClient client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
|
||||
requestUri = $"{provider.Configuration.OfficeManagementEndpoint}/api/v1.0/{customerId}/ServiceComms/CurrentStatus";
|
||||
|
||||
response = await client.GetAsync(requestUri);
|
||||
content = await response.Content.ReadAsStringAsync();
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new CommunicationException(content, response.StatusCode);
|
||||
}
|
||||
|
||||
odataResponse = JsonConvert.DeserializeObject<ODataResponse<HealthEvent>>(content);
|
||||
|
||||
// Track the event measurements for analysis.
|
||||
eventMetrics = new Dictionary<string, double>
|
||||
{
|
||||
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds },
|
||||
{ "NumberOfHealthEvents", odataResponse.Value.Count }
|
||||
};
|
||||
|
||||
// Capture the request for the customer summary for analysis.
|
||||
eventProperties = new Dictionary<string, string>
|
||||
{
|
||||
{ "CustomerId", customerId },
|
||||
{ "RequestUri", requestUri }
|
||||
};
|
||||
|
||||
provider.Telemetry.TrackEvent("GetCurrentStatusAsync", eventProperties, eventMetrics);
|
||||
|
||||
return odataResponse.Value;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
eventMetrics = null;
|
||||
eventProperties = null;
|
||||
response = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -92,7 +92,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
correlationId = Guid.NewGuid();
|
||||
operations = await GetAppOperationsAsync(correlationId);
|
||||
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
|
||||
rules = await operations.CountryValidationRules.ByCountry(countryCode).GetAsync().ConfigureAwait(false);
|
||||
|
||||
|
@ -159,7 +159,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
correlationId = Guid.NewGuid();
|
||||
operations = await GetAppOperationsAsync(correlationId);
|
||||
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
|
||||
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterAccountId))
|
||||
{
|
||||
|
@ -223,7 +223,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
correlationId = Guid.NewGuid();
|
||||
operations = await GetAppOperationsAsync(correlationId);
|
||||
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
|
||||
customers = new List<Customer>();
|
||||
|
||||
|
@ -299,7 +299,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
|
||||
startTime = DateTime.Now;
|
||||
correlationId = Guid.NewGuid();
|
||||
operations = await GetAppOperationsAsync(correlationId);
|
||||
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
|
||||
profile = await operations.Profiles.LegalBusinessProfile.GetAsync().ConfigureAwait(false);
|
||||
|
||||
|
@ -357,7 +357,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
correlationId = Guid.NewGuid();
|
||||
operations = await GetAppOperationsAsync(correlationId);
|
||||
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -421,16 +421,17 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
correlationId = Guid.NewGuid();
|
||||
operations = await GetAppOperationsAsync(correlationId);
|
||||
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
|
||||
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterAccountId))
|
||||
{
|
||||
principal.AssertValidCustomerContext(Resources.InvalidCustomerContextException);
|
||||
subscriptions = await operations.Customers.ById(principal.Operation.CustomerId).Subscriptions.GetAsync();
|
||||
subscriptions = await operations.Customers
|
||||
.ById(principal.Operation.CustomerId).Subscriptions.GetAsync().ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
subscriptions = await operations.Customers.ById(principal.CustomerId).Subscriptions.GetAsync();
|
||||
subscriptions = await operations.Customers.ById(principal.CustomerId).Subscriptions.GetAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// Track the event measurements for analysis.
|
||||
|
@ -514,7 +515,8 @@ namespace Microsoft.Store.PartnerCenter.Bot.Logic
|
|||
provider.Configuration.PartnerCenterApplicationSecret.ToUnsecureString(),
|
||||
provider.Configuration.PartnerCenterAccountId).ConfigureAwait(false);
|
||||
|
||||
await provider.Cache.StoreAsync(CacheDatabaseType.Authentication, PartnerCenterCacheKey, credentials).ConfigureAwait(false);
|
||||
await provider.Cache
|
||||
.StoreAsync(CacheDatabaseType.Authentication, PartnerCenterCacheKey, credentials).ConfigureAwait(false);
|
||||
|
||||
return credentials;
|
||||
}
|
||||
|
|
|
@ -235,7 +235,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
clientId,
|
||||
redirectUri,
|
||||
UserIdentifier.AnyUser,
|
||||
extraQueryParameters);
|
||||
extraQueryParameters).ConfigureAwait(false);
|
||||
|
||||
return authUri.ToString();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
using System.Threading.Tasks;
|
||||
using Intents;
|
||||
using Logic;
|
||||
using Logic.Office;
|
||||
using Telemetry;
|
||||
|
||||
/// <summary>
|
||||
|
@ -54,12 +53,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
/// Provides the ability to perform various partner operations.
|
||||
/// </summary>
|
||||
private static IPartnerOperations partnerOperations;
|
||||
|
||||
/// <summary>
|
||||
/// Provides the ability to communicate with the Office 365 Service Communications API.
|
||||
/// </summary>
|
||||
private static IServiceCommunications serviceCommunications;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Provides the ability to track telemetry data.
|
||||
/// </summary>
|
||||
|
@ -105,11 +99,6 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
/// </summary>
|
||||
public IPartnerOperations PartnerOperations => partnerOperations ?? (partnerOperations = new PartnerOperations(this));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ability to communicate with the Office 365 Service Communications API.
|
||||
/// </summary>
|
||||
public IServiceCommunications ServiceCommunications => serviceCommunications ?? (serviceCommunications = new ServiceCommunications(this));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the telemetry service reference.
|
||||
/// </summary>
|
||||
|
@ -152,7 +141,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
intent.Initialize();
|
||||
|
||||
await Configuration.InitializeAsync().ConfigureAwait(false);
|
||||
await localization.InitializeAsync().ConfigureAwait(false);
|
||||
await localization.InitializeAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
using System.Threading.Tasks;
|
||||
using Intents;
|
||||
using Logic;
|
||||
using Logic.Office;
|
||||
using Services;
|
||||
using Telemetry;
|
||||
|
||||
/// <summary>
|
||||
|
@ -52,11 +52,6 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
/// </summary>
|
||||
IPartnerOperations PartnerOperations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a reference t the service communications service.
|
||||
/// </summary>
|
||||
IServiceCommunications ServiceCommunications { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the telemetry service reference.
|
||||
/// </summary>
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
|
||||
public async Task ClearAsync(CacheDatabaseType database)
|
||||
{
|
||||
await Task.FromResult(0);
|
||||
await Task.FromResult(0).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -65,8 +65,8 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
/// </exception>
|
||||
public async Task DeleteAsync(CacheDatabaseType database, string key = null)
|
||||
{
|
||||
IDatabase cache = await GetCacheReferenceAsync(database);
|
||||
await cache.KeyDeleteAsync(key);
|
||||
IDatabase cache = await GetCacheReferenceAsync(database).ConfigureAwait(false);
|
||||
await cache.KeyDeleteAsync(key).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -107,8 +107,8 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
{
|
||||
key.AssertNotEmpty(nameof(key));
|
||||
|
||||
IDatabase cache = await GetCacheReferenceAsync(database);
|
||||
RedisValue value = await cache.StringGetAsync(key);
|
||||
IDatabase cache = await GetCacheReferenceAsync(database).ConfigureAwait(false);
|
||||
RedisValue value = await cache.StringGetAsync(key).ConfigureAwait(false);
|
||||
|
||||
return value.HasValue ? DecompressEntity<TEntity>(value) : null;
|
||||
}
|
||||
|
@ -134,10 +134,10 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
key.AssertNotEmpty(nameof(key));
|
||||
entity.AssertNotNull(nameof(entity));
|
||||
|
||||
IDatabase cache = await GetCacheReferenceAsync(database);
|
||||
IDatabase cache = await GetCacheReferenceAsync(database).ConfigureAwait(false);
|
||||
|
||||
await cache.StringSetAsync(
|
||||
key, CompressEntity(entity), expiration);
|
||||
key, CompressEntity(entity), expiration).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -287,7 +287,7 @@ namespace Microsoft.Store.PartnerCenter.Bot.Providers
|
|||
if (connection == null)
|
||||
{
|
||||
connection = await ConnectionMultiplexer.ConnectAsync(
|
||||
provider.Configuration.RedisCacheConnectionString.ToUnsecureString());
|
||||
provider.Configuration.RedisCacheConnectionString.ToUnsecureString()).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return connection.GetDatabase((int)database);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="CustomBotAuthentication.cs" company="Microsoft">
|
||||
// <copyright file="CustomBotAuthenticationAttribute.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
@ -14,13 +14,13 @@ namespace Microsoft.Store.PartnerCenter.Bot.Security
|
|||
using Extensions;
|
||||
using Microsoft.Bot.Connector;
|
||||
using Providers;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Provides custom authentication for the bot itself.
|
||||
/// </summary>
|
||||
/// <seealso cref="BotAuthentication" />
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class CustomBotAuthentication : BotAuthentication
|
||||
public sealed class CustomBotAuthenticationAttribute : BotAuthentication
|
||||
{
|
||||
/// <summary>
|
||||
/// Occurs before the action method is invoked.
|
|
@ -44,9 +44,217 @@
|
|||
</system.web>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Linq.Parallel" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Timer" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Encoding.Extensions" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Encoding" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Globalization" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.RegularExpressions" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Collections" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.InteropServices.RuntimeInformation" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Primitives" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Reflection" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Sockets" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Linq.Queryable" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Xml.ReaderWriter" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Diagnostics.Debug" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Resources.ResourceManager" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.SecureString" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.InteropServices" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Overlapped" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.IO.Compression" publicKeyToken="B77A5C561934E089" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Diagnostics.Contracts" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.Extensions" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.Numerics" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ComponentModel.EventBasedAsync" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Collections.Concurrent" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Diagnostics.Tracing" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Dynamic.Runtime" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Reflection.Primitives" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Security.Principal" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ComponentModel" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Linq" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Reflection.Extensions" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Diagnostics.StackTrace" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Xml.XmlSerializer" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Globalization.Extensions" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.NetworkInformation" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Xml.XDocument" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.Serialization.Json" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ObjectModel" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Xml.XPath.XDocument" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Linq.Expressions" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Parallel" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.Serialization.Primitives" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.ValueTuple" publicKeyToken="CC7B13FFCD2DDD51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Diagnostics.Tools" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Requests" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.11.0" newVersion="4.0.11.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Data.Common" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.Serialization.Xml" publicKeyToken="B03F5F7F11D50A3A" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.3.0" newVersion="4.1.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.1.1.2" newVersion="4.1.1.2" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
@ -114,7 +322,7 @@
|
|||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.WindowsAzure.Storage" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.1.0.0" newVersion="9.1.0.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-9.1.1.0" newVersion="9.1.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Bot.Builder.History" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
@ -162,4 +370,4 @@
|
|||
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
|
||||
</providers>
|
||||
</entityFramework>
|
||||
</configuration>
|
||||
</configuration>
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
<package id="Microsoft.Bot.Builder.CognitiveServices" version="1.1.2" targetFramework="net461" />
|
||||
<package id="Microsoft.Bot.Builder.History" version="3.14.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.Bot.Connector" version="3.14.1.1" targetFramework="net461" />
|
||||
<package id="Microsoft.CodeAnalysis.FxCopAnalyzers" version="2.6.0" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="Microsoft.CodeQuality.Analyzers" version="2.6.0" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="Microsoft.Graph" version="1.8.1" targetFramework="net461" />
|
||||
<package id="Microsoft.Graph.Core" version="1.8.1" targetFramework="net461" />
|
||||
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.2" targetFramework="net461" />
|
||||
|
@ -35,6 +37,8 @@
|
|||
<package id="Microsoft.IdentityModel.Protocols" version="5.2.1" targetFramework="net461" />
|
||||
<package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.2.1" targetFramework="net461" />
|
||||
<package id="Microsoft.IdentityModel.Tokens" version="5.2.1" targetFramework="net461" />
|
||||
<package id="Microsoft.NetCore.Analyzers" version="2.6.0" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="Microsoft.NetFramework.Analyzers" version="2.6.0" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="Microsoft.Rest.ClientRuntime" version="2.3.11" targetFramework="net461" />
|
||||
<package id="Microsoft.Rest.ClientRuntime.Azure" version="3.3.12" targetFramework="net461" />
|
||||
<package id="Microsoft.Store.PartnerCenter" version="1.7.1" targetFramework="net461" />
|
||||
|
@ -47,5 +51,6 @@
|
|||
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
|
||||
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
|
||||
<package id="System.Security.Cryptography.X509Certificates" version="4.3.2" targetFramework="net461" />
|
||||
<package id="WindowsAzure.Storage" version="9.1.0" targetFramework="net461" />
|
||||
<package id="Text.Analyzers" version="2.6.0" targetFramework="net461" developmentDependency="true" />
|
||||
<package id="WindowsAzure.Storage" version="9.1.1" targetFramework="net461" />
|
||||
</packages>
|
Загрузка…
Ссылка в новой задаче