Files
Fuchs_Intranet/Fuchs/Docs/Decisions/0021-user-group-management.md
Stefan 8bcec409c5 feat: Add Admin Groups Management Module
- Introduced a new module for managing user groups (`usrgrp`) in the administration interface.
- Implemented CRUD operations for user groups: list, create, rename, and delete.
- Added authorization checks to ensure only users with appropriate permissions can manage groups.
- Created corresponding frontend JavaScript and SCSS files for the new module.
- Updated documentation to reflect the new group management functionality and its authorization model.
- Added SQL stored procedures for group management operations.
- Established a new login script for database access, ensuring proper security practices.
2026-09-16 09:35:31 +02:00

89 lines
6.0 KiB
Markdown

---
status: Accepted
date: 2026-09-16
applyTo:
- "Fuchs/Controllers/IntranetController.AdminGroups.cs"
- "Fuchs/js/intranet/modules/fis.usrgrp*.js"
- "Fuchs/js/intranet/modules/fis.usrgrp.scss"
- "Fuchs/js/intranet/fis_main_menu.js"
- "Fuchs_Database/dbo/Functions/fis_admin_getUserGroupList.sql"
- "Fuchs_Database/dbo/Stored Procedures/fis_admin_setUserGroup.sql"
- "Fuchs_Database/dbo/Stored Procedures/fis_admin_delUserGroup.sql"
- "Fuchs_Database/dbo/Stored Procedures/fis_admin_addGroupMember.sql"
- "Fuchs_Database/dbo/Stored Procedures/fis_admin_remGroupMember.sql"
supersededBy: ""
---
# 0021 — User group management: new `usrgrp` module, close the missing `intranet_admin` gate on group writes
## Context
The per-user "Gruppen" dialog in the `usr` module ([0014](0014-admin-user-management.md),
[0015](0015-split-admin-user-management-module.md)) lets an admin toggle an existing user's
membership in each usergroup, but there was no UI anywhere to create, rename or delete a
usergroup itself — `fis_usergroups` could only be populated by running a raw SQL script by hand
(`hlp/db/create user group.sql`). The DB-layer proc `fis_admin_setUserGroup` (create/rename) and
the read-side `fis_admin_getUserGroupList` already existed but were wired to no controller
endpoint, mirroring the exact gap [0020](0020-user-management-create-and-delete.md) closed for
user accounts.
While wiring this up, three of the four `fis_admin_*` group-write procedures were found missing
the module's standard `intranet_admin` authorization check entirely (`fis_admin_addGroupMember`,
`fis_admin_remGroupMember`, `fis_admin_delUserGroup`) — a caller with `fds_sys > 4` but no
`intranet_admin` setting could add/remove a user's group membership or delete a group outright,
the same real authorization hole 0020 fixed for `fis_admin_delUserAccount`. `fis_admin_setUserGroup`
already had the check.
## Decision
- **New standalone module, `fn=usrgrp`** (`IntranetController.AdminGroups.cs`,
`fis.usrgrp.js`/`fis.usrgrp_txt_de.js`/`fis.usrgrp.scss`), added as a third entry in the existing
"Administration" sidemenu dropdown alongside Benutzerverwaltung and Systemüberwachung — per
[0015](0015-split-admin-user-management-module.md)'s own stated consequence that any future
admin-only feature should default to its own module under that dropdown rather than be folded
into an existing one. The dropdown itself already stays visible while any of its children is
open, so switching between Gruppenverwaltung and Benutzerverwaltung needs no dedicated "back"
control.
- **Same dual-authorization gate as every other module under this dropdown**: `fds_sys > 4`
server-side (`AdminMinAuthExclusive`/`GetSystemAdminAuthAsync`, shared from
`IntranetController.Admin.cs`) gates whether the module is reachable/visible at all;
`fis_admin_getUserAuth(@authaccount) > 1` (the `intranet_admin` setting) independently gates
every read/write the `fis_admin_*` procs perform. Both together are what "only admins can see
and change groups" means in this codebase — see the Consequences below for why this is enforced
in four places, not one.
- **New `id` cases in `Do_Process_AdminGroups`**: `list` → `fis_admin_getUserGroupList`, `create`/
`rename` → `fis_admin_setUserGroup` (same proc; `rename` supplies an existing `@usergroup_id`),
`delete` → `fis_admin_delUserGroup`. No membership editing here — that stays in the `usr`
module's existing per-user checkbox dialog, unchanged.
- **Closed the missing `intranet_admin` gate** on `fis_admin_addGroupMember`,
`fis_admin_remGroupMember` and `fis_admin_delUserGroup` by adding the same
`fis_admin_getUserAuth(@authaccount) > 1` guard `fis_admin_setUserGroup` already had, following
the same "no-op instead of error" style 0020 used for `fis_admin_delUserAccount`: a caller
without `intranet_admin >= 2` gets an unmodified result set / a `false` success bit, not a SQL
error, consistent with every other `fis_admin_*` proc in this area.
- **Frontend** mirrors `fis.usr.js`'s list+ribbon pattern (`renderLst`/`eM`/`iMn`): a card-style
row list with a base ribbon button ("Anlegen") and a per-row ribbon ("Umbenennen"/"Löschen") on
row selection, using `$ocms.dlgform` for create/rename and a `confirm(...)` guard (no dialog) for
delete — the same choice 0020 made for deleting a user account.
## Consequences
- Deleting a group does **not** guard against it still having members — its `fis_usergroups_members`
rows simply stop being returned (the membership query already filters on the group's own
`DateDeleted`). No UI currently surfaces "this group has N members" before deletion; acceptable
since deletion is a soft-delete and the group row can be recreated with the same effective
membership restored via `fis_admin_addGroupMember` if this turns out to matter in practice.
- Four separate `fis_admin_*` procs/functions now each independently re-check
`intranet_admin > 1` (`getUserGroupList`, `setUserGroup`, `delUserGroup`, `addGroupMember`,
`remGroupMember` — five, in fact) rather than a single shared gate; this is the established
style in this codebase (every `fis_admin_*` object re-checks for itself, see 0014) and not
something this change revisits.
- Same operational note as 0014/0015/0020: an account needs **both** `fds_sys > 4` and
`intranet_admin >= 2` to actually manage groups, not obvious from the UI.
## Alternatives considered
- **Extend the existing per-user "Gruppen" dialog** with an inline "new group" input and a
delete icon per row, instead of a new module. Rejected per explicit user direction — the user
asked for a dedicated sidemenu entry for group management, separate from the per-user dialog.
- **Fold into the `usr` module** as a second ribbon button. Rejected for the same reason 0015
split `usr` off `admin` in the first place: two unrelated concerns (managing individual user
accounts vs. managing the group catalog) behind one button was already identified as a mistake
once it happened once; the "own module under the dropdown" default from 0015 applies directly.