PUT in BotService was replaced by GET - the bot was unusable.

This commit is contained in:
Rodrigo Rodriguez (pragmatismo.io) 2018-11-01 15:11:23 -03:00
parent fa8e310a2e
commit 4315449a91
4 changed files with 97 additions and 110 deletions

View file

@ -79,37 +79,6 @@ export class GBAdminService {
return Promise.resolve(obj.value);
}
public static async acquireMsGraphTokenFromUsername(username, password) {
return new Promise<string>(async (resolve, reject) => {
let resource = "https://graph.microsoft.com";
let authenticatorAuthorityHostUrl = "https://login.microsoftonline.com";
let authenticatorTenant = "pragmatismo.onmicrosoft.com";
let authenticatorClientId = "0ffice19-91d5-41ea-98a4-ceea1655cc0b";
let authorizationUrl = UrlJoin(
authenticatorAuthorityHostUrl,
authenticatorTenant,
"/oauth2/authorize"
);
var authenticationContext = new AuthenticationContext(authorizationUrl);
authenticationContext.acquireTokenWithUsernamePassword(
resource,
username,
password,
authenticatorClientId,
async (err, res) => {
if (err) {
reject(err);
} else {
let token = res as TokenResponse;
resolve(token.accessToken);
}
}
);
});
}
public async acquireElevatedToken(instanceId): Promise<string> {
return new Promise<string>(async (resolve, reject) => {
let instance = await this.core.loadInstanceById(instanceId);
@ -195,7 +164,22 @@ export class GBAdminService {
maximumLength: 14
};
let password = passwordGenerator.generatePassword(options);
password = password.replace(/[=:;\?]/g, "");
password = password.replace(/@[=:;\?]/g, "#");
return password;
}
public static getRndReadableIdentifier() {
const passwordGenerator = new PasswordGenerator();
const options = {
upperCaseAlpha: false,
lowerCaseAlpha: true,
number: false,
specialCharacter: false,
minimumLength: 12,
maximumLength: 14
};
let name = passwordGenerator.generatePassword(options);
return name;
}
}

View file

@ -81,8 +81,10 @@ export class AzureDeployerService extends GBService {
let culture = "en-us";
// Tries do get information from .env file otherwise asks in command-line.
let instance: IGBInstance = {};
instance = await this.ensureConfiguration(instance);
instance.marketplacePassword = GBAdminService.getRndPassword();
let spinner = new Spinner("%s");
spinner.start();
@ -91,12 +93,19 @@ export class AzureDeployerService extends GBService {
let keys: any;
let name = instance.botId;
instance.marketplacePassword = GBAdminService.getRndPassword();
await this.internalDeployApp(name, instance.marketplacePassword)
logger.info(`Deploying Deploy Group (It may take a few minutes)...`);
await this.createDeployGroup(name, instance.cloudLocation);
instance = await this.deployBootBot(
instance,
name,
`${proxyAddress}/api/messages/${name}`,
instance.nlpAppId,
instance.nlpKey,
instance.cloudSubscriptionId
);
logger.info(`Deploying Bot Server...`);
let serverFarm = await this.createHostingPlan(
name,
@ -110,10 +119,9 @@ export class AzureDeployerService extends GBService {
instance.cloudLocation
);
let administratorLogin = `sa${GBAdminService.getRndPassword()}`;
let administratorPassword = GBAdminService.getRndPassword();
logger.info(`Deploying Bot Storage...`);
let administratorLogin = `sa${GBAdminService.getRndReadableIdentifier()}`;
let administratorPassword = GBAdminService.getRndPassword();
let storageServer = `${name}-storage-server`;
let storageName = `${name}-storage`;
await this.createStorageServer(
@ -124,7 +132,6 @@ export class AzureDeployerService extends GBService {
storageServer,
instance.cloudLocation
);
await this.createStorage(
name,
storageServer,
@ -195,7 +202,7 @@ export class AzureDeployerService extends GBService {
culture,
instance.nlpAuthoringKey
);
let appId = GBAdminService.generateUuid();
instance.nlpEndpoint = nlp.endpoint;
instance.nlpKey = keys.key1;
instance.nlpAppId = nlpAppId;
@ -205,10 +212,9 @@ export class AzureDeployerService extends GBService {
instance,
name,
`${proxyAddress}/api/messages/${name}`,
null,
null,
instance.cloudSubscriptionId,
appId
instance.nlpAppId,
instance.nlpKey,
instance.cloudSubscriptionId
);
spinner.stop();
@ -371,9 +377,34 @@ export class AzureDeployerService extends GBService {
endpoint,
nlpAppId,
nlpKey,
subscriptionId,
appId
subscriptionId
) {
let appId = GBConfigService.get("MSAPP_ID");
let appPassword = GBConfigService.get("MSAPP_PASSWORD");
if (!appId || !appPassword) {
process.stdout.write(
"Sorry, this part cannot be automated yet due to Microsoft schedule, please go to https://apps.dev.microsoft.com/portal/register-app to generate manually an App ID and App Secret.\n"
);
}
let retriveAppId = () => {
if (!appId) {
process.stdout.write("Generated Application Id (MSAPP_ID):");
appId = scanf("%s").replace(/(\n|\r)+$/, "");
}
};
let retriveAppPassword = () => {
if (!appPassword) {
process.stdout.write("Generated Password (MSAPP_PASSWORD):");
appPassword = scanf("%s").replace(/(\n|\r)+$/, "");
}
};
retriveAppId();
retriveAppPassword();
await this.internalDeployBot(
instance,
this.accessToken,
@ -385,10 +416,12 @@ export class AzureDeployerService extends GBService {
"global",
nlpAppId,
nlpKey,
subscriptionId,
appId
appId,
appPassword,
subscriptionId
);
instance.marketplaceId = appId;
instance.marketplacePassword = appPassword;
instance.botId = botId;
return instance;
@ -424,46 +457,12 @@ export class AzureDeployerService extends GBService {
req.headers = {};
req.headers["Content-Type"] = "application/json; charset=utf-8";
req.headers["accept-language"] = "*";
req.headers["x-ms-client-request-id"] = GBAdminService.generateUuid();
req.headers["Authorization"] = "Bearer " + accessToken;
let httpClient = new ServiceClient();
let res = await httpClient.sendRequest(req);
// TODO: Check res for error.
}
private async internalDeployApp(name, pass) {
let username = GBConfigService.get("CLOUD_USERNAME");
let password = GBConfigService.get("CLOUD_PASSWORD");
let accessToken = await GBAdminService.acquireMsGraphTokenFromUsername(username, password);
let graphUrl = "https://graph.microsoft.com";
let expiresOn = new Date().toISOString();
let parameters = {
displayName: name,
passwordCredentials: [
{
secretText: pass,
endDateTime: expiresOn
}
]
};
let req = new WebResource();
req.method = "POST";
req.url = `${graphUrl}/beta/applications`;
req.headers = {};
req.headers["Content-Type"] = "application/json; charset=utf-8";
req.headers["accept-language"] = "*";
req.headers["x-ms-client-request-id"] = GBAdminService.generateUuid();
req.headers["Authorization"] = "Bearer " + accessToken;
req.body = parameters;
let httpClient = new ServiceClient();
return await httpClient.sendRequest(req);
}
/**
* @see https://github.com/Azure/azure-rest-api-specs/blob/master/specification/botservice/resource-manager/Microsoft.BotService/preview/2017-12-01/botservice.json
*/
@ -478,14 +477,16 @@ export class AzureDeployerService extends GBService {
location,
nlpAppId,
nlpKey,
subscriptionId,
appId
appId,
appPassword,
subscriptionId
) {
return new Promise(async (resolve, reject) => {
let baseUrl = `https://management.azure.com/`;
await this.registerProviders(subscriptionId, baseUrl, accessToken);
let appPassword = GBAdminService.getRndPassword();
instance.marketplaceId = appId;
instance.marketplacePassword = appPassword;
let parameters = {
location: location,
@ -499,12 +500,12 @@ export class AzureDeployerService extends GBService {
displayName: name,
endpoint: endpoint,
iconUrl: iconUrl,
luisAppIds: [nlpAppId],
luisKey: nlpKey,
//luisAppIds: [nlpAppId],
//luisKey: nlpKey,
msaAppId: appId,
msaAppPassword: appPassword,
enabledChannels: ["webchat", "skype", "facebook"],
configuredChannels: ["webchat", "skype", "facebook"]
//enabledChannels: ["webchat"], // , "skype", "facebook"],
configuredChannels: ["webchat"] // , "skype", "facebook"]
}
};
@ -524,7 +525,9 @@ export class AzureDeployerService extends GBService {
reject(res.bodyAsText);
return;
}
logger.info(`Bot creation request done waiting for key generation...`);
resolve(instance);
setTimeout(async () => {
try {
@ -535,18 +538,13 @@ export class AzureDeployerService extends GBService {
req = this.createRequestObject(
url,
accessToken,
"PUT",
"GET",
JSON.stringify(parameters)
);
let resChannel = await httpClient.sendRequest(req);
console.log(resChannel.bodyAsText);
let key = (resChannel.bodyAsJson as any).properties.properties
.sites[0].key;
instance.marketplacePassword = appPassword;
instance.webchatKey = key;
resolve(instance);
} catch (error) {
reject(error);
@ -561,7 +559,10 @@ export class AzureDeployerService extends GBService {
let password = GBConfigService.get("CLOUD_PASSWORD");
let subscriptionId = GBConfigService.get("CLOUD_SUBSCRIPTIONID");
let accessToken = await GBAdminService.getADALTokenFromUsername(username, password);
let accessToken = await GBAdminService.getADALTokenFromUsername(
username,
password
);
let httpClient = new ServiceClient();
let parameters = {

View file

@ -1,8 +1,8 @@
/*****************************************************************************\
| ( )_ _ |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ ___ _ |
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/' _ `\ /'_`\ |
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| ( ) |( (_) ) |
| _ _ _ __ _ _ __ ___ ___ _ _ | ,_)(_) ___ _ _ _ |
| ( '_`\ ( '__)/'_` ) /'_ `\/' _ ` _ `\ /'_` )| | | |/',__)/ \ /`\ /'_`\ |
| | (_) )| | ( (_| |( (_) || ( ) ( ) |( (_| || |_ | |\__, \| |*| |( (_) ) |
| | ,__/'(_) `\__,_)`\__ |(_) (_) (_)`\__,_)`\__)(_)(____/(_) (_)`\___/' |
| | | ( )_) | |
| (_) \___/' |
@ -300,20 +300,22 @@ export class GBCoreService implements IGBCoreService {
public async writeEnv(instance: IGBInstance) {
let env =
`ADMIN_PASS=${instance.adminPass}\n` +
`ADDITIONAL_DEPLOY_PATH=\n` +
`ADMIN_PASS=${instance.adminPass}\n` +
`CLOUD_SUBSCRIPTIONID=${instance.cloudSubscriptionId}\n` +
`CLOUD_LOCATION=${instance.cloudLocation}\n` +
`CLOUD_GROUP=${instance.botId}\n` +
`CLOUD_USERNAME=${instance.cloudUsername}\n` +
`CLOUD_PASSWORD=${instance.cloudPassword}\n` +
`MSAPP_ID=${instance.marketplaceId}\n`+
`MSAPP_PASSWORD=${instance.marketplacePassword}\n`+
`NLP_AUTHORING_KEY=${instance.nlpAuthoringKey}\n`+
`STORAGE_DIALECT=${instance.storageDialect}\n` +
`STORAGE_SERVER=${instance.storageServer}.database.windows.net\n` +
`STORAGE_NAME=${instance.storageName}\n` +
`STORAGE_USERNAME=${instance.storageUsername}\n` +
`STORAGE_PASSWORD=${instance.storagePassword}\n` +
`STORAGE_SYNC=true\n` +
`CLOUD_USERNAME=${instance.cloudUsername}\n` +
`CLOUD_PASSWORD=${instance.cloudPassword}\n` +
`CLOUD_SUBSCRIPTIONID=${instance.cloudSubscriptionId}\n` +
`CLOUD_LOCATION=${instance.cloudLocation}\n` +
`CLOUD_GROUP=${instance.botId}\n` +
`NLP_AUTHORING_KEY=${instance.nlpAuthoringKey}`;
`STORAGE_SYNC=true\n`;
fs.writeFileSync(".env", env);
}

View file

@ -108,7 +108,7 @@ export class GBServer {
bootInstance = await azureDeployer.deployFarm(proxyAddress);
} catch (error) {
logger.warn(
"Error while deploying to the cloud, please, cleanup any objects created before running again."
"In case of error, please cleanup any infrastructure (cloud or on-premises) objects created before running again."
);
throw error;
}
@ -205,7 +205,7 @@ export class GBServer {
// Load all instances from .gbot found on deploy package directory.
if (!instances) {
let saveInstance = new GuaribasInstance(bootInstance);
saveInstance.save();
await saveInstance.save();
instances = await core.loadInstances();
}