[OpenNMS/opennms] f6b7b8: NMS-20106: versioned user management API and Prime...
joseanesONMS via opennms-cvs <[email protected]>
| Newsgroups | gmane.network.opennms.cvs |
|---|---|
| Message-ID | <OpenNMS/opennms/push/refs/heads/jira/NMS-20108-oncall-roles-pr/[email protected]> |
Branch: refs/heads/jira/NMS-20108-oncall-roles-pr
Home: https://github.com/OpenNMS/opennms
Commit: f6b7b8b7bb63caccaf92261f33ccbdb79f3e19d7
https://github.com/OpenNMS/opennms/commit/f6b7b8b7bb63caccaf92261f33ccbdb79f3e19d7
Author: joseanesONMS <[email protected]>
Date: 2026-09-01 (Tue, 01 Sep 2026)
Changed paths:
M opennms-config/src/main/java/org/opennms/netmgt/config/GroupManager.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/UsersRestService.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/api/UsersRestApi.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/UserDto.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/UserPasswordRequest.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/UserRenameRequest.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/UserWriteRequest.java
M opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-default.json
M opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template.json
A opennms-webapp-rest/src/test/java/org/opennms/web/rest/v2/UsersRestServiceIT.java
M opennms-webapp/src/main/webapp/WEB-INF/applicationContext-spring-security.xml
M smoke-test/src/test/java/org/opennms/smoketest/MenuHeaderIT.java
A ui/src/components/ManageUsers/DutyScheduleEditor.vue
A ui/src/components/ManageUsers/UserEditorDialog.vue
A ui/src/components/ManageUsers/UserPasswordDialog.vue
A ui/src/components/ManageUsers/UserRenameDialog.vue
A ui/src/components/ManageUsers/UsersAbout.vue
A ui/src/components/ManageUsers/UsersTable.vue
A ui/src/containers/ManageUsers.vue
M ui/src/main/router/index.ts
M ui/src/services/index.ts
A ui/src/services/userAdminService.ts
A ui/src/stores/userAdminStore.ts
A ui/src/types/userAdmin.ts
A ui/tests/components/AdminDialogs/UserEditorDialog.test.ts
A ui/tests/components/ManageUsers/DutyScheduleEditor.test.ts
A ui/tests/stores/userAdminStore.test.ts
Log Message:
-----------
NMS-20106: versioned user management API and PrimeVue Manage Users page (#8713)
* NMS-20106: versioned user management API and PrimeVue Manage Users page
Adds /api/v2/users (interface + impl following the v2 conventions):
list/get/create/update, dedicated password and rename endpoints, delete,
and available-roles — all admin-only via new Spring Security rules plus
in-code checks. users.xml stays the system of record: updates apply only
the exposed fields, so contact types the API does not carry (XMPP among
them) and the password survive untouched, and passwords are stored
salted via the existing UserManager hashing. Unlike the legacy JSPs,
which only hid the buttons, the admin/rtc delete and rename protections
are enforced server-side; responses never include the password hash
(the v1 API returns it to admins).
The new Manage Users page (ui/#/admin/users) is a straight visualization
of that API: users table without the XMPP column, add/edit dialog with
role assignment, password and rename dialogs, and delete disabled for
the protected system accounts. The Manage Users menu entry now points at
the new page.
* NMS-20106: validation, atomic updates, and tests for the users API
Fixes from self-review. The list fields of UserDto now default to null
so a request that omits them genuinely preserves roles and duty
schedules (empty-list defaults made the preservation guards dead code
and a partial update wiped both). Mutations validate the whole request
first and then apply it to a detached copy of the stored user, so a
rejected request can no longer leave partial changes in UserManager's
shared in-memory state; a failed create rolls the phantom map entry
back, and a service-level lock closes the check-then-act races. Duty
schedule validation accepts overnight ranges (legacy wrote MoTu2000-800
and hand-edited files contain them — rejecting those made such users
uneditable), user ids reject characters that cannot appear in a URL
path segment, a body/path user-id mismatch is rejected instead of
ignored, and HEAD joins the admin-only security rules. The UI keeps the
previous user list when a refresh fails instead of blanking the table.
The IT grows to 14 tests including regressions for omitted-field
preservation, rejected-update atomicity, and overnight schedules.
* NMS-20106: duty schedule runtime semantics, clearable fields, and help
Follow-up from the group-management review, applying the same findings
here. Duty schedules with begin after end are rejected for new entries
(DutySchedule.isInSchedule compares within one calendar day, so an
overnight range never matches); strings already stored on the record
keep round-tripping so hand-edited files never make a user uneditable.
Dot-segment user ids are rejected. Emptied form fields now clear the
value instead of silently preserving it. The service serializes on the
same shared monitor as the groups API because user mutations cascade
into GroupManager. Adds a collapsed "?" help panel explaining what user
accounts are for and how to use the page.
* NMS-20106: validate user fields inline and surface API errors in the dialogs
The dialogs previously reported failures only through a toast that renders
behind the modal overlay, so a rejected save looked like nothing happened.
Mutating service calls now return the server's error message, which the
dialogs display inside the form while staying open; new client-side checks
(shared lib/adminValidation.ts) mirror the server rules for user-ids and
flag malformed email addresses before submitting. Users whose ids contain
/ \ or % (possible in hand-edited users.xml) get their row actions replaced
with a file-managed note, since the security filter rejects those characters
in URL paths. Error toasts now use the error styling.
* NMS-20106: close review findings on the users API and editor
The markup regexes used full-string matches that a newline anywhere
bypassed; they now scan for the characters directly. The admin account can
no longer have ROLE_ADMIN removed (it would lock every administrator out).
applyDto treats omitted scalar fields as preserve, matching the documented
contract and the sibling APIs, so a roles-only PUT no longer wipes names,
comments and contacts. User comments now reject markup like group comments
do, with unchanged hand-edited values grandfathered. Deleting a user who
supervises an on-call role is rejected, since GroupManager leaves the
supervisor attribute dangling. The client email check accepts display-name
and comma-separated recipient forms and, like the comments check, only
fires on changed input so hand-edited values never block the editor.
* NMS-20106: follow the Manage Users menu entry to the new page in MenuHeaderIT
The menu entry now lands on the Vue page, so the smoke test waits for its
page title instead of the legacy JSP breadcrumb.
* NMS-20106: use @opennms/onms-ui wrappers on the Manage Users page
Swap direct PrimeVue components for the Onms-XXX seam wrappers across the
users table and its dialogs: Button->OnmsButton (text/outlined mapped to
variant), Dialog->OnmsDialog, InputText->OnmsInputText,
Password->OnmsPassword, MultiSelect->OnmsMultiSelect, DataTable->OnmsTable,
Column->OnmsColumn, Tag->OnmsTag. Message and IftaLabel have no wrapper
yet and stay on PrimeVue. No behaviour change.
* NMS-20106: address review — route dialog sizing through the OnmsDialog width prop
Replace :style="{ width, maxWidth }" on OnmsDialog (which rode $attrs into
PrimeVue) with the seam's declared width prop, using min(Npx, 95vw) to keep
the responsive cap.
* NMS-20106: carry on-call role supervisor across user rename
GroupManager.renameUser rewrote group memberships and schedule names but
left role.getSupervisor() pointing at the old id, so renaming a supervisor
silently killed the rota's supervisor fallback -- the same dangling-reference
case the delete path guards against. Rewrite the supervisor as part of the
rename so every reference follows the user to the new id.
* NMS-20106: bring Manage Users dialogs onto the current onms-ui seam
Drop the nested primevue IftaLabel from every field and use FormField's own
label/for/required/error props, and replace the direct primevue Message error
banners with a themed role=alert element, so the dialogs no longer import any
un-wrapped PrimeVue primitive. Field errors now render through FormField (the
two test selectors follow the FormField-generated error ids).
* NMS-20106: make the v2 users API pure camelCase JSON
Drop the JAXB annotations from the v2 user model DTOs so they serialize as
plain camelCase JSON (userId, fullName, pagerEmail, userComments, dutySchedules,
roles, readOnly, newUserId) instead of the hyphenated XML element names, and
carry that through the UI types, service, dialogs, and table. The XML mapping
to/from users.xml already lives in the REST service. Also swap the hand-rolled
isBlank/trimToNull helpers for org.apache.commons.lang3.StringUtils and match
the request-field names in the validation messages.
* NMS-20106: finish camelCase column fields on the users table
The Full Name and Pager Email columns still bound to the old hyphenated
field names after the camelCase migration, so they rendered blank; point
them at fullName/pagerEmail. Show '--' for an empty roles cell.
* NMS-20106: adopt the Info-dialog help and overflow-menu row actions
Replace the inline About panel with an Info-icon button in the table header
that opens the help copy in an OnmsDialog (new shared AboutDialogButton), and
collapse the four per-row action buttons to inline Edit and Delete plus a
overflow OnmsMenu carrying Change Password and Rename. Protected-account
disabling and the file-managed note for unaddressable ids are unchanged.
* NMS-20106: point the Manage Users menu entry to the Vue page in the default template too
menu-template-default.json must stay identical to menu-template.json.
* NMS-20106: stop cumulative HTML-escaping of full name and contacts on write
copyOf rebuilt the user through the config-model setters (setFullName,
Contact.setInfo), which run a non-idempotent Encode.forHtml, so every write —
a password change or any unrelated edit — re-escaped the stored value one
layer deeper (O'Brien -> O'Brien -> O&#39;Brien ...). Clone via a JAXB
round-trip (field access bypasses the sanitizing setters), and in applyDto only
write full name / email / pager-email through the setter when the value
actually changed. New IT stores escapable values and asserts a password change
and an unrelated edit leave them byte-for-byte unchanged.
Also fixes the build-ui lint failure (arrow-parens/quote style).
* NMS-20106: bring the Manage Users editor to parity with the legacy page
The new page (now the menu target) edited only name, email, pager-email,
comments and roles, dropping the legacy modifyUser.jsp fields that notifd
relies on. Surface the rest so the menu no longer routes to a lesser editor:
- API: UserDto gains work/mobile/home phone and numeric/text pager service +
PIN; UsersRestService maps them to the workPhone/mobilePhone/homePhone and
numericPage/textPage contacts (info + serviceProvider), writing through the
sanitizing setters only when a value changed. tui-pin, time-zone-id and duty
schedules were already on the DTO.
- UI: the editor adds phones, pager service/PIN, telephone PIN, a time-zone
picker, and an add/remove duty-schedule list.
ITs cover create + partial-update round-trips of the new contacts; editor
tests cover load/save of the new fields and the duty-schedule list.
* NMS-20106: richer duty-schedule editor with day toggles and time pickers
Replace the raw MoWeFr800-1700 text inputs in the user editor with a
DutyScheduleEditor: each coverage window is a row of day toggles (Mo–Su)
plus native begin/end time pickers, parsed from and serialized back to the
canonical schedule string. A hand-edited entry the structured form can't
represent stays editable as raw text so it is never silently dropped.
* NMS-20106: validate tuiPin, roll back failed saves, stop dialog rewrites !smoke
users.xsd constrains tui-pin to [0-9]+ but it was the only field written
unvalidated: a bad PIN entered the in-memory map, failed the schema-validating
marshal, and — with isUpdateNeeded() seeing an unchanged file — wedged every
later user mutation until restart. It is now rejected with a 400 before it
touches the map, and the IT proves a valid write still succeeds after the
rejected one.
updateUser and setPassword get the same rollback discipline createUser
already had: a failed save re-saves the previous state, so a 500 no longer
leaves a new password hash live in memory until a restart quietly reverts it.
The duty-schedule editor no longer rewrites schedules on open: parsed rows
keep their incoming string and serialize it byte-identically until the row
itself is edited, and the watcher only emits when the value actually changes.
The server grandfathers legacy strings byte-identically, so the old
mount-time canonicalization (day order, zero-padding) made such users
unsavable for unrelated edits. Tests cover the non-canonical shape from the
review: no emit on mount, untouched rows survive verbatim, canonicalization
only on a real edit.
Commit: cd11e8e484ba3b677ecb33fcc2d520a254a86ce3
https://github.com/OpenNMS/opennms/commit/cd11e8e484ba3b677ecb33fcc2d520a254a86ce3
Author: Jose Anes <[email protected]>
Date: 2026-09-01 (Tue, 01 Sep 2026)
Changed paths:
M opennms-config/src/main/java/org/opennms/netmgt/config/GroupManager.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/UsersRestService.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/api/UsersRestApi.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/UserDto.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/UserPasswordRequest.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/UserRenameRequest.java
A opennms-webapp-rest/src/main/java/org/opennms/web/rest/v2/model/UserWriteRequest.java
M opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template-default.json
M opennms-webapp-rest/src/main/webapp/WEB-INF/menu/menu-template.json
A opennms-webapp-rest/src/test/java/org/opennms/web/rest/v2/UsersRestServiceIT.java
M opennms-webapp/src/main/webapp/WEB-INF/applicationContext-spring-security.xml
M smoke-test/src/test/java/org/opennms/smoketest/MenuHeaderIT.java
A ui/src/components/ManageUsers/DutyScheduleEditor.vue
A ui/src/components/ManageUsers/UserEditorDialog.vue
A ui/src/components/ManageUsers/UserPasswordDialog.vue
A ui/src/components/ManageUsers/UserRenameDialog.vue
A ui/src/components/ManageUsers/UsersAbout.vue
A ui/src/components/ManageUsers/UsersTable.vue
A ui/src/containers/ManageUsers.vue
M ui/src/main/router/index.ts
M ui/src/services/index.ts
A ui/src/services/userAdminService.ts
A ui/src/stores/userAdminStore.ts
A ui/src/types/userAdmin.ts
A ui/tests/components/AdminDialogs/UserEditorDialog.test.ts
A ui/tests/components/ManageUsers/DutyScheduleEditor.test.ts
A ui/tests/stores/userAdminStore.test.ts
Log Message:
-----------
Merge branch 'develop' of https://github.com/OpenNMS/opennms into jira/NMS-20108-oncall-roles-pr
# Conflicts:
# opennms-webapp/src/main/webapp/WEB-INF/applicationContext-spring-security.xml
# ui/src/main/router/index.ts
# ui/src/services/index.ts
Compare: https://github.com/OpenNMS/opennms/compare/06640b4d5e2b...cd11e8e484ba
To unsubscribe from these emails, change your notification settings at https://github.com/OpenNMS/opennms/settings/notifications
_______________________________________________
Please read the OpenNMS Mailing List FAQ:
http://www.opennms.org/wiki/index.php?page=MailingListFaq
opennms-cvs mailing list
To *unsubscribe* or change your subscription options, see the bottom of this page:
https://lists.sourceforge.net/lists/listinfo/opennms-cvs