- 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.
The Gruppenverwaltung module lets a privileged operator see every non-deleted usergroup,
create a new one, rename it, and delete it. It's the catalog-management counterpart to the usr
module's per-user "Gruppen" dialog, which toggles an individual user's membership in these groups
but cannot create/rename/delete the groups themselves. Same sidemenu-visibility and server-side
authorization gate as usr/admin (fds_sys > 4), own fn=usrgrp, own frontend bundle, own
controller partial. See 0021 for why this is a
separate module rather than folded into usr.
How it works
Authorization (two independent axes — same as usr, read 0014 first)
Menu visibility + fds_sys gate — fis_main_menu.js#addAdminMenuButtonsIfAuthorized
checks fds_sys > 4 once and, if authorized, adds the "Administration" sidemenu dropdown with
three entries: Benutzerverwaltung (init:usr), Gruppenverwaltung (init:usrgrp) and
Systemüberwachung (init:admin). Every /do/usrgrp/* endpoint re-checks fds_sys > 4
server-side (Do_Process_AdminGroups, reusing AdminMinAuthExclusive/GetSystemAdminAuthAsync
from IntranetController.Admin.cs) and 401s otherwise.
Separate SQL-layer gate — every fis_admin_* proc/function called below independently
checks the caller's intranet_admin setting via fis_admin_getUserAuth(@authaccount) > 1. An
account with fds_sys > 4 but no intranet_admin setting reaches every usrgrp endpoint but
gets empty results / silent no-op writes — not an error. This also applies to
fis_admin_addGroupMember/remGroupMember (used by the usr module's membership dialog,
documented there) — all five group-related fis_admin_* write/read objects now carry this
check as of 0021, which closed a real gap where
three of them had none.
Request flow
click "Gruppenverwaltung" → $ocms.init('usrgrp')
POST /do/usrgrp/auth → { manage, level } (manage>0 ⇒ authorized)
load /web/fis.usrgrp.de.js + /web/fis.usrgrp.css
$ocms.usrgrp.init2() → init3() → renderLst()
POST /do/usrgrp/list → { groups: [...] } every non-deleted group
base ribbon (eM) → "Anlegen" (always available)
POST /do/usrgrp/create {name} → { ok, usergroup_id, name }
row click → per-row ribbon (iMn): Umbenennen / Löschen
POST /do/usrgrp/rename {usergroup_id, name} → { ok, usergroup_id, name }
POST /do/usrgrp/delete {usergroup_id} → { ok }
Backend (IntranetController.AdminGroups.cs)
list → fis_admin_getUserGroupList(@authaccount, NULL), all non-deleted groups with
decrypted names.
create/rename → both call fis_admin_setUserGroup(@authaccount, @usergroup_id, @name, @enc_key); create passes @usergroup_id = NULL (the proc generates a new id via
fis_fn_id), rename passes the existing id.
delete → fis_admin_delUserGroup(@authaccount, @usergroup_id) (soft-delete: sets
UserDeleted/DateDeleted). No check for remaining members — a deleted group's membership
rows simply stop being returned by fis_admin_getUserGroupMembership (filtered on the group's
own DateDeleted), see 0021 Consequences.
Same list+ribbon pattern as fis.usr.js: renderLst builds a single-column card-style row list;
a row click toggles .selected and swaps the #topbar ribbon between the base ribbon (eM:
"Anlegen") and the per-row actions (iMn: Umbenennen/Löschen). createDlg/renameDlg use
$ocms.dlgform; deleteGroup follows the confirm(...)-before-destructive-action pattern (no
dialog, nothing to collect beyond the confirmation).