From 127ca54d2b0486d82e5e49e532f8aba24508c7ab Mon Sep 17 00:00:00 2001 From: Gavin Halliday Date: Thu, 8 Jun 2023 11:52:22 +0100 Subject: [PATCH 01/29] HPCC-29667 Allow remoteread.ecl to be run stand alone Signed-off-by: Gavin Halliday --- testing/regress/ecl/setup/files.ecl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/testing/regress/ecl/setup/files.ecl b/testing/regress/ecl/setup/files.ecl index 7a2d55a2549..b1db42dd473 100644 --- a/testing/regress/ecl/setup/files.ecl +++ b/testing/regress/ecl/setup/files.ecl @@ -56,7 +56,9 @@ SHARED STRING _indexPrefix := '~regress::' + EXPORT filePrefix := #IFDEFINED(root.filePrefix, _filePrefix); EXPORT indexPrefix := #IFDEFINED(root.filePrefix, _indexPrefix); -EXPORT QueryFilePrefixId := __TARGET_PLATFORM__ + '::' + Str.ToLowerCase(WORKUNIT) + '::'; +wuid := Str.ToLowerCase(WORKUNIT); +wuidScope := IF(wuid <> '', wuid, 'WORKUNIT'); +EXPORT QueryFilePrefixId := __TARGET_PLATFORM__ + '::' + wuidScope + '::'; EXPORT QueryFilePrefix := filePrefix + QueryFilePrefixId; EXPORT DG_FileOut := filePrefix + 'DG_'; From 1621648bf9d3f8372f9751ca8670aca7b8951b0f Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Fri, 22 Sep 2023 14:22:14 +0100 Subject: [PATCH 02/29] Split off 8.10.62 Signed-off-by: Gordon Smith --- helm/hpcc/Chart.yaml | 4 ++-- helm/hpcc/templates/_helpers.tpl | 2 +- helm/hpcc/templates/dafilesrv.yaml | 2 +- helm/hpcc/templates/dali.yaml | 2 +- helm/hpcc/templates/dfuserver.yaml | 2 +- helm/hpcc/templates/eclagent.yaml | 4 ++-- helm/hpcc/templates/eclccserver.yaml | 4 ++-- helm/hpcc/templates/eclscheduler.yaml | 2 +- helm/hpcc/templates/esp.yaml | 2 +- helm/hpcc/templates/localroxie.yaml | 2 +- helm/hpcc/templates/roxie.yaml | 8 ++++---- helm/hpcc/templates/sasha.yaml | 2 +- helm/hpcc/templates/thor.yaml | 10 +++++----- version.cmake | 2 +- 14 files changed, 24 insertions(+), 24 deletions(-) diff --git a/helm/hpcc/Chart.yaml b/helm/hpcc/Chart.yaml index a78c1e9cd8a..7f050b91f9e 100644 --- a/helm/hpcc/Chart.yaml +++ b/helm/hpcc/Chart.yaml @@ -6,9 +6,9 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. -version: 8.10.61-closedown0 +version: 8.10.63-closedown0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. -appVersion: 8.10.61-closedown0 +appVersion: 8.10.63-closedown0 diff --git a/helm/hpcc/templates/_helpers.tpl b/helm/hpcc/templates/_helpers.tpl index 7f3a3cf74d4..b5b1d55c3b8 100644 --- a/helm/hpcc/templates/_helpers.tpl +++ b/helm/hpcc/templates/_helpers.tpl @@ -1208,7 +1208,7 @@ kind: Service metadata: name: {{ $lvars.serviceName | quote }} labels: - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- include "hpcc.addStandardLabels" (dict "root" $.root "instance" $lvars.serviceName ) | indent 4 }} {{- if $lvars.labels }} {{ toYaml $lvars.labels | indent 4 }} diff --git a/helm/hpcc/templates/dafilesrv.yaml b/helm/hpcc/templates/dafilesrv.yaml index a49c696dbd1..63080874c54 100644 --- a/helm/hpcc/templates/dafilesrv.yaml +++ b/helm/hpcc/templates/dafilesrv.yaml @@ -50,7 +50,7 @@ spec: labels: {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "dafilesrv" "name" "dafilesrv" "instance" .name) | indent 8 }} server: {{ .name | quote }} - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 annotations: checksum/config: {{ $configSHA }} spec: diff --git a/helm/hpcc/templates/dali.yaml b/helm/hpcc/templates/dali.yaml index 7b8fd476465..847fffaa841 100644 --- a/helm/hpcc/templates/dali.yaml +++ b/helm/hpcc/templates/dali.yaml @@ -81,7 +81,7 @@ spec: run: {{ $dali.name | quote }} server: {{ $dali.name | quote }} app: dali - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey $.Values.global "metrics" }} {{- include "hpcc.generateMetricsReporterLabel" $.Values.global.metrics | nindent 8 }} {{- end }} diff --git a/helm/hpcc/templates/dfuserver.yaml b/helm/hpcc/templates/dfuserver.yaml index b78cb54cb0e..c83522dcc0a 100644 --- a/helm/hpcc/templates/dfuserver.yaml +++ b/helm/hpcc/templates/dfuserver.yaml @@ -56,7 +56,7 @@ spec: {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "dfuserver" "name" "dfuserver" "instance" .name) | indent 8 }} run: {{ .name | quote }} accessDali: "yes" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey . "labels" }} {{ toYaml .labels | indent 8 }} {{- end }} diff --git a/helm/hpcc/templates/eclagent.yaml b/helm/hpcc/templates/eclagent.yaml index a22d419e456..8fa036065aa 100644 --- a/helm/hpcc/templates/eclagent.yaml +++ b/helm/hpcc/templates/eclagent.yaml @@ -58,7 +58,7 @@ data: {{- include "hpcc.addStandardLabels" (dict "root" $ "component" $apptype "name" "eclagent" "instance" $appJobName "instanceOf" (printf "%s-job" .me.name)) | indent 12 }} accessDali: "yes" accessEsp: "yes" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey .me "labels" }} {{ toYaml .me.labels | indent 12 }} {{- end }} @@ -137,7 +137,7 @@ spec: run: {{ .name | quote }} accessDali: "yes" accessEsp: {{ .useChildProcesses | default false | ternary "yes" "no" | quote }} - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey . "labels" }} {{ toYaml .labels | indent 8 }} {{- end }} diff --git a/helm/hpcc/templates/eclccserver.yaml b/helm/hpcc/templates/eclccserver.yaml index 1d2713a7208..098ecf1fa3c 100644 --- a/helm/hpcc/templates/eclccserver.yaml +++ b/helm/hpcc/templates/eclccserver.yaml @@ -57,7 +57,7 @@ data: {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "eclccserver" "name" "eclccserver" "instance" $compileJobName "instanceOf" (printf "%s-job" .me.name)) | indent 12 }} accessDali: "yes" accessEsp: "yes" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey .me "labels" }} {{ toYaml .me.labels | indent 12 }} {{- end }} @@ -142,7 +142,7 @@ spec: run: {{ .name | quote }} accessDali: "yes" accessEsp: {{ .useChildProcesses | default false | ternary "yes" "no" | quote }} - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey . "labels" }} {{ toYaml .labels | indent 8 }} {{- end }} diff --git a/helm/hpcc/templates/eclscheduler.yaml b/helm/hpcc/templates/eclscheduler.yaml index 0b4a20f8b2c..22b457f823a 100644 --- a/helm/hpcc/templates/eclscheduler.yaml +++ b/helm/hpcc/templates/eclscheduler.yaml @@ -64,7 +64,7 @@ spec: run: {{ .name | quote }} accessDali: "yes" accessEsp: "no" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey . "labels" }} {{ toYaml .labels | indent 8 }} {{- end }} diff --git a/helm/hpcc/templates/esp.yaml b/helm/hpcc/templates/esp.yaml index 95ece3aee0e..ef226043918 100644 --- a/helm/hpcc/templates/esp.yaml +++ b/helm/hpcc/templates/esp.yaml @@ -116,7 +116,7 @@ spec: server: {{ .name | quote }} accessDali: "yes" app: {{ $application }} - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- include "hpcc.addStandardLabels" (dict "root" $ "name" $application "component" "esp" "instance" .name) | indent 8 }} {{- if hasKey $.Values.global "metrics" }} {{- include "hpcc.generateMetricsReporterLabel" $.Values.global.metrics | nindent 8 }} diff --git a/helm/hpcc/templates/localroxie.yaml b/helm/hpcc/templates/localroxie.yaml index 9c4d242575e..a09491568c2 100644 --- a/helm/hpcc/templates/localroxie.yaml +++ b/helm/hpcc/templates/localroxie.yaml @@ -70,7 +70,7 @@ spec: server: {{ $servername | quote }} accessDali: "yes" accessEsp: "yes" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "roxie-server" "name" "roxie" "instance" $roxie.name) | indent 8 }} {{- if hasKey . "labels" }} {{ toYaml .labels | indent 8 }} diff --git a/helm/hpcc/templates/roxie.yaml b/helm/hpcc/templates/roxie.yaml index 87149855f85..a71c7424fd5 100644 --- a/helm/hpcc/templates/roxie.yaml +++ b/helm/hpcc/templates/roxie.yaml @@ -118,7 +118,7 @@ spec: {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "topology-server" "name" "roxie" "instance" $commonCtx.toponame) | indent 8 }} run: {{ $commonCtx.toponame | quote }} roxie-cluster: {{ $roxie.name | quote }} - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey $.Values.global "metrics" }} {{- include "hpcc.generateMetricsReporterLabel" $.Values.global.metrics | nindent 8}} {{- end }} @@ -178,7 +178,7 @@ kind: Service metadata: name: {{ $commonCtx.toponame | quote }} labels: - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "topology-server" "name" "roxie" "instance" $commonCtx.toponame) | indent 4 }} spec: ports: @@ -240,7 +240,7 @@ spec: roxie-cluster: {{ $roxie.name | quote }} accessDali: "yes" accessEsp: "yes" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "roxie-server" "name" "roxie" "instance" $servername) | indent 8 }} {{- if hasKey $.Values.global "metrics" }} {{- include "hpcc.generateMetricsReporterLabel" $.Values.global.metrics | nindent 8}} @@ -343,7 +343,7 @@ spec: roxie-cluster: {{ $roxie.name | quote }} accessDali: "yes" accessEsp: "yes" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey $.Values.global "metrics" }} {{- include "hpcc.generateMetricsReporterLabel" $.Values.global.metrics | nindent 8}} {{- end }} diff --git a/helm/hpcc/templates/sasha.yaml b/helm/hpcc/templates/sasha.yaml index 4c1de9ca988..f18acce7be2 100644 --- a/helm/hpcc/templates/sasha.yaml +++ b/helm/hpcc/templates/sasha.yaml @@ -52,7 +52,7 @@ spec: run: {{ $serviceName | quote }} server: {{ $serviceName | quote }} accessDali: {{ (has "dali" $sasha.access) | ternary "yes" "no" | quote }} - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- if hasKey $sasha "labels" }} {{ toYaml $sasha.labels | indent 8 }} {{- end }} diff --git a/helm/hpcc/templates/thor.yaml b/helm/hpcc/templates/thor.yaml index b0dbcc5fdad..a98a3b62b65 100644 --- a/helm/hpcc/templates/thor.yaml +++ b/helm/hpcc/templates/thor.yaml @@ -82,7 +82,7 @@ data: labels: accessDali: "yes" accessEsp: "yes" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "eclagent" "name" "thor" "instance" $eclAgentJobName "instanceOf" (printf "%s-job" .eclAgentName)) | indent 8 }} {{- if hasKey .me "labels" }} {{ toYaml .me.labels | indent 12 }} @@ -149,7 +149,7 @@ data: accessEsp: "yes" app: "thor" component: "thormanager" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 instance: "_HPCC_JOBNAME_" job: "_HPCC_JOBNAME_" {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "thormanager" "name" "thor" "instance" $thorManagerJobName "instanceOf" (printf "%s-thormanager-job" .me.name)) | indent 12 }} @@ -218,7 +218,7 @@ data: accessEsp: "yes" app: "thor" component: "thorworker" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 instance: "_HPCC_JOBNAME_" job: "_HPCC_JOBNAME_" {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "thorworker" "name" "thor" "instance" $thorWorkerJobName "instanceOf" (printf "%s-thorworker-job" .me.name)) | indent 12 }} @@ -353,7 +353,7 @@ spec: accessEsp: {{ $commonCtx.eclAgentUseChildProcesses | ternary "yes" "no" | quote }} app: "thor" component: "thor-eclagent" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 instance: {{ $commonCtx.eclAgentName | quote }} {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "eclagent" "name" "thor" "instance" $commonCtx.eclAgentName ) | indent 8 }} {{- if hasKey $commonCtx.me "labels" }} @@ -418,7 +418,7 @@ spec: accessEsp: "no" app: "thor" component: "thor-thoragent" - helmVersion: 8.10.61-closedown0 + helmVersion: 8.10.63-closedown0 instance: {{ $commonCtx.thorAgentName | quote }} {{- include "hpcc.addStandardLabels" (dict "root" $ "component" "eclagent" "name" "thor" "instance" $commonCtx.thorAgentName ) | indent 8 }} {{- if hasKey $commonCtx.me "labels" }} diff --git a/version.cmake b/version.cmake index f489a4db670..699157579ff 100644 --- a/version.cmake +++ b/version.cmake @@ -5,7 +5,7 @@ set ( HPCC_NAME "Community Edition" ) set ( HPCC_PROJECT "community" ) set ( HPCC_MAJOR 8 ) set ( HPCC_MINOR 10 ) -set ( HPCC_POINT 61 ) +set ( HPCC_POINT 63 ) set ( HPCC_MATURITY "closedown" ) set ( HPCC_SEQUENCE 0 ) ### From a1a65efa07b975f1195fc904a91f8556b77146c1 Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Thu, 28 Sep 2023 10:37:46 -0400 Subject: [PATCH 03/29] HPCC-30220 ECL Watch fix authentication & ESP session lock issues Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/eclwatch/stub.js | 6 ++--- esp/src/src-react/components/Frame.tsx | 28 +++++++++++++++++--- esp/src/src-react/components/forms/Login.tsx | 11 ++++++++ esp/src/src-react/index.tsx | 7 +++-- esp/src/src/ESPUtil.ts | 4 +-- esp/src/src/KeyValStore.ts | 2 +- esp/src/src/Session.ts | 5 ++-- 7 files changed, 50 insertions(+), 13 deletions(-) diff --git a/esp/src/eclwatch/stub.js b/esp/src/eclwatch/stub.js index 9626bcc47b4..6bff90c731e 100644 --- a/esp/src/eclwatch/stub.js +++ b/esp/src/eclwatch/stub.js @@ -35,13 +35,13 @@ define([ if (modernMode === String(true) && hpccWidget !== "IFrameWidget") { switch (hpccWidget) { case "WUDetailsWidget": - window.location.replace(`/esp/files/index.html#/workunits/${params.Wuid}`); + window.location.replace(`/#/workunits/${params.Wuid}`); break; case "GraphsWUWidget": - window.location.replace(`/esp/files/index.html#/workunits/${params.Wuid}/metrics`); + window.location.replace(`/#/workunits/${params.Wuid}/metrics`); break; default: - window.location.replace("/esp/files/index.html"); + window.location.replace("/"); } } else { ready(function () { diff --git a/esp/src/src-react/components/Frame.tsx b/esp/src/src-react/components/Frame.tsx index 67ecfd90b01..594f756080c 100644 --- a/esp/src/src-react/components/Frame.tsx +++ b/esp/src/src-react/components/Frame.tsx @@ -1,18 +1,21 @@ import * as React from "react"; +import * as topic from "dojo/topic"; import { ThemeProvider } from "@fluentui/react"; import { FluentProvider } from "@fluentui/react-components"; import { select as d3Select } from "@hpcc-js/common"; import { scopedLogger } from "@hpcc-js/util"; -import { useUserTheme } from "../hooks/theme"; -import { useGlobalWorkunitNotes } from "../hooks/workunit"; import { HolyGrail } from "../layouts/HolyGrail"; import { hashHistory } from "../util/history"; import { router } from "../routes"; import { DevTitle } from "./Title"; import { MainNavigation, SubNavigation } from "./Menu"; import { CookieConsent } from "./forms/CookieConsent"; -import { userKeyValStore } from "../../src/KeyValStore"; +import { userKeyValStore } from "src/KeyValStore"; +import { fireIdle, initSession, lock, unlock } from "src/Session"; import { useGlobalStore } from "../hooks/store"; +import { useUserTheme } from "../hooks/theme"; +import { useGlobalWorkunitNotes } from "../hooks/workunit"; +import { useUserSession } from "../hooks/user"; const logger = scopedLogger("../components/Frame.tsx"); const envLogger = scopedLogger("environment"); @@ -23,6 +26,7 @@ interface FrameProps { export const Frame: React.FunctionComponent = () => { const [showCookieConsent, setShowCookieConsent] = React.useState(false); + const { userSession, setUserSession } = useUserSession(); const [locationPathname, setLocationPathname] = React.useState(window.location.hash.split("#").join("")); const [body, setBody] = React.useState(

...loading...

); const { theme, themeV9, isDark } = useUserTheme(); @@ -49,6 +53,24 @@ export const Frame: React.FunctionComponent = () => { }); }, [globalWUNotes]); + React.useEffect(() => { + initSession(); + + topic.subscribe("hpcc/session_management_status", function (publishedMessage) { + if (publishedMessage.status === "Unlocked") { + unlock(); + } else if (publishedMessage.status === "Locked") { + lock(); + } else if (publishedMessage.status === "DoIdle") { + fireIdle(); + } else if (publishedMessage.status === "Idle") { + window.localStorage.setItem("pageOnLock", window.location.hash.substring(1)); + setUserSession({ ...userSession, Status: "Locked" }); + window.location.reload(); + } + }); + }, [setUserSession, userSession]); + React.useEffect(() => { const unlisten = hashHistory.listen(async (location, action) => { diff --git a/esp/src/src-react/components/forms/Login.tsx b/esp/src/src-react/components/forms/Login.tsx index a5dc021cb51..a6d7d39c769 100644 --- a/esp/src/src-react/components/forms/Login.tsx +++ b/esp/src/src-react/components/forms/Login.tsx @@ -37,6 +37,15 @@ export const Login: React.FunctionComponent = ({ const [showError, setShowError] = React.useState(false); const [errorMessage, setErrorMessage] = React.useState(""); + React.useEffect(() => { + const cookies = Utility.parseCookies(); + if (cookies["ESPSessionState"] === "true") { + const lastUrl = window.localStorage.getItem("pageOnLock") ?? "/"; + window.localStorage.removeItem("pageOnLock"); + replaceUrl(lastUrl); + } + }, []); + const loginStyles = React.useMemo(() => mergeStyleSets({ root: { height: "100%", @@ -107,6 +116,8 @@ export const Login: React.FunctionComponent = ({ setErrorMessage(cookies.ESPAuthenticationMSG); setShowError(true); } else { + cookies["Status"] = "Unlocked"; + cookies["ESPAuthenticated"] = "true"; createUserSession(cookies).then(() => { setErrorMessage(""); replaceUrl("/", null, true); diff --git a/esp/src/src-react/index.tsx b/esp/src/src-react/index.tsx index d946f22edf6..b3049252cf4 100644 --- a/esp/src/src-react/index.tsx +++ b/esp/src/src-react/index.tsx @@ -5,6 +5,7 @@ import { scopedLogger } from "@hpcc-js/util"; import { cookieKeyValStore, userKeyValStore } from "src/KeyValStore"; import { containerized, ModernMode } from "src/BuildInfo"; import { ECLWatchLogger } from "./hooks/logging"; +import { replaceUrl } from "./util/history"; import "css!dijit-themes/flat/flat.css"; import "css!hpcc/css/ecl.css"; @@ -40,8 +41,10 @@ store.getEx(ModernMode, { defaultValue: String(containerized) }).then(async mode const authType = await authTypeResp?.text() ?? "None"; const userStore = cookieKeyValStore(); const userSession = await userStore.getAll(); - if (authType.indexOf("None") < 0 && (!userSession["ESPAuthenticated"] && (!userSession["ECLWatchUser"] || !userSession["Status"] || userSession["Status"] === "Locked"))) { - window.location.replace("#/login"); + if (authType.indexOf("None") < 0 && (userSession["ESPSessionState"] === "false" || userSession["ECLWatchUser"] === "false" || (!userSession["Status"] || userSession["Status"] === "Locked"))) { + if (window.location.hash.indexOf("login") < 0) { + replaceUrl("/login"); + } import("./components/forms/Login").then(_ => { try { ReactDOM.render( diff --git a/esp/src/src/ESPUtil.ts b/esp/src/src/ESPUtil.ts index 43cf058435d..8c8a94e4abc 100644 --- a/esp/src/src/ESPUtil.ts +++ b/esp/src/src/ESPUtil.ts @@ -314,10 +314,10 @@ export function goToPageUserPreference(gridName, key) { export const MonitorLockClick = dojo.declare([Evented], { unlocked() { - this.emit("unlocked", {}); + this.emit("Unlocked", {}); }, locked() { - this.emit("locked", {}); + this.emit("Locked", {}); } }); diff --git a/esp/src/src/KeyValStore.ts b/esp/src/src/KeyValStore.ts index 3066af2b4cd..8dc900bf2d3 100644 --- a/esp/src/src/KeyValStore.ts +++ b/esp/src/src/KeyValStore.ts @@ -212,7 +212,7 @@ class CookieStorage implements IKeyValStore { set(key: string, value: string, broadcast?: boolean): Promise { const cookies = Utility.parseCookies(); const oldValue = cookies[key]; - document.cookie = `${key}=${value}`; + document.cookie = `${key}=${value};path=/`; return Promise.resolve().then(() => { if (broadcast) { this._dispatch.post(new ValueChangedMessage(key, value, oldValue)); diff --git a/esp/src/src/Session.ts b/esp/src/src/Session.ts index d24351a7771..530fe131694 100644 --- a/esp/src/src/Session.ts +++ b/esp/src/src/Session.ts @@ -14,7 +14,6 @@ const espTimeoutSeconds = cookie("ESPSessionTimeoutSeconds") || 600; // 10 minun const IDLE_TIMEOUT = espTimeoutSeconds * 1000; const SESSION_RESET_FREQ = 30 * 1000; const idleWatcher = new ESPUtil.IdleWatcher(IDLE_TIMEOUT); -const monitorLockClick = new ESPUtil.MonitorLockClick(); const sessionIsActive = espTimeoutSeconds; let _prevReset = Date.now(); @@ -73,7 +72,9 @@ export function initSession() { }); idleWatcher.start(); - monitorLockClick.unlocked(); + if (!cookie("Status")) { + document.cookie = "Status=Unlocked;Path=/"; + } } else if (cookie("ECLWatchUser")) { window.location.replace(dojoConfig.urlInfo.basePath + "/Login.html"); } From 999c65896b92215c5872023c456f33822c06d38d Mon Sep 17 00:00:00 2001 From: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> Date: Thu, 28 Sep 2023 10:00:15 -0400 Subject: [PATCH 04/29] HPCC-30220 ECL Watch fix authentication & ESP session lock issues Signed-off-by: Jeremy Clements <79224539+jeclrsg@users.noreply.github.com> --- esp/src/eclwatch/stub.js | 6 ++--- esp/src/src-react/components/Frame.tsx | 26 ++++++++++++++++++-- esp/src/src-react/components/forms/Login.tsx | 11 +++++++++ esp/src/src-react/index.tsx | 7 ++++-- esp/src/src/ESPUtil.ts | 4 +-- esp/src/src/KeyValStore.ts | 2 +- esp/src/src/Session.ts | 5 ++-- 7 files changed, 49 insertions(+), 12 deletions(-) diff --git a/esp/src/eclwatch/stub.js b/esp/src/eclwatch/stub.js index 9626bcc47b4..6bff90c731e 100644 --- a/esp/src/eclwatch/stub.js +++ b/esp/src/eclwatch/stub.js @@ -35,13 +35,13 @@ define([ if (modernMode === String(true) && hpccWidget !== "IFrameWidget") { switch (hpccWidget) { case "WUDetailsWidget": - window.location.replace(`/esp/files/index.html#/workunits/${params.Wuid}`); + window.location.replace(`/#/workunits/${params.Wuid}`); break; case "GraphsWUWidget": - window.location.replace(`/esp/files/index.html#/workunits/${params.Wuid}/metrics`); + window.location.replace(`/#/workunits/${params.Wuid}/metrics`); break; default: - window.location.replace("/esp/files/index.html"); + window.location.replace("/"); } } else { ready(function () { diff --git a/esp/src/src-react/components/Frame.tsx b/esp/src/src-react/components/Frame.tsx index 73d48d509a5..587e48246d3 100644 --- a/esp/src/src-react/components/Frame.tsx +++ b/esp/src/src-react/components/Frame.tsx @@ -1,17 +1,20 @@ import * as React from "react"; +import * as topic from "dojo/topic"; import { ThemeProvider } from "@fluentui/react"; import { FluentProvider } from "@fluentui/react-components"; import { select as d3Select } from "@hpcc-js/common"; import { scopedLogger } from "@hpcc-js/util"; -import { useUserTheme } from "../hooks/theme"; import { HolyGrail } from "../layouts/HolyGrail"; import { hashHistory } from "../util/history"; import { router } from "../routes"; import { DevTitle } from "./Title"; import { MainNavigation, SubNavigation } from "./Menu"; import { CookieConsent } from "./forms/CookieConsent"; -import { userKeyValStore } from "../../src/KeyValStore"; +import { userKeyValStore } from "src/KeyValStore"; +import { fireIdle, initSession, lock, unlock } from "src/Session"; import { useGlobalStore } from "../hooks/store"; +import { useUserTheme } from "../hooks/theme"; +import { useUserSession } from "../hooks/user"; const logger = scopedLogger("../components/Frame.tsx"); @@ -21,6 +24,7 @@ interface FrameProps { export const Frame: React.FunctionComponent = () => { const [showCookieConsent, setShowCookieConsent] = React.useState(false); + const { userSession, setUserSession } = useUserSession(); const [locationPathname, setLocationPathname] = React.useState(window.location.hash.split("#").join("")); const [body, setBody] = React.useState(

...loading...

); const { theme, themeV9, isDark } = useUserTheme(); @@ -46,6 +50,24 @@ export const Frame: React.FunctionComponent = () => { return () => unlisten(); }, []); + React.useEffect(() => { + initSession(); + + topic.subscribe("hpcc/session_management_status", function (publishedMessage) { + if (publishedMessage.status === "Unlocked") { + unlock(); + } else if (publishedMessage.status === "Locked") { + lock(); + } else if (publishedMessage.status === "DoIdle") { + fireIdle(); + } else if (publishedMessage.status === "Idle") { + window.localStorage.setItem("pageOnLock", window.location.hash.substring(1)); + setUserSession({ ...userSession, Status: "Locked" }); + window.location.reload(); + } + }); + }, [setUserSession, userSession]); + React.useEffect(() => { document.title = `${showEnvironmentTitle && environmentTitle.length ? environmentTitle : "ECL Watch v9"}${locationPathname.split("/").join(" | ")}`; }, [environmentTitle, locationPathname, showEnvironmentTitle]); diff --git a/esp/src/src-react/components/forms/Login.tsx b/esp/src/src-react/components/forms/Login.tsx index a5dc021cb51..a6d7d39c769 100644 --- a/esp/src/src-react/components/forms/Login.tsx +++ b/esp/src/src-react/components/forms/Login.tsx @@ -37,6 +37,15 @@ export const Login: React.FunctionComponent = ({ const [showError, setShowError] = React.useState(false); const [errorMessage, setErrorMessage] = React.useState(""); + React.useEffect(() => { + const cookies = Utility.parseCookies(); + if (cookies["ESPSessionState"] === "true") { + const lastUrl = window.localStorage.getItem("pageOnLock") ?? "/"; + window.localStorage.removeItem("pageOnLock"); + replaceUrl(lastUrl); + } + }, []); + const loginStyles = React.useMemo(() => mergeStyleSets({ root: { height: "100%", @@ -107,6 +116,8 @@ export const Login: React.FunctionComponent = ({ setErrorMessage(cookies.ESPAuthenticationMSG); setShowError(true); } else { + cookies["Status"] = "Unlocked"; + cookies["ESPAuthenticated"] = "true"; createUserSession(cookies).then(() => { setErrorMessage(""); replaceUrl("/", null, true); diff --git a/esp/src/src-react/index.tsx b/esp/src/src-react/index.tsx index d946f22edf6..b3049252cf4 100644 --- a/esp/src/src-react/index.tsx +++ b/esp/src/src-react/index.tsx @@ -5,6 +5,7 @@ import { scopedLogger } from "@hpcc-js/util"; import { cookieKeyValStore, userKeyValStore } from "src/KeyValStore"; import { containerized, ModernMode } from "src/BuildInfo"; import { ECLWatchLogger } from "./hooks/logging"; +import { replaceUrl } from "./util/history"; import "css!dijit-themes/flat/flat.css"; import "css!hpcc/css/ecl.css"; @@ -40,8 +41,10 @@ store.getEx(ModernMode, { defaultValue: String(containerized) }).then(async mode const authType = await authTypeResp?.text() ?? "None"; const userStore = cookieKeyValStore(); const userSession = await userStore.getAll(); - if (authType.indexOf("None") < 0 && (!userSession["ESPAuthenticated"] && (!userSession["ECLWatchUser"] || !userSession["Status"] || userSession["Status"] === "Locked"))) { - window.location.replace("#/login"); + if (authType.indexOf("None") < 0 && (userSession["ESPSessionState"] === "false" || userSession["ECLWatchUser"] === "false" || (!userSession["Status"] || userSession["Status"] === "Locked"))) { + if (window.location.hash.indexOf("login") < 0) { + replaceUrl("/login"); + } import("./components/forms/Login").then(_ => { try { ReactDOM.render( diff --git a/esp/src/src/ESPUtil.ts b/esp/src/src/ESPUtil.ts index 43cf058435d..8c8a94e4abc 100644 --- a/esp/src/src/ESPUtil.ts +++ b/esp/src/src/ESPUtil.ts @@ -314,10 +314,10 @@ export function goToPageUserPreference(gridName, key) { export const MonitorLockClick = dojo.declare([Evented], { unlocked() { - this.emit("unlocked", {}); + this.emit("Unlocked", {}); }, locked() { - this.emit("locked", {}); + this.emit("Locked", {}); } }); diff --git a/esp/src/src/KeyValStore.ts b/esp/src/src/KeyValStore.ts index 3066af2b4cd..8dc900bf2d3 100644 --- a/esp/src/src/KeyValStore.ts +++ b/esp/src/src/KeyValStore.ts @@ -212,7 +212,7 @@ class CookieStorage implements IKeyValStore { set(key: string, value: string, broadcast?: boolean): Promise { const cookies = Utility.parseCookies(); const oldValue = cookies[key]; - document.cookie = `${key}=${value}`; + document.cookie = `${key}=${value};path=/`; return Promise.resolve().then(() => { if (broadcast) { this._dispatch.post(new ValueChangedMessage(key, value, oldValue)); diff --git a/esp/src/src/Session.ts b/esp/src/src/Session.ts index d24351a7771..530fe131694 100644 --- a/esp/src/src/Session.ts +++ b/esp/src/src/Session.ts @@ -14,7 +14,6 @@ const espTimeoutSeconds = cookie("ESPSessionTimeoutSeconds") || 600; // 10 minun const IDLE_TIMEOUT = espTimeoutSeconds * 1000; const SESSION_RESET_FREQ = 30 * 1000; const idleWatcher = new ESPUtil.IdleWatcher(IDLE_TIMEOUT); -const monitorLockClick = new ESPUtil.MonitorLockClick(); const sessionIsActive = espTimeoutSeconds; let _prevReset = Date.now(); @@ -73,7 +72,9 @@ export function initSession() { }); idleWatcher.start(); - monitorLockClick.unlocked(); + if (!cookie("Status")) { + document.cookie = "Status=Unlocked;Path=/"; + } } else if (cookie("ECLWatchUser")) { window.location.replace(dojoConfig.urlInfo.basePath + "/Login.html"); } From b76fbae97f1c2ebc315645382369f87829ce5744 Mon Sep 17 00:00:00 2001 From: wangkx Date: Tue, 10 Oct 2023 16:59:10 -0400 Subject: [PATCH 05/29] HPCC-30429 Fix WsECL display for 'Create Workunit' option The 'Create Workunit' option should not be available for a queriesOnly roxie. Signed-off-by: wangkx --- esp/services/ws_ecl/ws_ecl_service.cpp | 23 ++++++++++++++++++++--- esp/xslt/wsecl3_form.xsl | 12 +++++++++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/esp/services/ws_ecl/ws_ecl_service.cpp b/esp/services/ws_ecl/ws_ecl_service.cpp index a444ce2d13c..8e6d09d1d28 100644 --- a/esp/services/ws_ecl/ws_ecl_service.cpp +++ b/esp/services/ws_ecl/ws_ecl_service.cpp @@ -1568,12 +1568,17 @@ int CWsEclBinding::getGenForm(IEspContext &context, CHttpRequest* request, CHttp xform->setParameter("useTextareaForStringArray", "1"); #ifdef _CONTAINERIZED - bool isRoxie = wsecl->connMap.getValue(wuinfo.qsetname) != nullptr; -#else + VStringBuffer xpath("queues[@name='%s']", wuinfo.qsetname.get()); + IPropertyTree *queue = getComponentConfigSP()->queryPropTree(xpath.str()); + if (queue && strieq(queue->queryProp("@type"), "roxie")) + xform->setParameter("includeRoxieOptions", queue->getPropBool("@queriesOnly") ? "2" : "3"); + else + xform->setParameter("includeRoxieOptions", "0"); + #else Owned clusterInfo = getTargetClusterInfo(wuinfo.qsetname); bool isRoxie = clusterInfo && (clusterInfo->getPlatform() == RoxieCluster); -#endif xform->setParameter("includeRoxieOptions", isRoxie ? "1" : "0"); +#endif // set the prop noDefaultValue param IProperties* props = context.queryRequestParameters(); @@ -2134,8 +2139,18 @@ void CWsEclBinding::sendRoxieRequest(const char *target, StringBuffer &req, Stri } } +static void checkWorkunitCompatibleOptions(IEspContext &context, bool submitWorkunit) +{ + bool statsToWorkunit = context.queryRequestParameters()->getPropBool("@statsToWorkunit", false); + bool summaryStats = context.queryRequestParameters()->getPropBool("@summaryStats", false); + if (submitWorkunit && (statsToWorkunit || summaryStats)) + throw makeStringException(-1, "Neither 'Save stats to workunit' or 'Get summary stats' are supported for the 'Create Workunit' option"); +} + int CWsEclBinding::onSubmitQueryOutput(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo, const char *format, bool forceCreateWorkunit) { + checkWorkunitCompatibleOptions(context, forceCreateWorkunit); + StringBuffer status; StringBuffer output; @@ -2200,6 +2215,8 @@ int CWsEclBinding::onSubmitQueryOutput(IEspContext &context, CHttpRequest* reque int CWsEclBinding::onSubmitQueryOutputView(IEspContext &context, CHttpRequest* request, CHttpResponse* response, WsEclWuInfo &wsinfo, bool forceCreateWorkunit) { + checkWorkunitCompatibleOptions(context, forceCreateWorkunit); + IConstWorkUnit *wu = wsinfo.ensureWorkUnit(); StringBuffer soapmsg; diff --git a/esp/xslt/wsecl3_form.xsl b/esp/xslt/wsecl3_form.xsl index d2b6a7ff012..1cc73aa3214 100644 --- a/esp/xslt/wsecl3_form.xsl +++ b/esp/xslt/wsecl3_form.xsl @@ -311,7 +311,7 @@ function switchInputForm() - + @@ -339,6 +339,16 @@ function switchInputForm()   + + +   + + +