Skip to content

Commit 9e94aaf

Browse files
committed
WIP
1 parent 6cd4792 commit 9e94aaf

File tree

5 files changed

+149
-61
lines changed

5 files changed

+149
-61
lines changed

package.json

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@
8383
"intersystems-community_servermanager": [
8484
{
8585
"id": "intersystems-community_servermanager",
86-
"name": "Server Manager",
87-
"contextualTitle": "InterSystems Server Manager",
86+
"name": "Servers",
87+
"contextualTitle": "InterSystems Tools",
8888
"icon": "images/serverManager.svg"
8989
}
9090
]
@@ -237,17 +237,23 @@
237237
"icon": "$(star-empty)"
238238
},
239239
{
240-
"command": "intersystems-community.servermanager.openManagementPortalExternal",
240+
"command": "intersystems-community.servermanager.openPortalExternal",
241241
"category": "InterSystems Server Manager",
242242
"title": "Open Management Portal in External Browser",
243243
"icon": "$(link-external)"
244244
},
245245
{
246-
"command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser",
246+
"command": "intersystems-community.servermanager.openPortalTab",
247247
"category": "InterSystems Server Manager",
248-
"title": "Open Management Portal in Simple Browser Tab",
248+
"title": "Open Management Portal in Tab",
249249
"icon": "$(tools)"
250250
},
251+
{
252+
"command": "intersystems-community.servermanager.editSettings",
253+
"category": "InterSystems Server Manager",
254+
"title": "Edit Settings",
255+
"icon": "$(edit)"
256+
},
251257
{
252258
"command": "intersystems-community.servermanager.storePassword",
253259
"category": "InterSystems Server Manager",
@@ -344,11 +350,11 @@
344350
"when": "false"
345351
},
346352
{
347-
"command": "intersystems-community.servermanager.openManagementPortalExternal",
353+
"command": "intersystems-community.servermanager.openPortalExternal",
348354
"when": "false"
349355
},
350356
{
351-
"command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser",
357+
"command": "intersystems-community.servermanager.openPortalTab",
352358
"when": "false"
353359
}
354360
],
@@ -363,9 +369,15 @@
363369
"when": "view == intersystems-community_servermanager",
364370
"group": "navigation@20"
365371
},
372+
{
373+
"command": "intersystems-community.servermanager.editSettings",
374+
"when": "view == intersystems-community_servermanager",
375+
"group": "1_edit"
376+
},
366377
{
367378
"command": "intersystems-community.servermanager.importServers",
368-
"when": "view == intersystems-community_servermanager && isWindows"
379+
"when": "view == intersystems-community_servermanager && isWindows",
380+
"group": "2_import"
369381
}
370382
],
371383
"view/item/context": [
@@ -380,29 +392,34 @@
380392
"group": "inline@10"
381393
},
382394
{
383-
"command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser",
395+
"command": "intersystems-community.servermanager.openPortalTab",
384396
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
385397
"group": "inline@80"
386398
},
387399
{
388-
"command": "intersystems-community.servermanager.openManagementPortalExternal",
400+
"command": "intersystems-community.servermanager.openPortalExternal",
389401
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
390402
"group": "inline@90"
391403
},
392404
{
393405
"submenu": "intersystems-community.servermanager.iconColor",
394406
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
395-
"group": "color"
407+
"group": "1_edit@10"
408+
},
409+
{
410+
"command": "intersystems-community.servermanager.editSettings",
411+
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
412+
"group": "1_edit@20"
396413
},
397414
{
398415
"command": "intersystems-community.servermanager.storePassword",
399416
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
400-
"group": "password@10"
417+
"group": "2_password@10"
401418
},
402419
{
403420
"command": "intersystems-community.servermanager.clearPassword",
404421
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
405-
"group": "password@20"
422+
"group": "2_password@20"
406423
}
407424
]
408425
}

src/api/getServerSpec.ts

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@ interface CredentialSet {
99

1010
export let credentialCache = new Map<string, CredentialSet>();
1111

12-
export async function getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false): Promise<ServerSpec | undefined> {
12+
/**
13+
* Get a server specification.
14+
*
15+
* @param name The name.
16+
* @param scope The settings scope to use for the lookup.
17+
* @param flushCredentialCache Flush the session's cache of credentials obtained from keystore and/or user prompting.
18+
* @param noCredentials Set username and password as undefined; do not fetch credentials from anywhere.
19+
* @returns Server specification or undefined.
20+
*/
21+
export async function getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false, noCredentials: boolean = false): Promise<ServerSpec | undefined> {
1322
if (flushCredentialCache) {
1423
credentialCache[name] = undefined;
1524
}
@@ -25,9 +34,15 @@ export async function getServerSpec(name: string, scope?: vscode.ConfigurationSc
2534
server.webServer.scheme = server.webServer.scheme || 'http';
2635
server.webServer.pathPrefix = server.webServer.pathPrefix || '';
2736

28-
// Obtain a username (including blank to try connecting anonymously)
29-
if (!server.username) {
30-
await vscode.window
37+
if (noCredentials) {
38+
server.username = undefined;
39+
server.password = undefined;
40+
}
41+
else {
42+
43+
// Obtain a username (including blank to try connecting anonymously)
44+
if (!server.username) {
45+
await vscode.window
3146
.showInputBox({
3247
placeHolder: `Username to connect to InterSystems server '${name}' as`,
3348
prompt: 'Leave empty to attempt unauthenticated access',
@@ -40,34 +55,34 @@ export async function getServerSpec(name: string, scope?: vscode.ConfigurationSc
4055
return undefined;
4156
}
4257
});
43-
if (!server.username) {
44-
server.username = '';
45-
server.password = '';
58+
if (!server.username) {
59+
server.username = '';
60+
server.password = '';
61+
}
4662
}
47-
}
48-
49-
// Obtain password from session cache or keychain unless trying to connect anonymously
50-
if (server.username && !server.password) {
51-
if (credentialCache[name] && credentialCache[name].username === server.username) {
52-
server.password = credentialCache[name].password;
53-
} else {
54-
const keychain = new Keychain(name);
55-
const password = await keychain.getPassword().then(result => {
56-
if (typeof result === 'string') {
57-
return result;
58-
} else {
59-
return undefined;
63+
64+
// Obtain password from session cache or keychain unless trying to connect anonymously
65+
if (server.username && !server.password) {
66+
if (credentialCache[name] && credentialCache[name].username === server.username) {
67+
server.password = credentialCache[name].password;
68+
} else {
69+
const keychain = new Keychain(name);
70+
const password = await keychain.getPassword().then(result => {
71+
if (typeof result === 'string') {
72+
return result;
73+
} else {
74+
return undefined;
75+
}
76+
});
77+
if (password) {
78+
server.password = password;
79+
credentialCache[name] = {username: server.username, password: password};
6080
}
61-
});
62-
if (password) {
63-
server.password = password;
64-
credentialCache[name] = {username: server.username, password: password};
6581
}
82+
6683
}
67-
68-
}
69-
if (server.username && !server.password) {
70-
await vscode.window
84+
if (server.username && !server.password) {
85+
await vscode.window
7186
.showInputBox({
7287
password: true,
7388
placeHolder: `Password for user '${server.username}' on InterSystems server '${name}'`,
@@ -84,6 +99,7 @@ export async function getServerSpec(name: string, scope?: vscode.ConfigurationSc
8499
server = undefined;
85100
}
86101
})
102+
}
87103
}
88104
return server;
89105
}

src/extension.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function activate(context: vscode.ExtensionContext) {
7373
})
7474
);
7575
context.subscriptions.push(
76-
vscode.commands.registerCommand(`${extensionId}.openManagementPortalExternal`, (server?: ServerTreeItem) => {
76+
vscode.commands.registerCommand(`${extensionId}.openPortalExternal`, (server?: ServerTreeItem) => {
7777
if (server?.contextValue?.match(/\.server\./) && server.name) {
7878
getPortalUriWithCredentials(server.name).then((uriWithCredentials) => {
7979
if (uriWithCredentials) {
@@ -84,7 +84,7 @@ export function activate(context: vscode.ExtensionContext) {
8484
})
8585
);
8686
context.subscriptions.push(
87-
vscode.commands.registerCommand(`${extensionId}.openManagementPortalInSimpleBrowser`, (server?: ServerTreeItem) => {
87+
vscode.commands.registerCommand(`${extensionId}.openPortalTab`, (server?: ServerTreeItem) => {
8888
if (server?.contextValue?.match(/\.server\./) && server.name) {
8989
getPortalUriWithCredentials(server.name).then((uriWithCredentials) => {
9090
if (uriWithCredentials) {
@@ -97,6 +97,12 @@ export function activate(context: vscode.ExtensionContext) {
9797
});
9898
}
9999
})
100+
);
101+
context.subscriptions.push(
102+
vscode.commands.registerCommand(`${extensionId}.editSettings`, (server?: ServerTreeItem) => {
103+
// Until there's a dedicated settings editor the best we can do is jump to the right section
104+
vscode.commands.executeCommand('workbench.action.openSettings', `@ext:${extensionId}`);
105+
})
100106
);
101107
context.subscriptions.push(
102108
vscode.commands.registerCommand(`${extensionId}.storePassword`, (server?: ServerTreeItem) => {
@@ -201,8 +207,8 @@ export function activate(context: vscode.ExtensionContext) {
201207
return getServerSummary(name, scope);
202208
},
203209

204-
async getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false, options?: { hideFromRecents?: boolean}): Promise<ServerSpec | undefined> {
205-
const spec = await getServerSpec(name, scope, flushCredentialCache);
210+
async getServerSpec(name: string, scope?: vscode.ConfigurationScope, flushCredentialCache: boolean = false, options?: { hideFromRecents?: boolean, noCredentials?: boolean}): Promise<ServerSpec | undefined> {
211+
const spec = await getServerSpec(name, scope, flushCredentialCache, options?.noCredentials);
206212
if (spec && !options?.hideFromRecents) {
207213
await view.addToRecents(name);
208214
}

src/makeRESTRequest.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export interface AtelierRESTEndpoint {
2626
* @param endpoint Optional endpoint object. If omitted the request will be to /api/atelier/
2727
* @param data Optional request data. Usually passed for POST requests.
2828
*/
29-
export async function makeRESTRequest(method: "GET"|"POST", server: ServerSpec, endpoint?: AtelierRESTEndpoint, data?: any): Promise<AxiosResponse | undefined> {
29+
export async function makeRESTRequest(method: "HEAD"|"GET"|"POST", server: ServerSpec, endpoint?: AtelierRESTEndpoint, data?: any): Promise<AxiosResponse | undefined> {
3030

3131
// Build the URL
3232
var url = server.webServer.scheme + "://" + server.webServer.host + ":" + String(server.webServer.port);
@@ -59,7 +59,7 @@ export interface AtelierRESTEndpoint {
5959
}
6060
}
6161
);
62-
if (respdata.status === 401) {
62+
if (respdata.status === 401 && typeof server.username !== 'undefined' && typeof server.password !== 'undefined') {
6363
// Either we had no cookies or they expired, so resend the request with basic auth
6464

6565
respdata = await axios.request(
@@ -71,8 +71,8 @@ export interface AtelierRESTEndpoint {
7171
'Content-Type': 'application/json'
7272
},
7373
auth: {
74-
username: server.username || "",
75-
password: server.password || ""
74+
username: server.username,
75+
password: server.password
7676
},
7777
withCredentials: true,
7878
jar: cookieJar
@@ -93,16 +93,16 @@ export interface AtelierRESTEndpoint {
9393
}
9494
}
9595
);
96-
if (respdata.status === 401) {
96+
if (respdata.status === 401 && typeof server.username !== 'undefined' && typeof server.password !== 'undefined') {
9797
// Either we had no cookies or they expired, so resend the request with basic auth
9898

9999
respdata = await axios.request(
100100
{
101101
method: method,
102102
url: url,
103103
auth: {
104-
username: server.username || "",
105-
password: server.password || ""
104+
username: server.username,
105+
password: server.password
106106
},
107107
withCredentials: true,
108108
jar: cookieJar

0 commit comments

Comments
 (0)