Skip to content

Commit 6db59c2

Browse files
authored
Merge branch 'master' into CustomAnalyticsWorking
2 parents f9a6920 + 7ba20e6 commit 6db59c2

48 files changed

Lines changed: 3381 additions & 1 deletion

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
</PropertyGroup>
6+
7+
</Project>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft": "Warning",
6+
"Microsoft.Hosting.Lifetime": "Information"
7+
}
8+
}
9+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft": "Warning",
6+
"Microsoft.Hosting.Lifetime": "Information"
7+
}
8+
},
9+
"AllowedHosts": "*"
10+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Contoso Sample Web Chat</title>
5+
<!-- This styling is for the canvas demonstration purposes. It is recommended
6+
that style is moved to separate file for organization in larger projects -->
7+
<style>
8+
html, body {
9+
height: 100%;
10+
}
11+
12+
body {
13+
margin: 0;
14+
}
15+
16+
h1 {
17+
font-size: 16px;
18+
font-family: Segoe UI;
19+
line-height: 20px;
20+
color: whitesmoke;
21+
display: table-cell;
22+
padding: 13px 0px 0px 20px;
23+
}
24+
25+
.heading {
26+
background-color: grey;
27+
height: 50px;
28+
}
29+
30+
.main {
31+
margin: 18px;
32+
border-radius: 4px;
33+
}
34+
35+
div[role="form"] {
36+
background-color: mediumpurple;
37+
}
38+
39+
#webchat {
40+
position: fixed;
41+
height: calc(100% - 50px);
42+
width: 100%;
43+
top: 50px;
44+
overflow: hidden;
45+
}
46+
47+
</style>
48+
</head>
49+
<body>
50+
<div>
51+
<div class="heading">
52+
53+
<!-- Change the h1 text to change the bot name -->
54+
<h1>Matt Bot</h1>
55+
56+
</div>
57+
<div id="webchat" role="main"></div>
58+
</div>
59+
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
60+
<script>
61+
const styleOptions = {
62+
// Add styleOptions to customize web chat canvas
63+
hideUploadButton: true,
64+
sendBoxButtonColor: 'red',
65+
botAvatarImage: 'https://maxcdn.icons8.com/Share/icon/ios7/Industry/bot1600.png'
66+
};
67+
68+
const styleSet = window.WebChat.createStyleSet({
69+
bubbleBackground: 'rgba(0, 0, 255, .1)',
70+
bubbleFromUserBackground: 'rgba(0, 255, 0, .1)'
71+
});
72+
73+
styleSet.textContent = Object.assign(
74+
{},
75+
styleSet.textContent,
76+
{
77+
fontFamily: '\'Comic Sans MS\', \'Arial\', sans-serif',
78+
fontWeight: 'bold'
79+
}
80+
);
81+
82+
// Add your BOT ID below
83+
var BOT_ID = "097b7cbb-0604-459c-8e42-de03daa68596";
84+
85+
var theURL = "https://powerva.microsoft.com/api/botmanagement/v1/directline/directlinetoken?botId=" + BOT_ID;
86+
87+
//Set this variable to the encrypted token string. In real use, the token will need to extracted from the users store/cookie
88+
var theToken = "ABC123";
89+
90+
const store = window.WebChat.createStore(
91+
{},
92+
// This code sends the encryted token to PVA. Set the varToken value to the encryted Token the user holds.
93+
({ dispatch }) => next => action => {
94+
if (action.type === "DIRECT_LINE/CONNECT_FULFILLED") {
95+
dispatch({
96+
type: 'WEB_CHAT/SEND_EVENT',
97+
payload: {
98+
name: 'pvaSetContext',
99+
value: {
100+
"tokenValue": "" + theToken + ""
101+
}
102+
}
103+
});
104+
}
105+
return next(action);
106+
}
107+
);
108+
fetch(theURL)
109+
.then(response => response.json())
110+
.then(conversationInfo => {
111+
window.WebChat.renderWebChat(
112+
{
113+
directLine: window.WebChat.createDirectLine({
114+
token: conversationInfo.token,
115+
}),
116+
store: store,
117+
styleOptions: styleOptions
118+
},
119+
document.getElementById('webchat')
120+
);
121+
})
122+
.catch(err => console.error("An error occurred: " + err));
123+
</script>
124+
<style>
125+
126+
</style>
127+
</body>
128+
</html>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Security.Claims;
7+
using System.Threading.Tasks;
8+
using Microsoft.Bot.Connector.Authentication;
9+
using Microsoft.Extensions.Configuration;
10+
11+
namespace DecryptSkillBot.Authentication
12+
{
13+
/// <summary>
14+
/// Sample claims validator that loads an allowed list from configuration if present
15+
/// and checks that requests are coming from allowed parent bots.
16+
/// </summary>
17+
public class AllowedCallersClaimsValidator : ClaimsValidator
18+
{
19+
private const string ConfigKey = "AllowedCallers";
20+
private readonly List<string> _allowedCallers;
21+
22+
public AllowedCallersClaimsValidator(IConfiguration config)
23+
{
24+
if (config == null)
25+
{
26+
throw new ArgumentNullException(nameof(config));
27+
}
28+
29+
// AllowedCallers is the setting in the appsettings.json file
30+
// that consists of the list of parent bot IDs that are allowed to access the skill.
31+
// To add a new parent bot, simply edit the AllowedCallers and add
32+
// the parent bot's Microsoft app ID to the list.
33+
// In this sample, we allow all callers if AllowedCallers contains an "*".
34+
var section = config.GetSection(ConfigKey);
35+
var appsList = section.Get<string[]>();
36+
if (appsList == null)
37+
{
38+
throw new ArgumentNullException($"\"{ConfigKey}\" not found in configuration.");
39+
}
40+
41+
_allowedCallers = new List<string>(appsList);
42+
}
43+
44+
public override Task ValidateClaimsAsync(IList<Claim> claims)
45+
{
46+
// If _allowedCallers contains an "*", we allow all callers.
47+
if (SkillValidation.IsSkillClaim(claims) && !_allowedCallers.Contains("*"))
48+
{
49+
// Check that the appId claim in the skill request is in the list of callers configured for this bot.
50+
var appId = JwtTokenValidation.GetAppIdFromClaims(claims);
51+
if (!_allowedCallers.Contains(appId))
52+
{
53+
throw new UnauthorizedAccessException($"Received a request from a bot with an app ID of \"{appId}\". To enable requests from this caller, add the app ID to your configuration file.");
54+
}
55+
}
56+
57+
return Task.CompletedTask;
58+
}
59+
}
60+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Microsoft.Bot.Builder;
7+
using Microsoft.Bot.Schema;
8+
using Newtonsoft.Json;
9+
10+
namespace DecryptSkillBot.Bots
11+
{
12+
public class DecryptBot : ActivityHandler
13+
{
14+
15+
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
16+
{
17+
18+
// Initial message - you can remove this, it's to show the skill is running
19+
var messageText = "Looking up your details...";
20+
await turnContext.SendActivityAsync(MessageFactory.Text(messageText, messageText, InputHints.ExpectingInput), cancellationToken);
21+
22+
// Load token from input
23+
var activity = turnContext.Activity;
24+
var tokenEncrypted = new TokenEncrypted();
25+
if (activity.Value != null)
26+
{
27+
tokenEncrypted = JsonConvert.DeserializeObject<TokenEncrypted>(JsonConvert.SerializeObject(activity.Value));
28+
}
29+
30+
// this is the variable for the object you return back to PVA
31+
var userId = new UserId();
32+
33+
if (tokenEncrypted.token != null)
34+
{
35+
// Decrypyt your token value here
36+
// Call class to decrypt with your public key here
37+
// Set the UserId value based on the value decryption provides, remove the line below
38+
userId.Id = DecryptToken.GetUserID(tokenEncrypted);
39+
}
40+
41+
// The code below sets the resultValue and ends the conversation with the skill
42+
var endActivity = new Activity();
43+
endActivity.Type = ActivityTypes.EndOfConversation;
44+
endActivity.Value = userId;
45+
46+
endActivity.Code = EndOfConversationCodes.CompletedSuccessfully;
47+
await turnContext.SendActivityAsync(endActivity, cancellationToken);
48+
}
49+
50+
protected override Task OnEndOfConversationActivityAsync(ITurnContext<IEndOfConversationActivity> turnContext, CancellationToken cancellationToken)
51+
{
52+
// This will be called if the root bot is ending the conversation. Sending additional messages should be
53+
// avoided as the conversation may have been deleted.
54+
// Perform cleanup of resources if needed.
55+
return Task.CompletedTask;
56+
}
57+
}
58+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System.Threading.Tasks;
5+
using Microsoft.AspNetCore.Mvc;
6+
using Microsoft.Bot.Builder;
7+
using Microsoft.Bot.Builder.Integration.AspNet.Core;
8+
using Microsoft.Extensions.Caching.Memory;
9+
using Microsoft.Extensions.Configuration;
10+
11+
namespace DecryptSkillBot.Controllers
12+
{
13+
// This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot
14+
// implementation at runtime. Multiple different IBot implementations running at different endpoints can be
15+
// achieved by specifying a more specific type for the bot constructor argument.
16+
[Route("api/messages")]
17+
[ApiController]
18+
public class BotController : ControllerBase
19+
{
20+
private readonly IBotFrameworkHttpAdapter _adapter;
21+
private readonly IBot _bot;
22+
private IConfiguration _config;
23+
private IMemoryCache _memoryCache;
24+
25+
public BotController(IBotFrameworkHttpAdapter adapter, IBot bot, IConfiguration config, IMemoryCache memoryCache)
26+
{
27+
_adapter = adapter;
28+
_bot = bot;
29+
_config = config;
30+
_memoryCache = memoryCache;
31+
}
32+
33+
[HttpPost]
34+
public async Task PostAsync()
35+
{
36+
await _adapter.ProcessAsync(Request, Response, _bot);
37+
}
38+
}
39+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
<LangVersion>latest</LangVersion>
6+
<AssemblyName>DecryptSkillBot</AssemblyName>
7+
<RootNamespace>DecryptSkillBot</RootNamespace>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.1" />
12+
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Version="4.10.3" />
13+
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<Content Update="appsettings.json">
18+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
19+
</Content>
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"groupLocation": {
6+
"value": ""
7+
},
8+
"groupName": {
9+
"value": ""
10+
},
11+
"appId": {
12+
"value": ""
13+
},
14+
"appSecret": {
15+
"value": ""
16+
},
17+
"botId": {
18+
"value": ""
19+
},
20+
"botSku": {
21+
"value": ""
22+
},
23+
"newAppServicePlanName": {
24+
"value": ""
25+
},
26+
"newAppServicePlanSku": {
27+
"value": {
28+
"name": "S1",
29+
"tier": "Standard",
30+
"size": "S1",
31+
"family": "S",
32+
"capacity": 1
33+
}
34+
},
35+
"newAppServicePlanLocation": {
36+
"value": ""
37+
},
38+
"newWebAppName": {
39+
"value": ""
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)