From 5eb8492742a6ede252bc4f40dd33932700792718 Mon Sep 17 00:00:00 2001 From: dc Date: Tue, 3 Nov 2026 12:22:16 +0000 Subject: [PATCH] fix(deploy): gate the browse actions on the settings file --- .agents/docs/deploy-window-authorization.md | 33 +- .../dc-location/dc-location.component.html | 19 +- .../dc-location/dc-location.component.spec.ts | 128 +++++- .../dc-location/dc-location.component.ts | 13 + .../sasjs-configurator.component.html | 4 +- sas/sasjs/macros/mpe_action.sas | 71 ++++ sas/sasjs/macros/mpe_action.test.sas | 117 ++++++ sas/sasjs/macros/mpe_dirlist.sas | 8 +- sas/sasjs/macros/mpe_dirlist.test.sas | 7 +- sas/sasjs/macros/mpe_writecheck.sas | 3 +- sas/sasjs/macros/mpe_writecheck.test.sas | 6 +- .../server/services_server/admin/makedata.sas | 81 ++-- .../services_server/admin/makedata.test.sas | 395 +++--------------- .../viya/services_viya/admin/makedata.sas | 62 ++- 14 files changed, 496 insertions(+), 451 deletions(-) create mode 100644 sas/sasjs/macros/mpe_action.sas create mode 100644 sas/sasjs/macros/mpe_action.test.sas diff --git a/.agents/docs/deploy-window-authorization.md b/.agents/docs/deploy-window-authorization.md index ae2604b..afda14b 100644 --- a/.agents/docs/deploy-window-authorization.md +++ b/.agents/docs/deploy-window-authorization.md @@ -1,19 +1,14 @@ -# Why the deploy window has no admin gate +# What guards the deploy window -The deploy screens ask two questions about the physical filesystem - what folders sit below this parent, and can the deployment user write to this one. Both are answered by `makedata` (`ACTION=DIRLIST` and `ACTION=WRITECHECK`), through `mpe_adminsetup.sas`. +The deploy screens ask two questions about the physical filesystem - what folders sit below this parent, and can the deployment user write to this one. Both are answered by `makedata` (`ACTION=DIRLIST` and `ACTION=WRITECHECK`), through `mpe_dirlist.sas` and `mpe_writecheck.sas`. -Neither action checks a group, and this note records why that is the right answer rather than an oversight - so the next review does not have to work it out again. +This note records the two-layer answer: a gate that closes the window once the appLoc is configured, and why the window itself has no group check. -## The window is the deployment itself +## The gate -`makedata` exists from the moment the service pack is deployed until it runs successfully, at which point it deletes itself (and, on SASjs Server, the configurator). Deploying the pack and running `makedata` is an administrator's job, done in one sitting; there is no steady state in which these actions are reachable on a configured system. +The deploy window is over once the appLoc has `services/public/settings.sas`: `makedata` writes it at the end of a successful run, and a run that failed - or was abandoned - after writing it leaves the file behind. So the service refuses `DIRLIST` and `WRITECHECK` whenever that file is present, however the run that created it ended. On SASjs Server the file is fetched with `ms_getfile` and a probe that cannot answer (anything other than 200 or 404) is treated as configured: an unreachable drive is not evidence that the window is open. Viya checks the same file through `mfv_existfile`. -What the actions do, for the record: - -- `DIRLIST` - enumerate the folders below any absolute path the SAS process can open. Folder names only; no file contents, no file listing. -- `WRITECHECK` - ask whether a path exists, is a folder, and whether the deployment user can create and delete a file in it. It creates a uniquely named probe file and removes it again. - -Both refuse a value carrying a macro trigger, a quote or a statement separator, and shape check it with `mp_validatecol(ISPATH)` before use. +The consequence for tests: the browse actions are refused on any appLoc that runs the suite, because every such appLoc is configured. `services/admin/makedata.test.sas` therefore asserts the refusal, and the listing and write-probe behaviour is asserted against the macros directly (`macros/mpe_dirlist.test.sas`, `macros/mpe_writecheck.test.sas`). The macros' own abort paths (a relative path, one carrying a macro trigger) are not asserted anywhere: `mp_abort` cannot be exercised inside the test session. ## Why there is no group check @@ -21,13 +16,17 @@ Every other admin service gates on `&mpeadmins`, which comes from `MPE_CONFIG` i The window is not narrower than the configurator's own: on SASjs Server the configurator page, in the same window, lets the caller pick any group they belong to and create the control library - which is full Data Controller admin. `DIRLIST` and `WRITECHECK` are strictly less powerful than that. +## What the actions do, for the record + +- `DIRLIST` - enumerate the folders below any absolute path the SAS process can open. Folder names only; no file contents, no file listing. +- `WRITECHECK` - ask whether a path exists, is a folder, and whether the deployment user can create and delete a file in it. It creates a uniquely named probe file and removes it again. + +Both refuse a value carrying a macro trigger, a quote or a statement separator, and shape check it with `mp_validatecol(ISPATH)` before use. The shape check fails closed: an absent `ISPATH` rule refuses the path rather than accepting it. + ## The assessment -- **There is no admin group to check.** It is created by `makedata`, from the group the deployer picks in the configurator. +- **The window is the deployment itself.** `makedata` is deployed, run once by an administrator, and deletes itself on success. +- **There is no admin group to check while it runs.** It is created by `makedata`, from the group the deployer picks in the configurator. - **The caller is the administrator.** Reaching these actions means reaching the STPs of a deployment in progress, which is the same caller the configurator is serving in the same window. - **The actions are the weaker half of that window.** The configurator, in the same window, lets the caller pick any group they belong to and create the control library - which is full Data Controller admin. Listing folders and probing a write cannot achieve that. -- **They do not survive.** A successful `makedata` deletes the service, so a configured system has nothing that can enumerate a directory or write a probe file. - -## If it ever stops being internal - -The option, if these actions are ever reachable outside a deployment, is a gate that does not depend on the control library - an allowlist in the service, or an OS/metadata group named at deploy time. That is a change to how the deploy screens authenticate rather than a change to this service. +- **The window closes on the settings file, not on survival of the service.** That is what covers a failed or abandoned run. diff --git a/client/src/app/deploy/sections/dc-location/dc-location.component.html b/client/src/app/deploy/sections/dc-location/dc-location.component.html index 7939bcb..31187b1 100644 --- a/client/src/app/deploy/sections/dc-location/dc-location.component.html +++ b/client/src/app/deploy/sections/dc-location/dc-location.component.html @@ -4,13 +4,14 @@ clrInput [id]="inputId" [name]="inputId" + [attr.aria-label]="ariaLabel" [ngModel]="path" (ngModelChange)="onPathChange($event)" placeholder="Type a folder, or browse below" />