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

6.0 KiB

status, date, applyTo, supersededBy
status date applyTo supersededBy
Accepted 2026-09-16
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

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, 0015) 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 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'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.