feat(users): add authentication source dropdown to the user form

The add / edit user drawer now exposes a Source select (Local / OIDC /
SAML / CAS) so an admin can flip an existing account between Local
password and an external IdP without touching the database. Mirrors
the matching `PUT /v1/users/{id}` change on the backend.

Password field follows the selected source:

* Hidden when source != Local — those users authenticate via the IdP
  and a local password row would be a /login bypass.
* Required when CREATE-with-Local, or when EDIT is switching an SSO
  user back to Local (the backend rejects SSO -> Local without a
  fresh password to avoid locking the user out of /login).
* Optional when editing an already-Local user, matching today's
  behaviour.

A switch in EDIT mode surfaces a tip explaining the side effect
(password cleared / new password required) so the consequence isn't
hidden. The Source select is disabled on self-edit — same guard the
role column already uses — so an admin can't lock themselves out by
flipping their own row to an external source.

Strings are added to all five locales; the IdP protocol acronyms
(OIDC / SAML / CAS) render verbatim and don't need translation keys.
This commit is contained in:
gitlawr
2026-07-01 15:39:10 +08:00
committed by jialin
parent 8a15172316
commit 350f398cde
8 changed files with 121 additions and 17 deletions
+5
View File
@@ -13,6 +13,11 @@ export default {
'Включить или отключить эту учетную запись пользователя',
'users.form.fullname': 'Полное имя',
'users.form.source': 'Источник',
'users.form.source.local': 'Локальный',
'users.form.source.tip.switchToLocal':
'Переключение на «Локальный» требует ввода нового пароля. После этого пользователь будет входить через стандартную форму входа.',
'users.form.source.tip.switchToExternal':
'Переключение на внешний источник удаляет локальный пароль пользователя. После этого вход будет выполняться через настроенного провайдера идентификации.',
'users.table.user': 'пользователи',
'users.form.admin': 'Администратор',
'users.form.user': 'Пользователь',