mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 02:32:35 -05:00
Merge from vscode 10492ba146318412cbee8b76a8c630f226914734
This commit is contained in:
@@ -35,7 +35,6 @@ const BUILT_IN_AUTH_DEPENDENTS: AuthDependent[] = [
|
||||
interface AllowedExtension {
|
||||
id: string;
|
||||
name: string;
|
||||
sessionIds?: string[];
|
||||
}
|
||||
|
||||
function readAllowedExtensions(storageService: IStorageService, providerId: string, accountName: string): AllowedExtension[] {
|
||||
@@ -87,15 +86,6 @@ export class MainThreadAuthenticationProvider extends Disposable {
|
||||
const updatedAllowedList = quickPick.selectedItems.map(item => item.extension);
|
||||
storageService.store(`${this.id}-${accountName}`, JSON.stringify(updatedAllowedList), StorageScope.GLOBAL);
|
||||
|
||||
// Remove sessions of untrusted extensions
|
||||
const deselectedItems = items.filter(item => !quickPick.selectedItems.includes(item));
|
||||
deselectedItems.forEach(item => {
|
||||
const extensionData = allowedExtensions.find(extension => item.extension.id === extension.id);
|
||||
extensionData?.sessionIds?.forEach(sessionId => {
|
||||
this.logout(sessionId);
|
||||
});
|
||||
});
|
||||
|
||||
quickPick.dispose();
|
||||
});
|
||||
|
||||
@@ -286,19 +276,10 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
|
||||
this.authenticationService.sessionsUpdate(id, event);
|
||||
}
|
||||
|
||||
async $getSessionsPrompt(providerId: string, accountName: string, sessionId: string, providerName: string, extensionId: string, extensionName: string): Promise<boolean> {
|
||||
async $getSessionsPrompt(providerId: string, accountName: string, providerName: string, extensionId: string, extensionName: string): Promise<boolean> {
|
||||
const allowList = readAllowedExtensions(this.storageService, providerId, accountName);
|
||||
const extensionData = allowList.find(extension => extension.id === extensionId);
|
||||
if (extensionData) {
|
||||
if (!extensionData.sessionIds) {
|
||||
extensionData.sessionIds = [];
|
||||
}
|
||||
|
||||
if (!extensionData.sessionIds.find(id => id === sessionId)) {
|
||||
extensionData.sessionIds.push(sessionId);
|
||||
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -313,7 +294,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
|
||||
|
||||
const allow = choice === 1;
|
||||
if (allow) {
|
||||
allowList.push({ id: extensionId, name: extensionName, sessionIds: [sessionId] });
|
||||
allowList.push({ id: extensionId, name: extensionName });
|
||||
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
@@ -332,12 +313,4 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
|
||||
|
||||
return choice === 1;
|
||||
}
|
||||
|
||||
async $setTrustedExtension(providerId: string, accountName: string, extensionId: string, extensionName: string): Promise<void> {
|
||||
const allowList = readAllowedExtensions(this.storageService, providerId, accountName);
|
||||
if (!allowList.find(allowed => allowed.id === extensionId)) {
|
||||
allowList.push({ id: extensionId, name: extensionName, sessionIds: [] });
|
||||
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol));
|
||||
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors));
|
||||
const extHostTheming = rpcProtocol.set(ExtHostContext.ExtHostTheming, new ExtHostTheming(rpcProtocol));
|
||||
const extHostAuthentication = rpcProtocol.set(ExtHostContext.ExtHostAuthentication, new ExtHostAuthentication(rpcProtocol, extHostStorage));
|
||||
const extHostAuthentication = rpcProtocol.set(ExtHostContext.ExtHostAuthentication, new ExtHostAuthentication(rpcProtocol));
|
||||
const extHostTimeline = rpcProtocol.set(ExtHostContext.ExtHostTimeline, new ExtHostTimeline(rpcProtocol, extHostCommands));
|
||||
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment, extHostWorkspace, extHostLogService, extHostApiDeprecation, extHostDocuments));
|
||||
|
||||
|
||||
@@ -162,9 +162,8 @@ export interface MainThreadAuthenticationShape extends IDisposable {
|
||||
$registerAuthenticationProvider(id: string, displayName: string): void;
|
||||
$unregisterAuthenticationProvider(id: string): void;
|
||||
$onDidChangeSessions(providerId: string, event: modes.AuthenticationSessionsChangeEvent): void;
|
||||
$getSessionsPrompt(providerId: string, accountName: string, sessionId: string, providerName: string, extensionId: string, extensionName: string): Promise<boolean>;
|
||||
$getSessionsPrompt(providerId: string, accountName: string, providerName: string, extensionId: string, extensionName: string): Promise<boolean>;
|
||||
$loginPrompt(providerName: string, extensionName: string): Promise<boolean>;
|
||||
$setTrustedExtension(providerId: string, accountName: string, extensionId: string, extensionName: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface MainThreadConfigurationShape extends IDisposable {
|
||||
@@ -890,7 +889,7 @@ export interface MainThreadTunnelServiceShape extends IDisposable {
|
||||
export interface MainThreadTimelineShape extends IDisposable {
|
||||
$registerTimelineProvider(provider: TimelineProviderDescriptor): void;
|
||||
$unregisterTimelineProvider(source: string): void;
|
||||
$emitTimelineChangeEvent(e: TimelineChangeEvent): void;
|
||||
$emitTimelineChangeEvent(e: TimelineChangeEvent | undefined): void;
|
||||
}
|
||||
|
||||
// -- extension host
|
||||
|
||||
@@ -9,7 +9,6 @@ import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { IMainContext, MainContext, MainThreadAuthenticationShape, ExtHostAuthenticationShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { Disposable } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { IExtensionDescription, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { IExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
|
||||
|
||||
export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
private _proxy: MainThreadAuthenticationShape;
|
||||
@@ -21,8 +20,7 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
private _onDidChangeSessions = new Emitter<{ [providerId: string]: vscode.AuthenticationSessionsChangeEvent }>();
|
||||
readonly onDidChangeSessions: Event<{ [providerId: string]: vscode.AuthenticationSessionsChangeEvent }> = this._onDidChangeSessions.event;
|
||||
|
||||
constructor(mainContext: IMainContext,
|
||||
@IExtHostStorage private readonly storageService: IExtHostStorage) {
|
||||
constructor(mainContext: IMainContext) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadAuthentication);
|
||||
}
|
||||
|
||||
@@ -35,20 +33,6 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
return ids;
|
||||
}
|
||||
|
||||
private async hasNotBeenReadByOtherExtension(providerId: string, session: vscode.AuthenticationSession, extensionId: string): Promise<boolean> {
|
||||
const readerId = await this.storageService.getValue(true, `${providerId}-${session.accountName}-${session.id}`);
|
||||
if (!readerId) {
|
||||
await this.storageService.setValue(true, `${providerId}-${session.accountName}-${session.id}`, extensionId as any);
|
||||
return true;
|
||||
}
|
||||
|
||||
return readerId === extensionId;
|
||||
}
|
||||
|
||||
private async isMatchingSession(session: vscode.AuthenticationSession, scopes: string, providerId: string, extensionId: string): Promise<boolean> {
|
||||
return session.scopes.sort().join(' ') === scopes && (await this.hasNotBeenReadByOtherExtension(providerId, session, extensionId));
|
||||
}
|
||||
|
||||
async getSessions(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<readonly vscode.AuthenticationSession[]> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
if (!provider) {
|
||||
@@ -58,11 +42,8 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
|
||||
const orderedScopes = scopes.sort().join(' ');
|
||||
|
||||
const sessions = await provider.getSessions();
|
||||
const filteredSessions = await Promise.all(sessions.map(session => this.isMatchingSession(session, orderedScopes, providerId, extensionId)));
|
||||
|
||||
return sessions
|
||||
.filter((_, i) => { return filteredSessions[i]; })
|
||||
return (await provider.getSessions())
|
||||
.filter(session => session.scopes.sort().join(' ') === orderedScopes)
|
||||
.map(session => {
|
||||
return {
|
||||
id: session.id,
|
||||
@@ -72,7 +53,6 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
const isAllowed = await this._proxy.$getSessionsPrompt(
|
||||
provider.id,
|
||||
session.accountName,
|
||||
session.id,
|
||||
provider.displayName,
|
||||
extensionId,
|
||||
requestingExtension.displayName || requestingExtension.name);
|
||||
@@ -100,7 +80,6 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
}
|
||||
|
||||
const session = await provider.login(scopes);
|
||||
await this._proxy.$setTrustedExtension(provider.id, session.accountName, ExtensionIdentifier.toKey(requestingExtension.identifier), extensionName);
|
||||
return {
|
||||
id: session.id,
|
||||
accountName: session.accountName,
|
||||
@@ -109,7 +88,6 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
const isAllowed = await this._proxy.$getSessionsPrompt(
|
||||
provider.id,
|
||||
session.accountName,
|
||||
session.id,
|
||||
provider.displayName,
|
||||
ExtensionIdentifier.toKey(requestingExtension.identifier),
|
||||
requestingExtension.displayName || requestingExtension.name);
|
||||
|
||||
@@ -90,7 +90,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
|
||||
private readonly _storage: ExtHostStorage;
|
||||
private readonly _storagePath: IExtensionStoragePaths;
|
||||
private readonly _activator: ExtensionsActivator;
|
||||
private _extensionPathIndex: Promise<TernarySearchTree<IExtensionDescription>> | null;
|
||||
private _extensionPathIndex: Promise<TernarySearchTree<string, IExtensionDescription>> | null;
|
||||
|
||||
private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; };
|
||||
|
||||
@@ -236,7 +236,7 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
|
||||
}
|
||||
|
||||
// create trie to enable fast 'filename -> extension id' look up
|
||||
public getExtensionPathIndex(): Promise<TernarySearchTree<IExtensionDescription>> {
|
||||
public getExtensionPathIndex(): Promise<TernarySearchTree<string, IExtensionDescription>> {
|
||||
if (!this._extensionPathIndex) {
|
||||
const tree = TernarySearchTree.forPaths<IExtensionDescription>();
|
||||
const extensions = this._registry.getAllExtensionDescriptions().map(ext => {
|
||||
@@ -792,6 +792,6 @@ export interface IExtHostExtensionService extends AbstractExtHostExtensionServic
|
||||
deactivateAll(): Promise<void>;
|
||||
getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined;
|
||||
getExtensionRegistry(): Promise<ExtensionDescriptionRegistry>;
|
||||
getExtensionPathIndex(): Promise<TernarySearchTree<IExtensionDescription>>;
|
||||
getExtensionPathIndex(): Promise<TernarySearchTree<string, IExtensionDescription>>;
|
||||
registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable;
|
||||
}
|
||||
|
||||
@@ -184,11 +184,17 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||
...notebookDocumentMetadataDefaults,
|
||||
...newMetadata
|
||||
};
|
||||
if (this._metadataChangeListener) {
|
||||
this._metadataChangeListener.dispose();
|
||||
}
|
||||
|
||||
const observableMetadata = getObservable(newMetadata);
|
||||
this._metadata = observableMetadata.proxy;
|
||||
this._metadataChangeListener = this._register(observableMetadata.onDidChange(() => {
|
||||
this.updateMetadata();
|
||||
}));
|
||||
|
||||
this.updateMetadata();
|
||||
}
|
||||
|
||||
private _displayOrder: string[] = [];
|
||||
@@ -567,7 +573,7 @@ export class ExtHostNotebookOutputRenderer {
|
||||
return false;
|
||||
}
|
||||
|
||||
render(document: ExtHostNotebookDocument, output: vscode.CellOutput, mimeType: string): string {
|
||||
render(document: ExtHostNotebookDocument, output: vscode.CellDisplayOutput, mimeType: string): string {
|
||||
let html = this.renderer.render(document, output, mimeType);
|
||||
|
||||
return html;
|
||||
|
||||
@@ -95,7 +95,7 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory {
|
||||
|
||||
constructor(
|
||||
private readonly _apiFactory: IExtensionApiFactory,
|
||||
private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>,
|
||||
private readonly _extensionPaths: TernarySearchTree<string, IExtensionDescription>,
|
||||
private readonly _extensionRegistry: ExtensionDescriptionRegistry,
|
||||
private readonly _configProvider: ExtHostConfigProvider,
|
||||
private readonly _logService: ILogService,
|
||||
@@ -234,7 +234,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory {
|
||||
private _mainThreadTelemetry: MainThreadTelemetryShape;
|
||||
|
||||
constructor(
|
||||
private readonly _extensionPaths: TernarySearchTree<IExtensionDescription>,
|
||||
private readonly _extensionPaths: TernarySearchTree<string, IExtensionDescription>,
|
||||
private readonly _appUriScheme: string,
|
||||
@IExtHostRpcService rpcService: IExtHostRpcService,
|
||||
) {
|
||||
|
||||
@@ -645,6 +645,8 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
export class EnvironmentVariableCollection implements vscode.EnvironmentVariableCollection {
|
||||
readonly map: Map<string, vscode.EnvironmentVariableMutator> = new Map();
|
||||
|
||||
private _disposed = false;
|
||||
|
||||
protected readonly _onDidChangeCollection: Emitter<void> = new Emitter<void>();
|
||||
get onDidChangeCollection(): Event<void> { return this._onDidChangeCollection && this._onDidChangeCollection.event; }
|
||||
|
||||
@@ -656,18 +658,22 @@ export class EnvironmentVariableCollection implements vscode.EnvironmentVariable
|
||||
}
|
||||
|
||||
get size(): number {
|
||||
this._checkDisposed();
|
||||
return this.map.size;
|
||||
}
|
||||
|
||||
replace(variable: string, value: string): void {
|
||||
this._checkDisposed();
|
||||
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Replace });
|
||||
}
|
||||
|
||||
append(variable: string, value: string): void {
|
||||
this._checkDisposed();
|
||||
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Append });
|
||||
}
|
||||
|
||||
prepend(variable: string, value: string): void {
|
||||
this._checkDisposed();
|
||||
this._setIfDiffers(variable, { value, type: EnvironmentVariableMutatorType.Prepend });
|
||||
}
|
||||
|
||||
@@ -680,26 +686,39 @@ export class EnvironmentVariableCollection implements vscode.EnvironmentVariable
|
||||
}
|
||||
|
||||
get(variable: string): vscode.EnvironmentVariableMutator | undefined {
|
||||
this._checkDisposed();
|
||||
return this.map.get(variable);
|
||||
}
|
||||
|
||||
forEach(callback: (variable: string, mutator: vscode.EnvironmentVariableMutator, collection: vscode.EnvironmentVariableCollection) => any, thisArg?: any): void {
|
||||
this._checkDisposed();
|
||||
this.map.forEach((value, key) => callback(key, value, this));
|
||||
}
|
||||
|
||||
delete(variable: string): void {
|
||||
this._checkDisposed();
|
||||
this.map.delete(variable);
|
||||
this._onDidChangeCollection.fire();
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this._checkDisposed();
|
||||
this.map.clear();
|
||||
this._onDidChangeCollection.fire();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.map.clear();
|
||||
this._onDidChangeCollection.fire();
|
||||
if (!this._disposed) {
|
||||
this._disposed = true;
|
||||
this.map.clear();
|
||||
this._onDidChangeCollection.fire();
|
||||
}
|
||||
}
|
||||
|
||||
protected _checkDisposed() {
|
||||
if (this._disposed) {
|
||||
throw new Error('EnvironmentVariableCollection has already been disposed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ export class ExtHostTimeline implements IExtHostTimeline {
|
||||
|
||||
let disposable: IDisposable | undefined;
|
||||
if (provider.onDidChange) {
|
||||
disposable = provider.onDidChange(e => this._proxy.$emitTimelineChangeEvent({ ...e, id: provider.id }), this);
|
||||
disposable = provider.onDidChange(e => this._proxy.$emitTimelineChangeEvent({ uri: undefined, reset: true, ...e, id: provider.id }), this);
|
||||
}
|
||||
|
||||
const itemsBySourceAndUriMap = this._itemsBySourceAndUriMap;
|
||||
|
||||
@@ -55,12 +55,12 @@ function fromLittleEndianBuffer(buff: VSBuffer): Uint32Array {
|
||||
reverseEndianness(uint8Arr);
|
||||
}
|
||||
if (uint8Arr.byteOffset % 4 === 0) {
|
||||
return new Uint32Array(uint8Arr.buffer, uint8Arr.byteOffset);
|
||||
return new Uint32Array(uint8Arr.buffer, uint8Arr.byteOffset, uint8Arr.length / 4);
|
||||
} else {
|
||||
// unaligned memory access doesn't work on all platforms
|
||||
const data = new Uint8Array(uint8Arr.byteLength);
|
||||
data.set(uint8Arr);
|
||||
return new Uint32Array(data.buffer, data.byteOffset);
|
||||
return new Uint32Array(data.buffer, data.byteOffset, data.length / 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user