Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
Add ability to trust a notebook
  • Loading branch information
DonJayamanne committed Jul 9, 2020
commit 3bbd3fe7c796c2a38349065ee510eabb2ecd7e24
43 changes: 43 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,25 @@
},
"enablement": "python.datascience.notebookeditor.canrestartNotebookkernel"
},
{
"command": "python.datascience.notebookeditor.trust",
"title": "%DataScience.trustNotebookCommandTitle%",
"category": "Python",
"icon": {
"light": "resources/light/un-trusted.svg",
"dark": "resources/dark/un-trusted.svg"
},
"enablement": "notebookEditorFocused && !python.datascience.isnotebooktrusted && python.datascience.trustfeatureenabled"
},
{
"command": "python.datascience.notebookeditor.trusted",
"title": "%DataScience.notebookIsTrusted%",
"category": "Python",
"icon": {
"light": "resources/light/trusted.svg",
"dark": "resources/dark/trusted.svg"
}
},
{
"command": "python.datascience.notebookeditor.runallcells",
"title": "%python.command.python.datascience.notebookeditor.runallcells.title%",
Expand Down Expand Up @@ -849,6 +868,18 @@
"title": "%python.command.python.datascience.restartkernel.title%",
"group": "navigation",
"when": "notebookEditorFocused"
},
{
"command": "python.datascience.notebookeditor.trust",
"title": "%DataScience.trustNotebookCommandTitle%",
"group": "navigation@1",
"when": "notebookEditorFocused && !python.datascience.isnotebooktrusted && python.datascience.trustfeatureenabled"
},
{
"command": "python.datascience.notebookeditor.trusted",
"title": "%DataScience.notebookIsTrusted%",
"group": "navigation@1",
"when": "notebookEditorFocused && python.datascience.isnotebooktrusted && python.datascience.trustfeatureenabled"
}
],
"explorer/context": [
Expand Down Expand Up @@ -1122,6 +1153,18 @@
"category": "Python",
"when": "python.datascience.isnativeactive && python.datascience.featureenabled && python.datascience.isnotebooktrusted"
},
{
"command": "python.datascience.notebookeditor.trust",
"title": "%DataScience.trustNotebookCommandTitle%",
"category": "Python",
"when": "python.datascience.featureenabled && notebookEditorFocused && !python.datascience.isnotebooktrusted && python.datascience.trustfeatureenabled"
},
{
"command": "python.datascience.notebookeditor.trusted",
"title": "%DataScience.notebookIsTrusted%",
"category": "Python",
"when": "config.noExists"
},
{
"command": "python.datascience.notebookeditor.runallcells",
"title": "%python.command.python.datascience.notebookeditor.runallcells.title%",
Expand Down
1 change: 1 addition & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@
"DataScience.fetchingDataViewer": "Fetching data ...",
"DataScience.noRowsInDataViewer": "No rows match current filter",
"DataScience.jupyterServer": "Jupyter Server",
"DataScience.trustNotebookCommandTitle": "Trust notebook",
"DataScience.notebookIsTrusted": "Trusted",
"DataScience.notebookIsNotTrusted": "Not Trusted",
"DataScience.noKernel": "No Kernel",
Expand Down
4 changes: 4 additions & 0 deletions resources/dark/trusted.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions resources/dark/un-trusted.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions resources/light/run-file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions resources/light/trusted.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions resources/light/un-trusted.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/client/common/application/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,6 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu
[DSCommands.OpenNotebookNonCustomEditor]: [Uri];
[DSCommands.GatherQuality]: [string];
[DSCommands.EnableLoadingWidgetsFrom3rdPartySource]: [undefined | never];
[DSCommands.TrustNotebook]: [undefined | never | Uri];
[DSCommands.TrustedNotebook]: [undefined | never];
}
2 changes: 2 additions & 0 deletions src/client/datascience/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ export namespace Commands {
export const SaveAsNotebookNonCustomEditor = 'python.datascience.notebookeditor.saveAs';
export const OpenNotebookNonCustomEditor = 'python.datascience.notebookeditor.open';
export const GatherQuality = 'python.datascience.gatherquality';
export const TrustNotebook = 'python.datascience.notebookeditor.trust';
export const TrustedNotebook = 'python.datascience.notebookeditor.trusted';
Comment thread
joyceerhl marked this conversation as resolved.
export const EnableLoadingWidgetsFrom3rdPartySource =
'python.datascience.enableLoadingWidgetScriptsFromThirdPartySource';
}
Expand Down
2 changes: 1 addition & 1 deletion src/client/datascience/context/activeEditorContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class ActiveEditorContextService implements IExtensionSingleActivationSer
.getOrCreateNotebook({ identity: activeEditor.file, getOnly: true })
.then((nb) => {
if (activeEditor === this.notebookEditorProvider.activeEditor) {
const canStart = nb && nb.status !== ServerStatus.NotStarted;
const canStart = nb && nb.status !== ServerStatus.NotStarted && activeEditor.model?.isTrusted;
this.canRestartNotebookKernelContext.set(!!canStart).ignoreErrors();
}
})
Expand Down
50 changes: 14 additions & 36 deletions src/client/datascience/interactive-ipynb/nativeEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import * as path from 'path';
import {
CancellationToken,
CancellationTokenSource,
commands,
Event,
EventEmitter,
Memento,
Expand Down Expand Up @@ -98,7 +97,6 @@ import { KernelSwitcher } from '../jupyter/kernels/kernelSwitcher';
const nativeEditorDir = path.join(EXTENSION_ROOT_DIR, 'out', 'datascience-ui', 'notebook');
@injectable()
export class NativeEditor extends InteractiveBase implements INotebookEditor {
public readonly type: 'old' | 'custom' = 'custom';
public get onDidChangeViewState(): Event<void> {
return this._onDidChangeViewState.event;
}
Expand Down Expand Up @@ -140,6 +138,7 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor {
public get isDirty(): boolean {
return this.model ? this.model.isDirty : false;
}
public readonly type: 'old' | 'custom' = 'custom';
public model: Readonly<INotebookModel> | undefined;
protected savedEvent: EventEmitter<INotebookEditor> = new EventEmitter<INotebookEditor>();
protected closedEvent: EventEmitter<INotebookEditor> = new EventEmitter<INotebookEditor>();
Expand All @@ -152,6 +151,7 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor {
private startupTimer: StopWatch = new StopWatch();
private loadedAllCells: boolean = false;
private executeCancelTokens = new Set<CancellationTokenSource>();
private previouslyNotTrusted:boolean = false;

constructor(
@multiInject(IInteractiveWindowListener) listeners: IInteractiveWindowListener[],
Expand Down Expand Up @@ -227,6 +227,7 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor {
);
asyncRegistry.push(this);

asyncRegistry.push(this.trustService.onDidSetNotebookTrust(this.monitorChangesToTrust, this));
this.synchronizer.subscribeToUserActions(this, this.postMessage.bind(this));
}

Expand All @@ -251,6 +252,7 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor {

// Sign up for dirty events
model.changed(this.modelChanged.bind(this));
this.previouslyNotTrusted = model.isTrusted;
}

// tslint:disable-next-line: no-any
Expand Down Expand Up @@ -596,7 +598,13 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor {
}
}
}

private async monitorChangesToTrust() {
if (this.previouslyNotTrusted && this.model?.isTrusted) {
Comment thread
DonJayamanne marked this conversation as resolved.
this.previouslyNotTrusted = false;
// Tell UI to update main state
this.postMessage(InteractiveWindowMessages.TrustNotebookComplete).ignoreErrors();
}
}
private renameVariableExplorerHeights(name: string, updatedName: string) {
// Updates the workspace storage to reflect the updated name of the notebook
// should be called if the name of the notebook changes
Expand All @@ -612,38 +620,8 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor {
}

private async launchNotebookTrustPrompt() {
const prompts = [
localize.DataScience.trustNotebook(),
localize.DataScience.doNotTrustNotebook(),
localize.DataScience.trustAllNotebooks()
];
const selection = await this.applicationShell.showErrorMessage(
localize.DataScience.launchNotebookTrustPrompt(),
...prompts
);
if (!selection) {
return;
}
if (this.model && selection === localize.DataScience.trustNotebook() && !this.model.isTrusted) {
try {
const contents = this.model.getContent();
await this.trustService.trustNotebook(this.model.file, contents);
// Update model trust
this.model.update({
source: 'user',
kind: 'updateTrust',
oldDirty: this.model.isDirty,
newDirty: this.model.isDirty,
isNotebookTrusted: true
});
// Tell UI to update main state
await this.postMessage(InteractiveWindowMessages.TrustNotebookComplete);
} catch (err) {
traceError(err);
}
} else if (selection === localize.DataScience.trustAllNotebooks()) {
// Take the user to the settings UI where they can manually turn on the alwaysTrustNotebooks setting
commands.executeCommand('workbench.action.openSettings', 'python.dataScience.alwaysTrustNotebooks');
if (this.model && !this.model.isTrusted) {
await this.commandManager.executeCommand(Commands.TrustNotebook, this.model.file);
Comment thread
DonJayamanne marked this conversation as resolved.
}
}

Expand Down Expand Up @@ -831,4 +809,4 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor {
}
}
}
}

21 changes: 16 additions & 5 deletions src/client/datascience/notebook/helpers/cellUpdateHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ import { traceError } from '../../../common/logger';
import { sendTelemetryEvent } from '../../../telemetry';
import { VSCodeNativeTelemetry } from '../../constants';
import { VSCodeNotebookModel } from '../../notebookStorage/vscNotebookModel';
import { INotebookModel } from '../../types';
import { findMappedNotebookCellModel } from './cellMappers';
import { createCellFromVSCNotebookCell, updateVSCNotebookCellMetadata } from './helpers';
import {
createCellFromVSCNotebookCell,
createVSCCellOutputsFromOutputs,
updateVSCNotebookCellMetadata
} from './helpers';
// tslint:disable-next-line: no-var-requires no-require-imports
const vscodeNotebookEnums = require('vscode') as typeof import('vscode-proposed');

Expand Down Expand Up @@ -53,9 +58,8 @@ export function updateCellModelWithChangesToVSCCell(

/**
* Updates a notebook document as a result of trusting it.
* @returns `true` if document has been updated, else `false`.
*/
export function updateVSCNotebookAfterTrustingNotebook(document: NotebookDocument) {
export function updateVSCNotebookAfterTrustingNotebook(document: NotebookDocument, model: INotebookModel) {
const areAllCellsEditableAndRunnable = document.cells.every((cell) => {
if (cell.cellKind === vscodeNotebookEnums.CellKind.Markdown) {
return cell.metadata.editable;
Expand All @@ -69,8 +73,9 @@ export function updateVSCNotebookAfterTrustingNotebook(document: NotebookDocumen
document.metadata.editable &&
document.metadata.runnable;

// If already trusted, then nothing to do.
if (isDocumentEditableAndRunnable && areAllCellsEditableAndRunnable) {
return false;
return;
}

document.metadata.cellEditable = true;
Expand All @@ -83,8 +88,14 @@ export function updateVSCNotebookAfterTrustingNotebook(document: NotebookDocumen
if (cell.cellKind !== vscodeNotebookEnums.CellKind.Markdown) {
cell.metadata.runnable = true;
}

// Restore the output once we trust the notebook.
const cellModel = findMappedNotebookCellModel(cell, model.cells);
if (cellModel) {
// tslint:disable-next-line: no-any
cell.outputs = createVSCCellOutputsFromOutputs(cellModel.data.outputs as any);
}
});
return true;
}

export function clearCellForExecution(vscCell: NotebookCell, model: VSCodeNotebookModel) {
Expand Down
Loading