Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
gjsjohnmurray committed Apr 9, 2021
1 parent 61396c0 commit 7c4b697
Show file tree
Hide file tree
Showing 8 changed files with 303 additions and 15 deletions.
14 changes: 14 additions & 0 deletions images/serverManager.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions images/toolsContainer.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 76 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,32 @@
},
"main": "./out/extension",
"activationEvents": [
"onView:intersystems-community_servermanager",
"onCommand:intersystems-community.servermanager.addServer",
"onCommand:intersystems-community.servermanager.storePassword",
"onCommand:intersystems-community.servermanager.clearPassword",
"onCommand:intersystems-community.servermanager.importServers"
],
"contributes": {
"viewsContainers": {
"activitybar": [
{
"id": "intersystems-community_servermanager",
"title": "InterSystems Tools",
"icon": "images/toolsContainer.svg"
}
]
},
"views": {
"intersystems-community_servermanager": [
{
"id": "intersystems-community_servermanager",
"name": "Server Manager",
"contextualTitle": "InterSystems Server Manager",
"icon": "images/serverManager.svg"
}
]
},
"configuration": {
"title": "InterSystems Server Manager",
"properties": {
Expand Down Expand Up @@ -187,10 +208,28 @@
}
},
"commands": [
{
"command": "intersystems-community.servermanager.addServer",
"category": "InterSystems Server Manager",
"title": "Add Server",
"icon": "$(add)"
},
{
"command": "intersystems-community.servermanager.openManagementPortalExternal",
"category": "InterSystems Server Manager",
"title": "Open Management Portal in External Browser",
"icon": "$(link-external)"
},
{
"command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser",
"category": "InterSystems Server Manager",
"title": "Open Management Portal in Simple Browser Tab"
},
{
"command": "intersystems-community.servermanager.storePassword",
"category": "InterSystems Server Manager",
"title": "Store Password in Keychain"
"title": "Store Password in Keychain",
"icon": "$(key)"
},
{
"command": "intersystems-community.servermanager.clearPassword",
Expand All @@ -208,6 +247,42 @@
{
"command": "intersystems-community.servermanager.importServers",
"when": "isWindows"
},
{
"command": "intersystems-community.servermanager.openManagementPortalExternal",
"when": "false"
},
{
"command": "intersystems-community.servermanager.openManagementPortalInSimpleBrowser",
"when": "false"
}
],
"view/title": [
{
"command": "intersystems-community.servermanager.addServer",
"when": "view == intersystems-community_servermanager",
"group": "navigation"
},
{
"command": "intersystems-community.servermanager.importServers",
"when": "view == intersystems-community_servermanager && isWindows"
}
],
"view/item/context": [
{
"command": "intersystems-community.servermanager.openManagementPortalExternal",
"when": "view == intersystems-community_servermanager && viewItem == server",
"group": "inline"
},
{
"command": "intersystems-community.servermanager.storePassword",
"when": "view == intersystems-community_servermanager && viewItem == server",
"group": "password@10"
},
{
"command": "intersystems-community.servermanager.clearPassword",
"when": "view == intersystems-community_servermanager && viewItem == server",
"group": "password@20"
}
]
}
Expand Down
29 changes: 29 additions & 0 deletions src/api/getPortalUriWithCredentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as vscode from 'vscode';
import { Uri } from 'vscode';
import { getServerSpec } from './getServerSpec';

export async function getPortalUriWithCredentials(name: string, scope?: vscode.ConfigurationScope): Promise<Uri | undefined> {
return getServerSpec(name, scope).then((spec) => {
if (typeof spec !== 'undefined') {
const webServer = spec.webServer;
let queryString = '';

// At this point we don't know if the target is IRIS or Cache, so add credentials in both formats.
// Deliberately put password before username, otherwise it is visible in VS Code's confirmation dialog triggered target domain
// hasn't been set as trusted. Likewise, deliberately put IRIS* after Cache*
if (spec?.password) {
const passwordEncoded = encodeURIComponent(spec.password);
queryString += `&CachePassword=${passwordEncoded}&IRISPassword=${passwordEncoded}`;
}
if (spec?.username) {
const usernameEncoded = encodeURIComponent(spec.username);
queryString += `&CacheUsername=${usernameEncoded}&IRISUsername=${usernameEncoded}`;
}

// Push the credentials offscreen
queryString = '_=' + ' '.padStart(500,' ') + queryString;

return vscode.Uri.parse(`${webServer.scheme}://${webServer.host}:${webServer.port}${webServer.pathPrefix}/csp/sys/UtilHome.csp?${queryString}`, true);
}
})
}
2 changes: 1 addition & 1 deletion src/api/getServerSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export async function getServerSpec(name: string, scope?: vscode.ConfigurationSc
// Obtain password from session cache or keychain unless trying to connect anonymously
if (server.username && !server.password) {
if (credentialCache[name] && credentialCache[name].username === server.username) {
server.password = credentialCache[name];
server.password = credentialCache[name].password;
} else {
const keychain = new Keychain(name);
const password = await keychain.getPassword().then(result => {
Expand Down
16 changes: 12 additions & 4 deletions src/commands/managePasswords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ import * as vscode from 'vscode';
import { extensionId } from '../extension';
import { Keychain } from '../keychain';
import { credentialCache } from '../api/getServerSpec';
import { getServerNames } from '../api/getServerNames';
import { ServerTreeItem } from '../ui/serverManagerView';

export async function storePassword(): Promise<string> {
const name = await commonPickServer({matchOnDetail: true});
export async function storePassword(treeItem?: ServerTreeItem): Promise<string> {
if (treeItem && !getServerNames().some((value) => value.name === treeItem?.label)) {
treeItem = undefined;
}
const name = treeItem?.label || await commonPickServer({matchOnDetail: true});
let reply = '';
if (name) {
await vscode.window
Expand All @@ -30,9 +35,12 @@ export async function storePassword(): Promise<string> {
return reply;
}

export async function clearPassword(): Promise<string> {
export async function clearPassword(treeItem?: ServerTreeItem): Promise<string> {
if (treeItem && !getServerNames().some((value) => value.name === treeItem?.label)) {
treeItem = undefined;
}
let reply = '';
const name = await commonPickServer({matchOnDetail: true});
const name = treeItem?.label || await commonPickServer({matchOnDetail: true});
if (name) {
credentialCache[name] = undefined;
const keychain = new Keychain(name);
Expand Down
55 changes: 46 additions & 9 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { getServerNames } from './api/getServerNames';
import { getServerSpec } from './api/getServerSpec';
import { storePassword, clearPassword } from './commands/managePasswords';
import { importFromRegistry } from './commands/importFromRegistry';
import { ServerManagerView, ServerTreeItem } from './ui/serverManagerView';
import { addServer } from './api/addServer';
import { getPortalUriWithCredentials } from './api/getPortalUriWithCredentials';

export interface ServerName {
name: string,
Expand Down Expand Up @@ -42,8 +45,39 @@ export function activate(context: vscode.ExtensionContext) {

// Register the commands
context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.storePassword`, () => {
storePassword()
vscode.commands.registerCommand(`${extensionId}.addServer`, () => {
addServer();
})
);
context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.openManagementPortalExternal`, (server?: ServerTreeItem) => {
if (server?.contextValue === 'server' && server.label) {
getPortalUriWithCredentials(server.label).then((uriWithCredentials) => {
if (uriWithCredentials) {
vscode.env.openExternal(uriWithCredentials);
}
});
}
})
);
context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.openManagementPortalInSimpleBrowser`, (server?: ServerTreeItem) => {
if (server?.contextValue === 'server' && server.label) {
getPortalUriWithCredentials(server.label).then((uriWithCredentials) => {
if (uriWithCredentials) {
//vscode.commands.executeCommand('simpleBrowser.api.open', uriWithCredentials);
//
// It is essential to pass skipEncoding=true when converting the uri to a string,
// otherwise the encoding done within Simple Browser / webview causes double-encoding of the querystring.
vscode.commands.executeCommand('simpleBrowser.show', uriWithCredentials.toString(true));
}
});
}
})
);
context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.storePassword`, (server?: ServerTreeItem) => {
storePassword(server)
.then((name) => {
if (name && name.length > 0) {
_onDidChangePassword.fire(name);
Expand All @@ -52,20 +86,23 @@ export function activate(context: vscode.ExtensionContext) {
})
);
context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.clearPassword`, () => {
clearPassword()
vscode.commands.registerCommand(`${extensionId}.clearPassword`, (server?: ServerTreeItem) => {
clearPassword(server)
.then((name) => {
if (name && name.length > 0) {
_onDidChangePassword.fire(name);
}
});
})
);
context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.importServers`, () => {
importFromRegistry();
})
);
context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.importServers`, () => {
importFromRegistry();
})
);

// Server Manager View
new ServerManagerView(context);

let api = {
async pickServer(scope?: vscode.ConfigurationScope, options: vscode.QuickPickOptions = {}): Promise<string | undefined> {
Expand Down
Loading

0 comments on commit 7c4b697

Please sign in to comment.