Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
2476626
add luis config into dialogsetting
VanyLaw Aug 19, 2019
5a904ce
merge master
VanyLaw Aug 20, 2019
1607da9
make oauth setting per bot
VanyLaw Aug 20, 2019
8d7f1f3
fix miss
VanyLaw Aug 20, 2019
5682bcd
Merge remote-tracking branch 'origin/master' into wenyluo/setting
VanyLaw Aug 21, 2019
e4e4c07
join luisStorage and oauthStorage into dialogSettingStorage
VanyLaw Aug 21, 2019
2b7c4b2
remove debounce
VanyLaw Aug 21, 2019
df185dd
handle merge master conflict
VanyLaw Aug 22, 2019
74d72df
persist setting in bot folder
VanyLaw Aug 23, 2019
482c3bc
persist
VanyLaw Aug 23, 2019
250ca57
merge master and fix conflict
VanyLaw Aug 23, 2019
fd2dcfe
when get project, response settings with project info
VanyLaw Aug 23, 2019
02f2709
get persist setting file from server
VanyLaw Aug 26, 2019
170febc
merge master handle conflict;
VanyLaw Aug 26, 2019
e8549f5
refactor luis setting
VanyLaw Aug 27, 2019
86e3c4f
Merge remote-tracking branch 'origin/master' into wenyluo/setting
VanyLaw Aug 27, 2019
2f5aa5b
Merge branch 'master' into wenyluo/setting
cwhitten Aug 27, 2019
a4ff78a
polish
VanyLaw Aug 28, 2019
c0c918e
Merge remote-tracking branch 'origin/master' into wenyluo/setting
VanyLaw Aug 28, 2019
b4a6260
Merge remote-tracking branch 'origin/master' into wenyluo/setting
VanyLaw Sep 2, 2019
bb5bcb0
change the format of persist file
VanyLaw Sep 2, 2019
5120122
Merge remote-tracking branch 'origin/master' into wenyluo/setting
VanyLaw Sep 2, 2019
bde7564
fix conflict
VanyLaw Sep 2, 2019
6c26d9f
add endpointKey and just send sensitive value to bot runtime
VanyLaw Sep 3, 2019
9c56ca7
Merge remote-tracking branch 'origin/master' into wenyluo/setting
VanyLaw Sep 3, 2019
7b7ee41
change sync data to runtime
VanyLaw Sep 3, 2019
3f8e196
add new config settings for bot runtime
Sep 4, 2019
3148f15
Merge remote-tracking branch 'origin/master' into wenyluo/setting
VanyLaw Sep 4, 2019
e6fcc39
add debounce
VanyLaw Sep 4, 2019
beb00a9
Merge remote-tracking branch 'origin/master' into wenyluo/setting
VanyLaw Sep 4, 2019
aa02f08
updaet luis deploy e2e test
VanyLaw Sep 5, 2019
d2b4089
fix conflict
VanyLaw Sep 5, 2019
2105645
fix lint
VanyLaw Sep 5, 2019
6c8a89f
change e2e test
VanyLaw Sep 5, 2019
9257f5b
remove annotation
VanyLaw Sep 5, 2019
8c9d4bb
Merge remote-tracking branch 'origin/master' into wenyluo/setting
VanyLaw Sep 5, 2019
3b5499a
Merge branch 'master' into wenyluo/setting
boydc2014 Sep 5, 2019
5d165a0
Merge branch 'master' into wenyluo/setting
boydc2014 Sep 5, 2019
898fd06
fix comments
VanyLaw Sep 5, 2019
4b98b8c
Merge branch 'wenyluo/setting' of https://github.com/microsoft/BotFra…
VanyLaw Sep 5, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 39 additions & 27 deletions BotProject/CSharp/BotManager.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.BotFramework;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Dialogs.Debugging;
using Microsoft.Bot.Builder.Dialogs.Declarative;
using Microsoft.Bot.Builder.Dialogs.Declarative.Resources;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Microsoft.Bot.Builder.BotFramework;
using Microsoft.Bot.Connector.Authentication;

namespace Microsoft.Bot.Builder.TestBot.Json
{
Expand All @@ -21,7 +22,7 @@ public interface IBotManager
IBotFrameworkHttpAdapter CurrentAdapter { get; }
IBot CurrentBot { get; }

void SetCurrent(Stream fileStream, LuConfigFile luConfig = null, string appId = null, string appPwd = null);
void SetCurrent(Stream fileStream, string endpointKey = null, string appPwd = null);
}

public class BotManager : IBotManager
Expand Down Expand Up @@ -84,7 +85,7 @@ public void SetCurrent(string botDir)
CurrentBot = new TestBot("Main.dialog", conversationState, userState, resourceExplorer, DebugSupport.SourceRegistry);
}

public void SetCurrent(Stream fileStream, LuConfigFile luConfig = null, string appId = null, string appPwd = null)
public void SetCurrent(Stream fileStream, string endpointKey = null, string appPwd = null)
{
lock (locker)
{
Expand All @@ -94,20 +95,41 @@ public void SetCurrent(Stream fileStream, LuConfigFile luConfig = null, string a
// extract to bot folder
var extractPath = ExtractFile(downloadPath, GenNewBotDir());

if (luConfig != null)
{
AddLuisConfig(extractPath, luConfig);
}
RetrieveSettingsFile(extractPath, endpointKey, appPwd);
SetCurrent(extractPath);
}
}

public void RetrieveSettingsFile(string extractPath, string endpointKey, string appPwd)
{
var settingsPaths = Directory.GetFiles(extractPath, "appsettings.json", SearchOption.AllDirectories);
if (settingsPaths.Length == 0)
{
return;
}


AddOAuthConfig(appId, appPwd);

var settingsPath = settingsPaths.FirstOrDefault();

SetCurrent(extractPath);
var settings = JsonConvert.DeserializeObject<Dictionary<object, object>>(File.ReadAllText(settingsPath));

foreach (var pair in settings)
{
this.Config[pair.Key.ToString()] = pair.Value.ToString();
}

if (!String.IsNullOrEmpty(endpointKey))
{
var luconfigFile = JsonConvert.DeserializeObject<LuConfigFile>(settings["luis"].ToString());
AddLuisConfig(extractPath, luconfigFile, endpointKey);
}

if (!String.IsNullOrEmpty(appPwd))
{
AddOAuthConfig(appPwd);
}
}

public void AddLuisConfig(string extractPath, LuConfigFile luconfigFile)
public void AddLuisConfig(string extractPath, LuConfigFile luconfigFile, string endpointKey)
{
var settingsName = $"luis.settings.{luconfigFile.Environment}.{ luconfigFile.AuthoringRegion}.json";
var luisEndpoint = $"https://{luconfigFile.AuthoringRegion}.api.cognitive.microsoft.com";
Expand All @@ -124,25 +146,16 @@ public void AddLuisConfig(string extractPath, LuConfigFile luconfigFile)

var luisConfig = JsonConvert.DeserializeObject<LuisCustomConfig>(File.ReadAllText(luisPath));

luisConfig.Luis.Add("endpointKey", luconfigFile.AuthoringKey);
luisConfig.Luis.Add("endpointKey", endpointKey);

foreach (var item in luisConfig.Luis)
{
this.Config[$"luis:{item.Key}"] = item.Value;
}
}

private void AddOAuthConfig(string appId, string appPwd)
private void AddOAuthConfig(string appPwd)
{
if (string.IsNullOrEmpty(appId))
{
this.Config["MicrosoftAppId"] = string.Empty;
}
else
{
this.Config["MicrosoftAppId"] = appId;
}

if (string.IsNullOrEmpty(appPwd))
{
this.Config["MicrosoftAppPassword"] = string.Empty;
Expand All @@ -151,7 +164,6 @@ private void AddOAuthConfig(string appId, string appPwd)
{
this.Config["MicrosoftAppPassword"] = appPwd;
}

}

private string GenNewBotDir()
Expand Down
22 changes: 3 additions & 19 deletions BotProject/CSharp/Controllers/BotAdminController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,8 @@
//
// Generated with Bot Builder V4 SDK Template for Visual Studio EchoBot v4.3.0

using System;
using System.Linq;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace Microsoft.Bot.Builder.TestBot.Json
{
Expand All @@ -31,27 +24,18 @@ public IActionResult GetAsync()
{
return Ok();
}


[HttpPost]
public IActionResult PostAsync(IFormFile file, [FromForm]string config, [FromForm]string microsoftAppId, [FromForm]string microsoftAppPassword)
public IActionResult PostAsync(IFormFile file, [FromForm]string endpointKey = null, [FromForm]string microsoftAppPassword = null)
{
if (file == null)
{
return BadRequest();
}

if (!string.IsNullOrEmpty(config))
{
var luisConfigObj = JsonConvert.DeserializeObject<LuConfigFile>(config);
BotManager.SetCurrent(file.OpenReadStream(), luisConfigObj,microsoftAppId, microsoftAppPassword);
BotManager.SetCurrent(file.OpenReadStream(), endpointKey, microsoftAppPassword);

}
else
{
BotManager.SetCurrent(file.OpenReadStream(), null, microsoftAppId, microsoftAppPassword);
}

return Ok();
}
}
Expand Down
39 changes: 30 additions & 9 deletions Composer/cypress/integration/LuisDeploy.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,44 @@ context('Luis Deploy', () => {
cy.server();
cy.route('GET', '/api/launcher/connect', 'OK');
cy.route('POST', '/api/launcher/sync', 'OK');

cy.route('POST', 'api/projects/opened/settings', 'OK');
cy.visit(Cypress.env('COMPOSER_URL'));
cy.openBot('ToDoLuisBot');

// save as a new test bot to prevent changing original luisBot's publish settings and remove it after test
cy.get('[data-testid="LeftNav-CommandBarButtonHome"]').click();
cy.getByText('Save as').click();

cy.get('input[data-testid="NewDialogName"]').type('__TestBot');
cy.get('input[data-testid="NewDialogName"]').type('{enter}');

cy.get('[data-testid="ProjectTree"]').within(() => {
cy.getByText('__TestBot.Main').should('exist');
});
});

it('can deploy luis success', () => {
cy.get('[data-testid="LeftNav-CommandBarButtonUser Says"]').click();
cy.get('[data-testid="LUEditor"]').within(() => {
cy.getAllByText('ToDoLuisBot.Main').should('exist');
});

cy.route('POST', '/api/projects/opened/luFiles/publish', 'fixture:luPublish/success').as('publish');

cy.route({
method: 'POST',
url: '/api/projects/opened/luFiles/publish',
status: 200,
response: 'fixture:luPublish/success',
});
cy.getByText('Start Bot').click();
cy.get('[data-testid="ProjectNameInput"]').type('MyProject');
cy.get('[data-testid="EnvironmentInput"]').type('composer');
cy.get('[data-testid="AuthoringKeyInput"]').type('0d4991873f334685a9686d1b48e0ff48');
// clear its settings before
cy.get('[data-testid="ProjectNameInput"]')
.clear()
.type('MyProject');
cy.get('[data-testid="EnvironmentInput"]')
.clear()
.type('composer');
cy.get('[data-testid="AuthoringKeyInput"]')
.clear()
.type('0d4991873f334685a9686d1b48e0ff48');
// wait for the debounce interval of sync settings
cy.wait(1000);
cy.getByText('Publish').click();
cy.getByText('Restart Bot').should('exist');
cy.getByText('Test in Emulator').should('exist');
Expand Down
8 changes: 1 addition & 7 deletions Composer/packages/client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,13 @@ export const App: React.FC = () => {
const { state, actions } = useContext(StoreContext);
const [sideBarExpand, setSideBarExpand] = useState(false);
const { botName, creationFlowStatus } = state;
const { fetchProject, setCreationFlowStatus, setLuisConfig } = actions;
const { fetchProject, setCreationFlowStatus } = actions;
const mapNavItemTo = x => resolveToBasePath(BASEPATH, x);

useEffect(() => {
init();
}, []);

useEffect(() => {
if (botName) {
setLuisConfig(botName);
}
}, [botName]);

async function init() {
await fetchProject();
}
Expand Down
16 changes: 3 additions & 13 deletions Composer/packages/client/src/CreationFlow/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,7 @@ export function CreationFlow(props) {
const [step, setStep] = useState();
// eslint-disable-next-line react/prop-types
const { creationFlowStatus, setCreationFlowStatus } = props;
const {
fetchTemplates,
getAllProjects,
openBotProject,
createProject,
saveProjectAs,
saveTemplateId,
setLuisConfig,
} = actions;
const { fetchTemplates, getAllProjects, openBotProject, createProject, saveProjectAs, saveTemplateId } = actions;
const { botName, templateId } = state;

useEffect(() => {
Expand Down Expand Up @@ -68,8 +60,7 @@ export function CreationFlow(props) {
};

const openBot = async botFolder => {
const { botName } = await openBotProject(botFolder);
await setLuisConfig(botName);
await openBotProject(botFolder);
navigateTo('/dialogs/Main');
handleDismiss();
};
Expand All @@ -83,8 +74,7 @@ export function CreationFlow(props) {
};

const handleSaveAs = async formData => {
const { botName } = await saveProjectAs(formData.name, formData.description);
setLuisConfig(botName);
await saveProjectAs(formData.name, formData.description);
};

const handleSubmit = formData => {
Expand Down
31 changes: 20 additions & 11 deletions Composer/packages/client/src/TestController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
} from 'office-ui-fabric-react';
import formatMessage from 'format-message';

import LuisStorage from './utils/luisStorage';
import { StoreContext } from './store';
import { bot, botButton, calloutLabel, calloutDescription, calloutContainer } from './styles';
import { LuisConfig, Text, BotStatus } from './constants';
Expand All @@ -19,7 +18,7 @@ import { OpenAlertModal, DialogStyle } from './components/Modal';
import { getReferredFiles } from './utils/luUtil';
import { DialogInfo } from './store/types';

const openInEmulator = (url, authSettings) => {
const openInEmulator = (url, authSettings: { MicrosoftAppId: string; MicrosoftAppPassword: string }) => {
// this creates a temporary hidden iframe to fire off the bfemulator protocol
// and start up the emulator
const i = document.createElement('iframe');
Expand All @@ -45,8 +44,8 @@ export const TestController: React.FC = () => {
const [error, setError] = useState({ title: '', message: '' });
const [luisPublishSucceed, setLuisPublishSucceed] = useState(true);
const botActionRef = useRef(null);
const { botName, botStatus, dialogs, oAuth, toStartBot, luFiles } = state;
const { connectBot, reloadBot, publishLuis, startBot, setLuisConfig } = actions;
const { botName, botStatus, dialogs, toStartBot, luFiles, settings } = state;
const { connectBot, reloadBot, publishLuis, startBot } = actions;
const connected = botStatus === BotStatus.connected;

useEffect(() => {
Expand All @@ -73,10 +72,10 @@ export const TestController: React.FC = () => {
});
return;
}
const config = LuisStorage.get(botName);
const config = settings.luis;

if (getReferredFiles(luFiles, dialogs).length > 0) {
if (!luisPublishSucceed || config[LuisConfig.AUTHORING_KEY] === '') {
if (!luisPublishSucceed || (config && config[LuisConfig.AUTHORING_KEY] === '')) {
setModalOpen(true);
} else {
await publishAndReload();
Expand All @@ -98,9 +97,12 @@ export const TestController: React.FC = () => {
async function handlePublish() {
setFetchState(STATE.PUBLISHING);
try {
await setLuisConfig(botName);
await publishLuis();
return true;
if (settings.luis) {
await publishLuis(settings.luis.authoringKey);
return true;
} else {
throw new Error('Please Set Luis Config');
}
} catch (err) {
setError({ title: Text.LUISDEPLOYFAILURE, message: err.message });
setCalloutVisible(true);
Expand All @@ -113,7 +115,7 @@ export const TestController: React.FC = () => {
async function handleLoadBot() {
setFetchState(STATE.RELOADING);
try {
await (connected ? reloadBot(botName) : connectBot(botName));
await (connected ? reloadBot(settings) : connectBot(settings));
} catch (err) {
setError({ title: Text.CONNECTBOTFAILURE, message: err.message });
setCalloutVisible(true);
Expand All @@ -130,7 +132,14 @@ export const TestController: React.FC = () => {
iconProps={{
iconName: 'OpenInNewTab',
}}
onClick={() => openInEmulator('http://localhost:3979/api/messages', oAuth)}
onClick={() =>
openInEmulator(
'http://localhost:3979/api/messages',
settings.MicrosoftAppId && settings.MicrosoftAppPassword
? { MicrosoftAppId: settings.MicrosoftAppId, MicrosoftAppPassword: settings.MicrosoftAppPassword }
: { MicrosoftAppPassword: '', MicrosoftAppId: '' }
)
}
>
{formatMessage('Test in Emulator')}
</ActionButton>
Expand Down
5 changes: 4 additions & 1 deletion Composer/packages/client/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ export enum ActionTypes {
CONNECT_BOT_FAILURE = 'CONNECT_BOT_FAILURE',
RELOAD_BOT_SUCCESS = 'RELOAD_BOT_SUCCESS',
RELOAD_BOT_FAILURE = 'RELOAD_BOT_FAILURE',
UPDATE_OAUTH = 'UPDATE_OAUTH',
UPDATE_ENV_SETTING = 'UPDATE_ENV_SETTING',
SYNC_ENV_SETTING = 'SYNC_ENV_SETTING',
SET_ERROR = 'SET_ERROR',
TO_START_BOT = 'TO_START_BOT',
EDITOR_RESET_VISUAL = 'EDITOR_RESET_VISUAL',
Expand Down Expand Up @@ -190,3 +191,5 @@ export const SupportedFileTypes = [
'xlsx',
'xsn',
];

export const SensitiveProperties = ['MicrosoftAppPassword', 'luis.authoringKey', 'luis.endpointKey'];
Loading