Skip to content

Commit

Permalink
Merge pull request #185 from gjsjohnmurray/portal-explorer
Browse files Browse the repository at this point in the history
Add shortcut to Explorer section of Portal at namespace level
  • Loading branch information
gjsjohnmurray authored Aug 9, 2023
2 parents f6b7904 + cc512ea commit 20d3f62
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 8 deletions.
14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,11 @@
"title": "Open Management Portal in Tab",
"icon": "$(tools)"
},
{
"command": "intersystems-community.servermanager.openPortalExplorerExternal",
"title": "Open Management Portal Here in External Browser",
"icon": "$(link-external)"
},
{
"command": "intersystems-community.servermanager.retryServer",
"title": "Refresh",
Expand Down Expand Up @@ -445,6 +450,10 @@
"command": "intersystems-community.servermanager.openPortalTab",
"when": "false"
},
{
"command": "intersystems-community.servermanager.openPortalExplorerExternal",
"when": "false"
},
{
"command": "intersystems-community.servermanager.retryServer",
"when": "false"
Expand Down Expand Up @@ -595,6 +604,11 @@
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
"group": "inline@90"
},
{
"command": "intersystems-community.servermanager.openPortalExplorerExternal",
"when": "view == intersystems-community_servermanager && viewItem =~ /namespace$/",
"group": "inline@80"
},
{
"command": "intersystems-community.servermanager.retryServer",
"when": "view == intersystems-community_servermanager && viewItem =~ /\\.server\\./",
Expand Down
40 changes: 34 additions & 6 deletions src/api/getPortalUriWithToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ export enum BrowserTarget {

const allTokens = [new Map<string, string>(), new Map<string, string>()];

const simpleBrowserCompatible = new Map<string, boolean>();

export async function getPortalUriWithToken(
target: BrowserTarget,
name: string,
page = "/csp/sys/UtilHome.csp",
namespace = "%SYS",
scope?: vscode.ConfigurationScope,
): Promise<Uri | undefined> {

const PORTAL_HOME = "/csp/sys/UtilHome.csp";

// Use our own API so that the Recent folder updates with our activity
const myApi = vscode.extensions.getExtension(extensionId)?.exports;

Expand All @@ -32,8 +34,8 @@ export async function getPortalUriWithToken(
const response = await makeRESTRequest(
"POST",
spec,
{ apiVersion: 1, namespace: "%SYS", path: "/action/query" },
{ query: "select %Atelier_v1_Utils.General_GetCSPToken(?, ?) token", parameters: [PORTAL_HOME, token] },
{ apiVersion: 1, namespace, path: "/action/query" },
{ query: "select %Atelier_v1_Utils.General_GetCSPToken(?, ?) token", parameters: [page, token] },
);

if (!response) {
Expand All @@ -45,9 +47,35 @@ export async function getPortalUriWithToken(
allTokens[target].set(name, token);
}

if (target === BrowserTarget.SIMPLE && !simpleBrowserCompatible.has(name)) {
// Check that the portal webapps have all been altered so they don't require session cookie support, which Simple Browser cannot provide
const response = await makeRESTRequest(
"POST",
spec,
{ apiVersion: 1, namespace: "%SYS", path: "/action/query" },
{ query: "SELECT Name FROM Security.Applications WHERE {fn CONCAT(Name, '/')} %STARTSWITH '/csp/sys/' AND UseCookies = 2" },
);
if (response) {
const appsRequiringCookie = (response.data?.result?.content as any[]).map((row) => {
return row.Name as string;
});
if (appsRequiringCookie.length > 0) {
await vscode.window.showWarningMessage(`Portal web apps cannot be used in the Simple Browser tab if their 'UseCookies' property is set to 'Always' (the default). To resolve this, use Portal's security section to change it to 'Autodetect' in these apps: ${appsRequiringCookie.join(", ")}`, { modal: true });
return;
}
else {
simpleBrowserCompatible.set(name, true);
}
}
else {
vscode.window.showWarningMessage(`Unable to check the Portal web apps for compatibility with Simple Browser.`);
simpleBrowserCompatible.set(name, true);
}
}

const webServer = spec.webServer;
const queryString = token ? `CSPCHD=${encodeURIComponent(token)}` : "";
const queryString = `$NAMESPACE=${encodeURIComponent(namespace)}${token ? `&CSPCHD=${encodeURIComponent(token)}` : ""}`;

return vscode.Uri.parse(`${webServer.scheme}://${webServer.host}:${webServer.port}${webServer.pathPrefix}${PORTAL_HOME}?${queryString}`, true);
return vscode.Uri.parse(`${webServer.scheme}://${webServer.host}:${webServer.port}${webServer.pathPrefix}${page}?${queryString}`, true);
}
}
19 changes: 17 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,29 @@ export function activate(context: vscode.ExtensionContext) {
if (uriWithToken) {
//
// 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.
// otherwise the querystring's & and = get encoded.
vscode.commands.executeCommand("simpleBrowser.show", uriWithToken.toString(true));
}
});
}
}),
);
context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.openPortalExplorerExternal`, (namespaceTreeItem?: NamespaceTreeItem) => {
if (namespaceTreeItem) {
const pathParts = namespaceTreeItem.id?.split(":");
if (pathParts && pathParts.length === 4) {
const serverName = pathParts[1];
const namespace = pathParts[3];
getPortalUriWithToken(BrowserTarget.EXTERNAL, serverName, "/csp/sys/exp/%25CSP.UI.Portal.ClassList.zen", namespace).then((uriWithToken) => {
if (uriWithToken) {
vscode.env.openExternal(uriWithToken);
}
});
}
}
}),
);
context.subscriptions.push(
vscode.commands.registerCommand(`${extensionId}.editSettings`, (server?: ServerTreeItem) => {
// Until there's a dedicated settings editor the best we can do is jump to the right section
Expand Down

0 comments on commit 20d3f62

Please sign in to comment.