提交 6889ed3a 编写于 作者: A Alex Ross

Notification for elevating when using privileged port from openTunnel

上级 25a9fcdb
...@@ -3,22 +3,26 @@ ...@@ -3,22 +3,26 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { MainThreadTunnelServiceShape, IExtHostContext, MainContext, ExtHostContext, ExtHostTunnelServiceShape } from 'vs/workbench/api/common/extHost.protocol'; import { MainThreadTunnelServiceShape, IExtHostContext, MainContext, ExtHostContext, ExtHostTunnelServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService'; import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { CandidatePort, IRemoteExplorerService, makeAddress } from 'vs/workbench/services/remote/common/remoteExplorerService'; import { CandidatePort, IRemoteExplorerService, makeAddress } from 'vs/workbench/services/remote/common/remoteExplorerService';
import { ITunnelProvider, ITunnelService, TunnelCreationOptions, TunnelProviderFeatures, TunnelOptions } from 'vs/platform/remote/common/tunnel'; import { ITunnelProvider, ITunnelService, TunnelCreationOptions, TunnelProviderFeatures, TunnelOptions, RemoteTunnel, isPortPrivileged } from 'vs/platform/remote/common/tunnel';
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import type { TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver'; import type { TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
@extHostNamedCustomer(MainContext.MainThreadTunnelService) @extHostNamedCustomer(MainContext.MainThreadTunnelService)
export class MainThreadTunnelService extends Disposable implements MainThreadTunnelServiceShape { export class MainThreadTunnelService extends Disposable implements MainThreadTunnelServiceShape {
private readonly _proxy: ExtHostTunnelServiceShape; private readonly _proxy: ExtHostTunnelServiceShape;
private elevateionRetry: boolean = false;
constructor( constructor(
extHostContext: IExtHostContext, extHostContext: IExtHostContext,
@IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService, @IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService,
@ITunnelService private readonly tunnelService: ITunnelService @ITunnelService private readonly tunnelService: ITunnelService,
@INotificationService private readonly notificationService: INotificationService
) { ) {
super(); super();
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTunnelService); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTunnelService);
...@@ -35,13 +39,35 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun ...@@ -35,13 +39,35 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
} }
async $openTunnel(tunnelOptions: TunnelOptions, source: string): Promise<TunnelDto | undefined> { async $openTunnel(tunnelOptions: TunnelOptions, source: string): Promise<TunnelDto | undefined> {
const tunnel = await this.remoteExplorerService.forward(tunnelOptions.remoteAddress, tunnelOptions.localAddressPort, tunnelOptions.label, source, true); const tunnel = await this.remoteExplorerService.forward(tunnelOptions.remoteAddress, tunnelOptions.localAddressPort, tunnelOptions.label, source, false);
if (tunnel) { if (tunnel) {
if (!this.elevateionRetry
&& (tunnelOptions.localAddressPort !== undefined)
&& (tunnel.tunnelLocalPort !== undefined)
&& isPortPrivileged(tunnelOptions.localAddressPort)
&& (tunnel.tunnelLocalPort !== tunnelOptions.localAddressPort)) {
this.elevationPrompt(tunnelOptions, tunnel, source);
}
return TunnelDto.fromServiceTunnel(tunnel); return TunnelDto.fromServiceTunnel(tunnel);
} }
return undefined; return undefined;
} }
private async elevationPrompt(tunnelOptions: TunnelOptions, tunnel: RemoteTunnel, source: string) {
return this.notificationService.prompt(Severity.Info,
nls.localize('remote.tunnel.openTunnel', "The extension {0} has forwarded port {1}. You'll need to run as superuser to use port {2} locally.", source, tunnelOptions.remoteAddress.port, tunnelOptions.localAddressPort),
[{
label: nls.localize('remote.tunnelsView.elevationButton', "Use Port {0} as Sudo...", tunnel.tunnelRemotePort),
run: async () => {
this.elevateionRetry = true;
await this.remoteExplorerService.close({ host: tunnel.tunnelRemoteHost, port: tunnel.tunnelRemotePort });
await this.remoteExplorerService.forward(tunnelOptions.remoteAddress, tunnelOptions.localAddressPort, tunnelOptions.label, source, true);
this.elevateionRetry = false;
}
}]);
}
async $closeTunnel(remote: { host: string, port: number }): Promise<void> { async $closeTunnel(remote: { host: string, port: number }): Promise<void> {
return this.remoteExplorerService.close(remote); return this.remoteExplorerService.close(remote);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册