Eula handling for Azdata (#12035)

* Eula handling for Azdata

* PR feedback

* pr feedback

* pr feedback

* remove extra await

Co-authored-by: chgagnon <chgagnon@microsoft.com>
This commit is contained in:
Arvind Ranasaria
2020-08-31 18:57:22 -07:00
committed by GitHub
parent 85e6d785ff
commit 23bd05ea68
4 changed files with 63 additions and 16 deletions

View File

@@ -11,8 +11,8 @@ import { executeCommand, executeSudoCommand, ExitCodeError, ProcessOutput } from
import { HttpClient } from './common/httpClient';
import Logger from './common/logger';
import { getErrorMessage, searchForCmd } from './common/utils';
import { acceptEula, azdataConfigSection, debugConfigKey, doNotPromptInstallMemento, doNotPromptUpdateMemento, eulaUrl, installationReadmeUrl, microsoftPrivacyStatementUrl, requiredVersion } from './constants';
import * as loc from './localizedConstants';
import { azdataConfigSection, debugConfigKey, requiredVersion as requiredVersion, installationReadmeUrl, doNotPromptInstallMemento, doNotPromptUpdateMemento } from './constants';
export const azdataHostname = 'https://aka.ms';
export const azdataUri = 'azdata-msi';
@@ -291,6 +291,26 @@ export async function manuallyInstallOrUpgradeAzdata(context: vscode.ExtensionCo
// await vscode.window.showTextDocument(vscode.Uri.parse(downloadedFile));
}
/**
* Prompts user to accept EULA it if was not previously accepted. Stores and returns the user response to EULA prompt.
* @param memento - memento where the user response is stored.
* pre-requisite, the calling code has to ensure that the eula has not yet been previously accepted by the user.
* returns true if the user accepted the EULA.
*/
export async function promptForEula(memento: vscode.Memento): Promise<boolean> {
Logger.show();
Logger.log(loc.promptForEulaLog(microsoftPrivacyStatementUrl, eulaUrl));
const reply = await vscode.window.showInformationMessage(loc.promptForEula(microsoftPrivacyStatementUrl, eulaUrl), loc.yes, loc.no);
Logger.log(loc.userResponseToEulaPrompt(reply));
if (reply === loc.yes) {
await memento.update(acceptEula, true);
return true;
} else {
return false;
}
}
/**
* Downloads the Windows installer and runs it
*/

View File

@@ -5,6 +5,9 @@
export const azdataConfigSection = 'azdata';
export const debugConfigKey = 'logDebugInfo';
export const acceptEula = 'acceptEula';
export const microsoftPrivacyStatementUrl = 'https://privacy.microsoft.com/en-us/privacystatement';
export const eulaUrl = 'https://aka.ms/eula-azdata-en';
export const requiredVersion = '20.1.1';
export const doNotPromptInstallMemento = 'azdata.doNotPromptInstall';
export const doNotPromptUpdateMemento = 'azdata.doNotPromptUpdate';

View File

@@ -3,15 +3,28 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as azdataExt from 'azdata-ext';
import { findAzdata, IAzdataTool, manuallyInstallOrUpgradeAzdata } from './azdata';
import * as vscode from 'vscode';
import { findAzdata, IAzdataTool, manuallyInstallOrUpgradeAzdata, promptForEula } from './azdata';
import Logger from './common/logger';
import * as constants from './constants';
import * as loc from './localizedConstants';
let localAzdata: IAzdataTool | undefined = undefined;
let eulaAccepted: boolean = false;
export async function activate(context: vscode.ExtensionContext): Promise<azdataExt.IExtension> {
localAzdata = await checkForAzdata();
eulaAccepted = !!context.globalState.get(constants.acceptEula);
if (!eulaAccepted) {
// Don't block on this since we want extension to finish activating without requiring user actions.
// If EULA has not been accepted then we will check again while executing azdata commands.
promptForEula(context.globalState)
.then(userResponse => {
eulaAccepted = userResponse;
})
.catch(err => console.log(err));
}
// Don't block on this since we want the extension to finish activating without user actions
manuallyInstallOrUpgradeAzdata(context, localAzdata)
.catch(err => console.log(err));
@@ -20,22 +33,22 @@ export async function activate(context: vscode.ExtensionContext): Promise<azdata
arc: {
dc: {
create: async (namespace: string, name: string, connectivityMode: string, resourceGroup: string, location: string, subscription: string, profileName?: string, storageClass?: string) => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.arc.dc.create(namespace, name, connectivityMode, resourceGroup, location, subscription, profileName, storageClass);
},
endpoint: {
list: async () => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.arc.dc.endpoint.list();
}
},
config: {
list: async () => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.arc.dc.config.list();
},
show: async () => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.arc.dc.config.show();
}
}
@@ -43,11 +56,11 @@ export async function activate(context: vscode.ExtensionContext): Promise<azdata
postgres: {
server: {
list: async () => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.arc.postgres.server.list();
},
show: async (name: string) => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.arc.postgres.server.show(name);
}
}
@@ -55,36 +68,43 @@ export async function activate(context: vscode.ExtensionContext): Promise<azdata
sql: {
mi: {
delete: async (name: string) => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.arc.sql.mi.delete(name);
},
list: async () => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.arc.sql.mi.list();
},
show: async (name: string) => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.arc.sql.mi.show(name);
}
}
}
},
login: async (endpoint: string, username: string, password: string) => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.login(endpoint, username, password);
},
version: async () => {
throwIfNoAzdata();
await throwIfNoAzdataOrEulaNotAccepted(context);
return localAzdata!.version();
}
}
};
}
function throwIfNoAzdata(): void {
async function throwIfNoAzdataOrEulaNotAccepted(context: vscode.ExtensionContext): Promise<void> {
if (!localAzdata) {
throw new Error(loc.noAzdata);
}
if (!eulaAccepted) {
eulaAccepted = await promptForEula(context.globalState);
}
if (!eulaAccepted) {
Logger.log(loc.eulaNotAccepted);
throw new Error(loc.eulaNotAccepted);
}
}
async function checkForAzdata(): Promise<IAzdataTool | undefined> {

View File

@@ -35,6 +35,10 @@ export const unexpectedCommandError = (errMsg: string): string => localize('azda
export const upgradeError = (err: any): string => localize('azdata.upgradeError', "Error upgrading azdata : {0}", err.message ?? err);
export const upgradeCheckSkipped = localize('azdata.updateCheckSkipped', "No check for new azdata version availability performed as azdata was not found to be installed");
export const unexpectedExitCode = (code: number, err: string): string => localize('azdata.unexpectedExitCode', "Unexpected exit code from command : {1} ({0})", code, err);
export const noAzdata = localize('azdata.NoAzdata', "No azdata available");
export const noAzdata = localize('azdata.noAzdata', "No azdata available");
export const eulaNotAccepted = localize('azdata.eulaNotAccepted', "Microsoft Privacy statement and Azure Data CLI license terms have not been accepted");
export const installManually = (expectedVersion: string, instructionsUrl: string) => localize('azdata.installManually', "azdata is not installed. Version: {0} needs to be installed or some features may not work. Please install it manually using these [instructions]({1}). Restart ADS when installation is done.", expectedVersion, instructionsUrl);
export const installCorrectVersionManually = (currentVersion: string, expectedVersion: string, instructionsUrl: string) => localize('azdata.installCorrectVersionManually', "azdata version: {0} is installed, version: {1} needs to be installed or some features may not work. Please uninstall the current version and then install the correct version manually using these [instructions]({2}). Restart ADS when installation is done.", currentVersion, expectedVersion, instructionsUrl);
export const promptForEula = (privacyStatementUrl: string, eulaUrl: string) => localize('azdata.promptForEula', "It is required to accept the [Microsoft Privacy Statement]({0}) and the [Azure Data CLI license terms]({1}) to use this extension. Declining this will result in some features not working.", privacyStatementUrl, eulaUrl);
export const promptForEulaLog = (privacyStatementUrl: string, eulaUrl: string) => localize('azdata.promptForEulaLog', "Prompting the user to accept the following: {0}", promptForEula(privacyStatementUrl, eulaUrl));
export const userResponseToEulaPrompt = (response: string | undefined) => localize('azdata.promptForEulaResponse', "User response to Eula prompt: {0}", response);