From fd5c2c325c435806f5c6dbbf6bb376f6f30d2912 Mon Sep 17 00:00:00 2001 From: Isaiah Williams Date: Sat, 13 May 2017 14:01:46 +0000 Subject: [PATCH] added O365 health information --- .editorconfig | 74 ++++ Partner-Center-Bot.sln | 5 +- README.md | 3 + azuredeploy.json | 409 ++++++++++++++++++ azuredeploy.parameters.json | 60 +++ src/Bot/ApplicationInsights.config | 15 +- src/Bot/Bot.csproj | 122 +++--- src/Bot/Configuration/Configuration.cs | 5 + src/Bot/Configuration/IConfiguration.cs | 5 + src/Bot/Controllers/MessagesController.cs | 20 +- .../Controllers/OAuthCallbackController.cs | 26 +- src/Bot/Dialogs/ActionDialog.cs | 23 +- src/Bot/Dialogs/AuthDialog.cs | 26 +- src/Bot/Dialogs/QuestionDialog.cs | 11 +- src/Bot/Global.asax.cs | 2 +- src/Bot/Intents/IntentConstants.cs | 5 + src/Bot/Intents/IntentService.cs | 6 +- src/Bot/Intents/ListSubscriptionsIntent.cs | 20 +- src/Bot/Intents/OfficeIssuesIntent.cs | 140 ++++++ src/Bot/Intents/QuestionIntent.cs | 4 +- src/Bot/Intents/SelectSubscriptionIntent.cs | 33 +- src/Bot/Logic/BotService.cs | 17 +- src/Bot/Logic/CommunicationException.cs | 105 +++++ src/Bot/Logic/Extensions.cs | 44 ++ src/Bot/Logic/GraphClient.cs | 10 +- src/Bot/Logic/IBotService.cs | 6 + src/Bot/Logic/IPartnerOperations.cs | 7 + src/Bot/Logic/Office/HealthEvent.cs | 41 ++ .../Logic/Office/IServiceCommunications.cs | 25 ++ src/Bot/Logic/Office/ODataResponse.cs | 22 + src/Bot/Logic/Office/ServiceCommunications.cs | 102 +++++ src/Bot/Logic/PartnerOperations.cs | 98 ++++- src/Bot/Properties/AssemblyInfo.cs | 2 +- src/Bot/Resources.Designer.cs | 47 +- src/Bot/Resources.de.resx | 65 +-- src/Bot/Resources.es.resx | 65 +-- src/Bot/Resources.fr.resx | 65 +-- src/Bot/Resources.ja.resx | 65 +-- src/Bot/Resources.resx | 17 +- src/Bot/Security/CustomBotAuthentication.cs | 4 +- src/Bot/Security/CustomerPrincipal.cs | 4 +- src/Bot/Security/MachineKeyDataProtector.cs | 4 +- src/Bot/Security/TokenManagement.cs | 54 +-- src/Bot/Security/UserRoles.cs | 5 + src/Bot/Settings.StyleCop | 22 - src/Bot/Web.config | 26 +- src/Bot/packages.config | 44 +- 47 files changed, 1649 insertions(+), 331 deletions(-) create mode 100644 .editorconfig create mode 100644 azuredeploy.json create mode 100644 azuredeploy.parameters.json create mode 100644 src/Bot/Intents/OfficeIssuesIntent.cs create mode 100644 src/Bot/Logic/CommunicationException.cs create mode 100644 src/Bot/Logic/Office/HealthEvent.cs create mode 100644 src/Bot/Logic/Office/IServiceCommunications.cs create mode 100644 src/Bot/Logic/Office/ODataResponse.cs create mode 100644 src/Bot/Logic/Office/ServiceCommunications.cs delete mode 100644 src/Bot/Settings.StyleCop diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..fcf8be3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,74 @@ +# EditorConfig is awesome:http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Don't use tabs for indentation. +[*] +indent_style = space +# (Please don't specify an indent_size here; that has too many unintended consequences.) + +# Code files +[*.{cs,csx,vb,vbx}] +indent_size = 4 + +# Xml project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# Xml config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + +# Dotnet code style settings: +[*.{cs,vb}] +# Sort using and Import directives with System.* appearing first +dotnet_sort_system_directives_first = true +# Avoid "this." and "Me." if not necessary +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion + +# Use language keywords instead of framework type names for type references +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# Suggest more modern language features when available +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion + +# CSharp code style settings: +[*.cs] +# Prefer "var" everywhere +csharp_style_var_for_built_in_types = false:suggestion +csharp_style_var_when_type_is_apparent = false:suggestion +csharp_style_var_elsewhere = false:suggestion + +# Prefer method-like constructs to have a block body +csharp_style_expression_bodied_methods = false:none +csharp_style_expression_bodied_constructors = false:none +csharp_style_expression_bodied_operators = false:none + +# Prefer property-like constructs to have an expression-body +csharp_style_expression_bodied_properties = true:none +csharp_style_expression_bodied_indexers = true:none +csharp_style_expression_bodied_accessors = true:none + +# Suggest more modern language features when available +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Newline settings +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true diff --git a/Partner-Center-Bot.sln b/Partner-Center-Bot.sln index 12524ec..6332424 100644 --- a/Partner-Center-Bot.sln +++ b/Partner-Center-Bot.sln @@ -1,10 +1,13 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26228.4 +VisualStudioVersion = 15.0.26430.6 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2C543791-022E-451C-BBB4-D756A459B91A}" ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + azuredeploy.json = azuredeploy.json + azuredeploy.parameters.json = azuredeploy.parameters.json CONTRIBUTING.md = CONTRIBUTING.md LICENSE = LICENSE Partner-Center-Bot.json = Partner-Center-Bot.json diff --git a/README.md b/README.md index fcae943..ecfab5c 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ This makes it where the user can get answers to commonly asked questions. ## Deployment Please review the [Deployment](docs/Deployment.md) guide for details on how to deploy this solution. +[![Deploy to Azure](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FMicrosoft%2FPartner-Center-Bot%2Fmaster%2Fazuredeploy.json) +[![Visualize](http://armviz.io/visualizebutton.png)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2FMicrosoft%2FPartner-Center-Bot%2Fmaster%2Fazuredeploy.json) + ## Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact diff --git a/azuredeploy.json b/azuredeploy.json new file mode 100644 index 0000000..f0395f9 --- /dev/null +++ b/azuredeploy.json @@ -0,0 +1,409 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appInsightsLocation": { + "type": "string", + "defaultValue": "South Central US", + "allowedValues": [ + "South Central US", + "West Europe", + "East US", + "North Europe" + ], + "metadata": { + "description": "Location for the instance of App Insights." + } + }, + "applicationId": { + "type": "string", + "minLength": 1 + }, + "applicationSecret": { + "type": "string", + "minLength": 1 + }, + "applicationTenantId": { + "type": "string", + "minLength": 1 + }, + "branch": { + "type": "string" + }, + "cacheSKUName": { + "type": "string", + "allowedValues": [ + "Basic", + "Standard" + ], + "defaultValue": "Basic", + "metadata": { + "description": "The pricing tier of the new Azure Redis Cache." + } + }, + "cacheSKUFamily": { + "type": "string", + "allowedValues": [ + "C" + ], + "defaultValue": "C", + "metadata": { + "description": "The family for the SKU." + } + }, + "cacheSKUCapacity": { + "type": "int", + "allowedValues": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "defaultValue": 0, + "metadata": { + "description": "The size of the new Azure Redis Cache instance." + } + }, + "hostingPlanName": { + "type": "string", + "minLength": 1 + }, + "keyVaultApplicationCertThumbprint": { + "type": "string", + "metadata": { + "description": "Thumbprint for the certificate used to access Key Vault" + }, + "minLength": 1 + }, + "keyVaultApplicationId": { + "type": "string", + "metadata": { + "description": "Identifier of the application used to access Key Vault" + }, + "minLength": 1 + }, + "keyVaultName": { + "type": "string", + "minLength": 1 + }, + "keyVaultSkuName": { + "type": "string", + "defaultValue": "Standard", + "allowedValues": [ + "Standard", + "Premium" + ], + "metadata": { + "description": "SKU for the vault" + } + }, + "keyVaultTenantId": { + "type": "string", + "minLength": 1 + }, + "luisAppId": { + "type": "string", + "minLength": 1 + }, + "luisApiKey": { + "type": "string", + "minLength": 1 + }, + "microsoftAppId": { + "type": "string", + "minLength": 1 + }, + "microsoftAppPassword": { + "type": "string", + "minLength": 1 + }, + "partnerCenterApplicationId": { + "type": "string", + "minLength": 1 + }, + "partnerCenterApplicationSecret": { + "type": "string", + "minLength": 1 + }, + "partnerCenterApplicationTenantId": { + "type": "string", + "minLength": 1 + }, + "qnAKnowledgebaseId": { + "type": "string", + "minLength": 1 + }, + "qnASubscriptionKey": { + "type": "string", + "minLength": 1 + }, + "repoUrl": { + "type": "string" + }, + "siteName": { + "type": "string", + "minLength": 1 + }, + "skuName": { + "type": "string", + "defaultValue": "B1", + "allowedValues": [ + "B1", + "B2", + "B3", + "S1", + "S2", + "S3", + "P1", + "P2", + "P3", + "P4" + ], + "metadata": { + "description": "Describes the plan's pricing tier and capacity. Check details at https://azure.microsoft.com/en-us/pricing/details/app-service/" + } + }, + "skuCapacity": { + "type": "int", + "defaultValue": 1, + "minValue": 1, + "metadata": { + "description": "Describes the plan's instance count" + } + }, + "storageAccountType": { + "type": "string", + "defaultValue": "Standard_LRS", + "allowedValues": [ + "Standard_LRS", + "Standard_GRS", + "Standard_ZRS", + "Premium_LRS" + ], + "metadata": { + "description": "Storage Account Type" + } + } + }, + "variables": { + "cacheName": "[concat('cache', uniqueString(resourceGroup().id))]", + "storageAccountName": "[concat('storage', uniqueString(resourceGroup().id))]" + }, + "resources": [ + { + "type": "Microsoft.KeyVault/vaults", + "name": "[parameters('keyVaultName')]", + "apiVersion": "2015-06-01", + "location": "[resourceGroup().location]", + "properties": { + "tenantId": "[parameters('keyVaultTenantId')]", + "accessPolicies": [], + "sku": { + "name": "[parameters('keyVaultSkuName')]", + "family": "A" + } + } + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "name": "[concat(parameters('keyVaultName'), '/', 'ApplicationSecret')]", + "apiVersion": "2015-06-01", + "properties": { + "contentType": "text/plain", + "value": "[parameters('applicationSecret')]" + }, + "dependsOn": [ + "[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]" + ] + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "name": "[concat(parameters('keyVaultName'), '/', 'LuisApiKey')]", + "apiVersion": "2015-06-01", + "properties": { + "contentType": "text/plain", + "value": "[parameters('luisApiKey')]" + }, + "dependsOn": [ + "[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]" + ] + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "name": "[concat(parameters('keyVaultName'), '/', 'MicrosoftAppPassword')]", + "apiVersion": "2015-06-01", + "properties": { + "contentType": "text/plain", + "value": "[parameters('microsoftAppPassword')]" + }, + "dependsOn": [ + "[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]" + ] + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "name": "[concat(parameters('keyVaultName'), '/', 'PartnerCenterApplicationSecret')]", + "apiVersion": "2015-06-01", + "properties": { + "contentType": "text/plain", + "value": "[parameters('partnerCenterApplicationSecret')]" + }, + "dependsOn": [ + "[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]" + ] + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "name": "[concat(parameters('keyVaultName'), '/', 'QnASubscriptionKey')]", + "apiVersion": "2015-06-01", + "properties": { + "contentType": "text/plain", + "value": "[parameters('qnASubscriptionKey')]" + }, + "dependsOn": [ + "[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]" + ] + }, + { + "type": "Microsoft.KeyVault/vaults/secrets", + "name": "[concat(parameters('keyVaultName'), '/', 'StorageConnectionString')]", + "apiVersion": "2015-06-01", + "properties": { + "contentType": "text/plain", + "value": "[Concat('DefaultEndpointsProtocol=https;AccountName=',variables('StorageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName')), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]" + }, + "dependsOn": [ + "[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]", + "[concat('Microsoft.Storage/storageAccounts/', variables('StorageAccountName'))]" + ] + }, + { + "name": "[variables('cacheName')]", + "type": "Microsoft.Cache/Redis", + "location": "[resourceGroup().location]", + "apiVersion": "2016-04-01", + "dependsOn": [], + "tags": { + "displayName": "cache" + }, + "properties": { + "sku": { + "name": "[parameters('cacheSKUName')]", + "family": "[parameters('cacheSKUFamily')]", + "capacity": "[parameters('cacheSKUCapacity')]" + } + } + }, + { + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('storageAccountName')]", + "apiVersion": "2016-01-01", + "location": "[resourceGroup().location]", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "kind": "Storage", + "properties": { + } + }, + { + "apiVersion": "2015-08-01", + "name": "[parameters('hostingPlanName')]", + "type": "Microsoft.Web/serverfarms", + "location": "[resourceGroup().location]", + "tags": { + "displayName": "HostingPlan" + }, + "sku": { + "name": "[parameters('skuName')]", + "capacity": "[parameters('skuCapacity')]" + }, + "properties": { + "name": "[parameters('hostingPlanName')]" + } + }, + { + "apiVersion": "2015-08-01", + "name": "[parameters('siteName')]", + "type": "Microsoft.Web/sites", + "location": "[resourceGroup().location]", + "tags": { + "[concat('hidden-related:', resourceGroup().id, '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]": "Resource", + "displayName": "Website" + }, + "dependsOn": [ + "[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]" + ], + "properties": { + "name": "[parameters('siteName')]", + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]" + }, + "resources": [ + { + "name": "web", + "type": "sourcecontrols", + "location": "[resourceGroup().location]", + "apiVersion": "2015-08-01", + "dependsOn": [ + "[concat('Microsoft.Web/sites/', parameters('siteName'))]", + "[concat('Microsoft.Web/Sites/', parameters('siteName'), '/config/appsettings')]" + ], + "tags": { + "displayName": "CustomerPortal" + }, + "properties": { + "RepoUrl": "[parameters('repoUrl')]", + "branch": "[parameters('branch')]", + "IsManualIntegration": true + } + }, + { + "name": "appsettings", + "type": "config", + "apiVersion": "2015-08-01", + "dependsOn": [ + "[concat('Microsoft.Web/sites/', parameters('siteName'))]", + "[concat('Microsoft.Insights/components/', parameters('siteName'))]", + "[concat('Microsoft.Cache/Redis/', variables('cacheName'))]" + ], + "tags": { + "displayName": "ApplicationSettings" + }, + "properties": { + "ApplicationId": "[parameters('applicationId')]", + "ApplicationTenantId": "[parameters('applicationTenantId')]", + "InstrumentationKey": "[reference(concat('Microsoft.Insights/components/', parameters('siteName'))).InstrumentationKey]", + "PartnerCenterApplicationId": "[parameters('partnerCenterApplicationId')]", + "PartnerCenterApplicationTenantId": "[parameters('partnerCenterApplicationTenantId')]", + "VaultApplicationCertThumbprint": "[parameters('keyVaultApplicationCertThumbprint')]", + "VaultApplicationId": "[parameters('keyVaultApplicationId')]", + "VaultApplicationTenantId": "[parameters('keyVaultTenantId')]", + "VaultBaseAddress": "[concat('https://', parameters('keyVaultName'), '.vault.azure.net')]" + } + } + ] + }, + { + "apiVersion": "2014-04-01", + "name": "[parameters('siteName')]", + "type": "Microsoft.Insights/components", + "location": "[parameters('appInsightsLocation')]", + "tags": { + "[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', parameters('siteName'))]": "Resource", + "displayName": "AppInsightsComponent" + }, + "properties": { + "applicationId": "[parameters('siteName')]" + } + } + ], + "outputs": { + "WebsiteUrl": { + "type": "string", + "value": "[concat('https://',reference(resourceId('Microsoft.Web/sites', parameters('siteName'))).hostNames[0])]" + } + } +} \ No newline at end of file diff --git a/azuredeploy.parameters.json b/azuredeploy.parameters.json new file mode 100644 index 0000000..ec3fa44 --- /dev/null +++ b/azuredeploy.parameters.json @@ -0,0 +1,60 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appInsightsLocation": { + "value": "South Central US" + }, + "applicationId": { + "value": "" + }, + "applicationSecret": { + "value": "" + }, + "applicationTenantId": { + "value": "" + }, + "branch": { + "value": "master" + }, + "hostingPlanName": { + "value": "" + }, + "keyVaultApplicationCertThumbprint": { + "value": "" + }, + "keyVaultApplicationId": { + "value": "" + }, + "keyVaultName": { + "value": "" + }, + "keyVaultSkuName": { + "value": "Standard" + }, + "keyVaultTenantId": { + "value": "" + }, + "partnerCenterApplicationId": { + "value": "" + }, + "partnerCenterApplicationSecret": { + "value": "" + }, + "partnerCenterApplicationTenantId": { + "value": "" + }, + "repoUrl": { + "value": "https://github.com/Microsoft/Partner-Center-Bot" + }, + "siteName": { + "value": "" + }, + "skuName": { + "value": "B1" + }, + "skuCapacity": { + "value": 1 + } + } +} \ No newline at end of file diff --git a/src/Bot/ApplicationInsights.config b/src/Bot/ApplicationInsights.config index 2e0a49a..b8dc1d3 100644 --- a/src/Bot/ApplicationInsights.config +++ b/src/Bot/ApplicationInsights.config @@ -20,7 +20,20 @@ - + + + + core.windows.net + core.chinacloudapi.cn + core.cloudapi.de + core.usgovcloudapi.net + + + + @@ -69,7 +71,7 @@ - + @@ -85,7 +87,7 @@ - + @@ -97,11 +99,27 @@ - + - + + + + + + + + + + + + + + + + + diff --git a/src/Bot/packages.config b/src/Bot/packages.config index da9b755..5d827e1 100644 --- a/src/Bot/packages.config +++ b/src/Bot/packages.config @@ -3,31 +3,35 @@ - + - - - - - + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - \ No newline at end of file