Move config calculation to a separate method

pull/64/head
Kelvin Schoofs 7 years ago
parent 06ccecfec7
commit 69b16b9d8b

@ -4,7 +4,6 @@ import { parse as parseJsonc, ParseError } from 'jsonc-parser';
import * as path from 'path'; import * as path from 'path';
import { Client, ConnectConfig } from 'ssh2'; import { Client, ConnectConfig } from 'ssh2';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as proxy from './proxy'; import * as proxy from './proxy';
import { getSession as getPuttySession } from './putty'; import { getSession as getPuttySession } from './putty';
import SSHFileSystem, { EMPTY_FILE_SYSTEM } from './sshFileSystem'; import SSHFileSystem, { EMPTY_FILE_SYSTEM } from './sshFileSystem';
@ -168,31 +167,20 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
if (name === '<config>') return; if (name === '<config>') return;
this.updateConfig(name, config); this.updateConfig(name, config);
} }
public async createFileSystem(name: string, config?: FileSystemConfig): Promise<SSHFileSystem> { public async calculateActualConfig(config: FileSystemConfig): Promise<FileSystemConfig | null> {
if (name === '<config>') return this.configFileSystem; config = { ...config };
const existing = this.fileSystems.find(fs => fs.authority === name);
if (existing) return existing;
let promise = this.creatingFileSystems[name];
if (promise) return promise;
// config = config || this.memento.get(`fs.config.${name}`);
config = config || this.loadConfigs().find(c => c.name === name);
promise = catchingPromise<SSHFileSystem>(async (resolve, reject) => {
if (!config) {
throw new Error(`A SSH filesystem with the name '${name}' doesn't exist`);
}
this.registerFileSystem(name, { ...config });
if (config.putty) { if (config.putty) {
let nameOnly = true; let nameOnly = true;
if (config.putty === true) { if (config.putty === true) {
if (!config.host) return reject(new Error(`'putty' was true but 'host' is empty/missing`)); if (!config.host) throw new Error(`'putty' was true but 'host' is empty/missing`);
config.putty = config.host; config.putty = config.host;
nameOnly = false; nameOnly = false;
} else { } else {
config.putty = replaceVariables(config.putty); config.putty = replaceVariables(config.putty);
} }
const session = await getPuttySession(config.putty, config.host, config.username, nameOnly); const session = await getPuttySession(config.putty, config.host, config.username, nameOnly);
if (!session) return reject(new Error(`Couldn't find the requested PuTTY session`)); if (!session) throw new Error(`Couldn't find the requested PuTTY session`);
if (session.protocol !== 'ssh') return reject(new Error(`The requested PuTTY session isn't a SSH session`)); if (session.protocol !== 'ssh') throw new Error(`The requested PuTTY session isn't a SSH session`);
config.username = replaceVariables(config.username) || session.username; config.username = replaceVariables(config.username) || session.username;
config.host = replaceVariables(config.host) || session.hostname; config.host = replaceVariables(config.host) || session.hostname;
const port = replaceVariables((config.port || '') + '') || session.portnumber; const port = replaceVariables((config.port || '') + '') || session.portnumber;
@ -200,7 +188,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
config.agent = replaceVariables(config.agent) || (session.tryagent ? 'pageant' : undefined); config.agent = replaceVariables(config.agent) || (session.tryagent ? 'pageant' : undefined);
if (session.usernamefromenvironment) { if (session.usernamefromenvironment) {
config.username = process.env.USERNAME; config.username = process.env.USERNAME;
if (!config.username) return reject(new Error(`Trying to use the system username, but process.env.USERNAME is missing`)); if (!config.username) throw new Error(`Trying to use the system username, but process.env.USERNAME is missing`);
} }
const keyPath = replaceVariables(config.privateKeyPath) || (!config.agent && session.publickeyfile); const keyPath = replaceVariables(config.privateKeyPath) || (!config.agent && session.publickeyfile);
if (keyPath) { if (keyPath) {
@ -208,7 +196,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
const key = await toPromise<Buffer>(cb => readFile(keyPath, cb)); const key = await toPromise<Buffer>(cb => readFile(keyPath, cb));
config.privateKey = key; config.privateKey = key;
} catch (e) { } catch (e) {
return reject(new Error(`Error while reading the keyfile at:\n${keyPath}`)); throw new Error(`Error while reading the keyfile at:\n${keyPath}`);
} }
} }
switch (session.proxymethod) { switch (session.proxymethod) {
@ -216,7 +204,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
break; break;
case 1: case 1:
case 2: case 2:
if (!session.proxyhost) return reject(new Error(`Proxymethod is SOCKS 4/5 but 'proxyhost' is missing`)); if (!session.proxyhost) throw new Error(`Proxymethod is SOCKS 4/5 but 'proxyhost' is missing`);
config.proxy = { config.proxy = {
host: session.proxyhost, host: session.proxyhost,
port: session.proxyport, port: session.proxyport,
@ -224,7 +212,7 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
}; };
break; break;
default: default:
return reject(new Error(`The requested PuTTY session uses an unsupported proxy method`)); throw new Error(`The requested PuTTY session uses an unsupported proxy method`);
} }
} }
if (!config.username || (config.username as any) === true) { if (!config.username || (config.username as any) === true) {
@ -254,12 +242,29 @@ export class Manager implements vscode.FileSystemProvider, vscode.TreeDataProvid
} else { } else {
const answer = await vscode.window.showWarningMessage(`The field 'passphrase' was set to true, but no key was provided`, 'Configure', 'Ignore'); const answer = await vscode.window.showWarningMessage(`The field 'passphrase' was set to true, but no key was provided`, 'Configure', 'Ignore');
if (answer === 'Configure') { if (answer === 'Configure') {
this.commandConfigure(name); this.commandConfigure(config.name);
return reject(null); return null;
} }
} }
} }
if (config.password) config.agent = undefined; if (config.password) config.agent = undefined;
return config;
}
public async createFileSystem(name: string, config?: FileSystemConfig): Promise<SSHFileSystem> {
if (name === '<config>') return this.configFileSystem;
const existing = this.fileSystems.find(fs => fs.authority === name);
if (existing) return existing;
let promise = this.creatingFileSystems[name];
if (promise) return promise;
// config = config || this.memento.get(`fs.config.${name}`);
config = config || this.loadConfigs().find(c => c.name === name);
promise = catchingPromise<SSHFileSystem>(async (resolve, reject) => {
if (!config) {
throw new Error(`A SSH filesystem with the name '${name}' doesn't exist`);
}
this.registerFileSystem(name, { ...config });
config = (await this.calculateActualConfig(config))!;
if (config == null) return reject(null);
switch (config.proxy && config.proxy.type) { switch (config.proxy && config.proxy.type) {
case null: case null:
case undefined: case undefined:

Loading…
Cancel
Save