From 6f9896d12eff0dac7a03d25cdb8d9128353e3e25 Mon Sep 17 00:00:00 2001 From: zuevav Date: Wed, 7 Oct 2026 08:03:16 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D1=82=D0=B5=D0=BB=D0=B8=20=D0=B2=20=D0=BD=D0=B0=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=D1=85=20=E2=80=94=20=D0=BA?= =?UTF-8?q?=D0=B0=D0=BA=20=D0=B2=20=D0=BC=D0=B0=D1=81=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=B5:=20=D0=BF=D1=80=D0=BE=D1=81=D1=82=D0=BE=D0=B9=20=D0=B2?= =?UTF-8?q?=D0=B8=D0=B4=20=D0=B8=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=B9=20=D0=BF=D0=BE=D0=B4=20=D1=80?= =?UTF-8?q?=D0=B0=D1=81=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Блок «Учётные записи» мастера вынесен в part_accounts.html (accountsAdd, accountsAD) и стоит и в мастере, и в Настройка → Пользователи: роли плитками, создать сотрудника (с модулями), сотрудники и группы из домена. - Список сотрудников: строка — кружок, имя, логин, источник, последний вход, роль; «Изменить» раскрывает правку (имя, e-mail, роль, пароль, модули, «может входить»), «Удалить сотрудника» — тихой ссылкой с подтверждением. - «Расширенные настройки» под раскрытием: роли и права, домен вручную (контроллер, Base DN, сертификат ЦС, служебная запись, группы → роли, роль по умолчанию, время сессии), проверка входа, перепроверка групп; подписи укорочены, поля в ряд. - Ссылки-кнопки (dq-link, «убрать») одинаковые в настройках и мастере. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi --- internal/lkgateway/admin.go | 6 + .../lkgateway/web/templates/admin_setup.html | 112 ++++++------- .../lkgateway/web/templates/admin_wizard.html | 150 +----------------- internal/lkgateway/web/templates/layout.html | 73 +++++++++ .../web/templates/part_accounts.html | 117 ++++++++++++++ 5 files changed, 254 insertions(+), 204 deletions(-) create mode 100644 internal/lkgateway/web/templates/part_accounts.html diff --git a/internal/lkgateway/admin.go b/internal/lkgateway/admin.go index d761e6f..e0b654b 100644 --- a/internal/lkgateway/admin.go +++ b/internal/lkgateway/admin.go @@ -87,6 +87,12 @@ var templateFuncs = template.FuncMap{ v, certs := setupProbes(globalRC) return v != "" && certs > 0 }, + "avatarLetter": func(s string) string { // первая буква имени — для кружка в списке сотрудников + for _, r := range strings.TrimSpace(s) { + return strings.ToUpper(string(r)) + } + return "?" + }, "adDraft": adDraftForView, // неудачная попытка подключить домен — форма открывается заполненной "withRet": func(d any, ret string) map[string]any { return map[string]any{"D": d, "Ret": ret} }, "whForm": func(w WorkHoursSettings, ret string) map[string]any { return map[string]any{"W": w, "Ret": ret} }, diff --git a/internal/lkgateway/web/templates/admin_setup.html b/internal/lkgateway/web/templates/admin_setup.html index fbe5b0b..5f9c41b 100644 --- a/internal/lkgateway/web/templates/admin_setup.html +++ b/internal/lkgateway/web/templates/admin_setup.html @@ -107,51 +107,60 @@
{{$U := .Users}}{{$A := .Settings.Auth}}

Пользователи и вход

-

Кто может входить в bj и что ему разрешено. Вход — локальной учётной записью или доменной (Active Directory), роль доменного пользователя назначается по его группам AD.

+

Кто может входить в bj и что ему разрешено. Сотрудник входит своей учётной записью bj или доменной (Active Directory) — тогда пароль проверяет домен.

{{if $U.Open}}
Вход пока не требуется: пользователи не созданы. Создайте первого администратора — после этого все страницы потребуют входа.
{{end}}
-

Роли

+

Сотрудники ({{len $U.Users}})

+ {{if $U.Users}}
+ {{range $U.Users}} +
+ + + {{if .Name}}{{.Name}}{{else}}{{.Login}}{{end}}{{.Login}}{{if .Email}} · {{.Email}}{{end}} · {{if eq .Source "ad"}}доменная учётная запись{{else}}пароль в bj{{end}} · {{if not .LastLogin.IsZero}}вход {{msk .LastLogin}}{{else}}ещё не входил{{end}} + {{if not .Active}}заблокирован{{end}} + {{if $U.RoleShown .Role}}{{roleTitle .Role}}{{else}}{{$U.RoleNote .Role}}{{end}} + Изменить + +
+ + + + + {{if eq .Source "local"}}{{else}}
Пароль проверяет домен{{if .ADGroups}} · группы: {{range $i,$g := .ADGroups}}{{if $i}}, {{end}}{{$g}}{{end}}{{end}}{{if .Note}} · {{.Note}}{{end}}
{{end}} +
{{$m := .Modules}}{{range $U.Modules}}{{end}} +
+
+
+
+
+ {{end}}
{{else}}

Пока никого — добавьте сотрудника ниже.

{{end}} +
+ +
+

{{if $U.Open}}Создать первого администратора{{else}}Добавить сотрудника{{end}}

+ {{template "accountsAdd" (withRet . "/admin/setup")}} + {{template "accountsAD" (withRet . "/admin/setup")}} +
+ +
+

Активные сессии ({{len $U.Sessions}})

+ {{if $U.Sessions}} + {{range $U.Sessions}} + {{end}} +
ПользовательВходАктивностьАдресБраузер
{{.Login}}{{msk .Created}}{{msk .Seen}}{{.IP}}{{.UA}}
{{else}}

Сессий нет.

{{end}} +
+ +
+
+ Расширенные настройкироли и права, домен вручную: контроллер, сертификат, группы, перепроверка, время сессии +

Роли и права

{{range $U.Roles}}{{end}} {{range $U.Hidden}}{{end}}
РольЧто разрешено
{{.Title}}
{{.Key}}
{{.Desc}}
{{.Title}}Недоступна: в лицензии нет модуля «{{.Missing}}».

{{if $U.Modules}}Подключённые модули ({{range $i, $m := $U.Modules}}{{if $i}}, {{end}}«{{$m.Title}}»{{end}}) можно выдать любому пользователю дополнительно к роли. {{end}}Роли и модули показываются по лицензии: права модуля, которого нет в лицензии, не действуют. Настройки и пользователи — только администратор.

-
- -
-

Пользователи ({{len $U.Users}})

- {{range $U.Users}} -
- -
{{.Login}} {{if eq .Source "ad"}}AD{{end}}{{if not .Active}}заблокирован{{end}}
-
{{if not .LastLogin.IsZero}}вход {{msk .LastLogin}}{{else}}ещё не входил{{end}}{{if .Note}} · {{.Note}}{{end}}
- {{if .ADGroups}}
группы: {{range $i,$g := .ADGroups}}{{if $i}}, {{end}}{{$g}}{{end}}
{{end}}
- - - -
-
- {{else}}

Пользователей нет.

{{end}} - -

{{if $U.Open}}Создать первого администратора{{else}}Добавить пользователя{{end}}

-
- - - - - - - {{if $U.Modules}}{{end}} -
-
-

Доменного пользователя можно заранее завести с источником «Active Directory», чтобы выдать ему модули; роль при входе возьмётся из групп AD. Если потерян доступ администратора — удалите файл /var/lib/bj/.bj/users.json на сервере: система вернётся в режим первичной настройки.

-
- -
-

Вход через Active Directory

+

Вход через Active Directory

bj подключается к контроллеру домена и проверяет пароль пользователя (LDAP bind его же учётной записью). Роль назначается по членству в группах AD, включая вложенные. Пользователь появляется в списке при первом входе. Чтобы изменения групп действовали без повторного входа, укажите сервисную учётную запись только на чтение: bj будет перечитывать группы доменных пользователей по расписанию, менять роль и снимать доступ у удалённых из групп.

@@ -159,19 +168,19 @@
- +
- +
- - + +
-
Группы AD → роли (имя группы или полный DN; первое совпадение сверху)
+
Группы домена → роли имя группы или полный DN; действует первое совпадение сверху
{{range $A.ADGroups}}
{{end}} {{range $i := list "1" "2"}}
{{end}} @@ -181,30 +190,23 @@
-
+
- {{with adDraft}}{{template "adTrustCard" (withRet . "")}}{{end}}
- + - +

Без логина и пароля проверяется только доступность контроллера. С логином — вход, группы и вычисленная роль. Пароль проверки никуда не сохраняется.

{{$R := $U.ADRecheck}}
{{if and $A.ADEnabled $A.ADBindUser $A.ADBindPassword}} Перепроверка групп каждые {{if $A.ADRecheckMinutes}}{{$A.ADRecheckMinutes}}{{else}}15{{end}} мин: {{if $R.At.IsZero}}ещё не выполнялась{{else}}последняя {{msk $R.At}}, проверено {{$R.Checked}}, изменений {{$R.Changed}}{{if $R.Err}} — ошибка: {{$R.Err}}{{end}}{{end}} -
+
{{else}}Перепроверка групп выключена: роль доменного пользователя меняется только при следующем входе. Укажите сервисную учётную запись выше.{{end}}
-
- -
-

Активные сессии ({{len $U.Sessions}})

- {{if $U.Sessions}} - {{range $U.Sessions}} - {{end}} -
ПользовательВходАктивностьАдресБраузер
{{.Login}}{{msk .Created}}{{msk .Seen}}{{.IP}}{{.UA}}
{{else}}

Сессий нет.

{{end}} +

Если потерян доступ администратора — удалите файл /var/lib/bj/.bj/users.json на сервере: система вернётся в режим первичной настройки.

+
diff --git a/internal/lkgateway/web/templates/admin_wizard.html b/internal/lkgateway/web/templates/admin_wizard.html index db0a35b..f328c32 100644 --- a/internal/lkgateway/web/templates/admin_wizard.html +++ b/internal/lkgateway/web/templates/admin_wizard.html @@ -61,7 +61,6 @@ .keywiz .card h2 { font-size:16px; margin:0 0 6px; } .keywiz form .btn-ok, .keywiz form .btn-secondary { justify-self:start; border-radius:999px; padding:10px 22px; font-weight:600; } .keywiz form .btn-ok { background:var(--accent); border-color:var(--accent); } -.wiz-card .dq-link { background:none; border:0; padding:0; color:var(--accent); font-size:12.5px; font-weight:500; cursor:pointer; border-radius:4px; } /* ход подготовки: строки шагов со значком состояния */ .tooltip { display:inline-block; background:var(--border); color:var(--muted); border-radius:50%; width:16px; height:16px; line-height:16px; text-align:center; font-size:11px; cursor:help; margin-left:4px; } .help-block { background:var(--accent-weak); padding:10px 14px; margin:10px 0; font-size:13px; border-radius:10px; } @@ -651,154 +650,7 @@

Учётные записи

У каждого, кто работает с bj, — своя учётная запись: свой пароль и свои права, а в журнале видно, кто что сделал. Заведите сотрудников по ролям; права, пароли и вход через Active Directory меняются позже в разделе Настройка → Пользователи.

- - {{with .Fancy}}{{$U := .Users}} -
- - -

Кого добавить

-
- {{range $r := $U.Roles}} - - {{end}} -
-
- - - -
-
-
-

Пароль передайте сотруднику лично; сменить его можно в разделе Настройка → Пользователи.

-
-
- {{$A := .Settings.Auth}}{{$D := adDraft}}{{$on := and $A.ADEnabled $A.ADBindUser}} -
- Сотрудники из домена (Active Directory) — необязательно - {{if $on}} -
Домен {{$A.ADDomain}} подключёнконтроллер {{$A.ADServerHost}} · служебная запись {{$A.ADBindUser}}{{if $A.ADCAPEM}} · сертификат контроллера проверяется{{end}}
- -
-
    - - - {{if $A.ADGroups}}
    Группы домена с доступом в bj — их сотрудники входят без отдельной учётной записи:
    - {{range $A.ADGroups}}
    {{.Name}} → {{roleTitle .Role}} -
    {{end}} -
    {{end}} - - {{end}} -
    {{if and $A.ADEnabled $A.ADBindUser}}Другой домен или учётная запись{{else}}Подключить домен{{end}} - {{/* пароль в страницу не попадает никогда — только пометка, что он есть */}} - {{$bu := $A.ADBindUser}}{{$pw := ""}}{{if $A.ADBindPassword}}{{$pw = "задан"}}{{end}}{{$fs := ""}}{{$fd := ""}}{{$adv := false}} - {{if $D}}{{$bu = $D.BindUser}}{{$pw = ""}}{{if $D.HasPassword}}{{$pw = "введён"}}{{end}}{{$fs = $D.Form.Server}}{{$fd = $D.Form.Domain}}{{$adv = $D.Form.Adv}}{{end}} -

    Введите учётную запись домена и пароль — домен и его контроллеры bj найдёт сам. Прав администратора домена не нужно; лучше отдельная служебная запись (например svc-bj): bj хранит её пароль, чтобы искать сотрудников.

    - -
    - - - -
    Расширенные настройки — если домен не найдётся сам -
    - - -
    -

    Пусто — bj ищет сам. Контроллер можно указать именем (bj попробует LDAPS 636, затем LDAP 389 со StartTLS) или адресом со схемой: ldaps://dc1.corp.example.ru:636.

    -
    -
    -
    - {{if $D}}

    Не подключено: {{$D.Err}}{{if not $D.Cert}} Поправьте и нажмите «Подключить» ещё раз — введённое сохранено.{{end}}

    - {{template "adTrustCard" (withRet $D "/admin/wizard?step=13")}}{{end}} - -
    -
    - + {{with .Fancy}}{{template "accountsAdd" (withRet . "/admin/wizard?step=13")}}{{template "accountsAD" (withRet . "/admin/wizard?step=13")}} {{end}} {{template "wizNav" .}}
    diff --git a/internal/lkgateway/web/templates/layout.html b/internal/lkgateway/web/templates/layout.html index 8c96335..389c7cc 100644 --- a/internal/lkgateway/web/templates/layout.html +++ b/internal/lkgateway/web/templates/layout.html @@ -301,6 +301,78 @@ label { font-size:13px; font-weight:500; } :is(.settings-section, .wiz-card) .grid > div > label:not(:has(input[type=checkbox], input[type=radio])) { display:block; margin:0; } :is(.settings-section, .wiz-card) .grid > div > :is(input:not([type=checkbox]):not([type=radio]):not([type=hidden]), select, textarea) { display:block; width:100%; box-sizing:border-box; margin-top:5px !important; } @media (max-width:820px) { .settings-section.active { padding:20px 18px 18px; } } +/* Учётные записи (part_accounts: мастер и Настройка → Пользователи) */ +.acc-roles{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin:12px 0 4px} +.acc-role{display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border:1px solid var(--border);border-radius:12px;cursor:pointer;font-weight:400;margin:0} +.acc-role:has(input:checked){border-color:var(--accent);background:var(--accent-weak)} +.acc-role input{margin-top:3px;flex:none;width:auto} +.acc-role b{display:block;font-size:14.5px} +.acc-role small{display:block;color:var(--muted);font-size:13px;line-height:1.4;margin-top:3px} +.acc-role .acc-who{display:block;color:var(--text);font-size:12.5px;margin-top:6px} +.acc-form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;max-width:640px;margin-top:12px} +.acc-form label{display:block;margin:0} +.acc-form label input{width:100%;box-sizing:border-box;margin-top:4px} +.acc-pw{display:flex;gap:6px;align-items:flex-end} +.ad-st{display:flex;gap:12px;align-items:center;margin:12px 0 4px;padding:12px 16px;border-radius:12px;border:1px solid var(--border);background:var(--card-2);max-width:640px;box-sizing:border-box} +.ad-st b{display:block;font-size:15px;font-weight:650} +.ad-st small{display:block;color:var(--muted);font-size:13px;line-height:1.4;margin-top:2px;overflow-wrap:anywhere} +.ad-st-ic{flex:none;position:relative;width:26px;height:26px;border-radius:50%;background:var(--border-strong)} +.ad-st-ok{background:color-mix(in srgb,var(--ok) 9%,var(--card));border-color:color-mix(in srgb,var(--ok) 40%,var(--border))} +.ad-st-ok .ad-st-ic{background:var(--ok)} +.ad-st-ok .ad-st-ic::after{content:"";position:absolute;left:50%;top:45%;width:6px;height:11px;border:solid #fff;border-width:0 2.2px 2.2px 0;transform:translate(-50%,-50%) rotate(45deg)} +.ad-st-warn{background:var(--warn-weak);border-color:color-mix(in srgb,var(--warn) 45%,var(--border))} +.ad-st-warn .ad-st-ic{background:var(--warn)} +.ad-st-warn .ad-st-ic::after{content:"!";position:absolute;inset:0;display:grid;place-items:center;color:#fff;font-weight:700;font-size:15px} +.ad-st-spin{background:none;border:2.5px solid var(--accent-weak);border-top-color:var(--accent);box-sizing:border-box;animation:dq-spin .8s linear infinite} +.ad-q-l{display:block;margin:14px 0 0;font-weight:600;font-size:14px;max-width:640px} +.ad-q-l input{display:block;width:100%;box-sizing:border-box;margin-top:6px;font-size:15px !important;font-weight:400} +.ad-res{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:6px;max-width:640px} +.ad-hit{display:flex;gap:10px;align-items:baseline;width:100%;text-align:left;padding:10px 14px;border:1px solid var(--border);border-radius:10px;background:var(--card);color:var(--text);font:inherit;font-size:14px;cursor:pointer} +.ad-hit:hover:not(:disabled){border-color:var(--border-strong)} +.ad-hit.is-sel{border-color:var(--accent);background:var(--accent-weak)} +.ad-hit:disabled{opacity:.6;cursor:default} +.ad-kind{flex:none;font-size:11px;font-weight:600;padding:2px 8px;border-radius:999px;background:var(--card-2);color:var(--muted);border:1px solid var(--border)} +.ad-kind-g{background:var(--accent-weak);color:var(--accent);border-color:transparent} +.ad-pick{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:12px;padding:12px 14px;border:1px solid var(--accent);border-radius:12px;background:color-mix(in srgb,var(--accent-weak) 50%,var(--card));max-width:640px;box-sizing:border-box} +.ad-pick[hidden]{display:none} +.ad-groups{margin-top:16px;max-width:640px} +.ad-grp{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:8px 12px;border:1px solid var(--border);border-radius:10px;margin-top:6px;font-size:14px} +.ad-grp form{margin:0} +@media (max-width:600px){.acc-roles,.acc-form{grid-template-columns:minmax(0,1fr)}} +.acc-mods{display:flex;gap:6px 16px;flex-wrap:wrap;align-items:center;margin:12px 0 0;font-size:13.5px} +.acc-mods label{display:inline-flex;gap:6px;align-items:center;font-weight:400;margin:0;font-size:13.5px} +/* сотрудники в Настройка → Пользователи: строка — кто и с какой ролью, «Изменить» раскрывает правку */ +.usr-list{display:grid;gap:8px;margin-top:10px} +.usr{border:1px solid var(--border);border-radius:12px;background:var(--card)} +.usr[open]{border-color:color-mix(in srgb, var(--accent) 45%, var(--border))} +.usr>summary{display:flex;align-items:center;gap:12px;padding:10px 14px;cursor:pointer;list-style:none} +.usr>summary::-webkit-details-marker{display:none} +.usr>summary:hover .usr-edit{text-decoration:underline} +.usr-av{flex:none;width:34px;height:34px;border-radius:50%;background:var(--accent-weak);color:var(--accent);display:grid;place-items:center;font-weight:700;font-size:14px} +.usr-main{flex:1;min-width:0} +.usr-main b{display:block;font-size:14.5px;font-weight:600} +.usr-main small{display:block;color:var(--muted);font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} +.usr-role{flex:none;font-size:12.5px;font-weight:600;padding:3px 10px;border-radius:999px;background:var(--card-2);border:1px solid var(--border);color:var(--text-2)} +.usr-edit{flex:none;font-size:13px;color:var(--accent);min-width:64px;text-align:right} +.usr[open] .usr-edit{visibility:hidden} +.usr-form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;padding:14px;border-top:1px solid var(--border)} +.usr-form label{display:block;margin:0} +.usr-form label input:not([type=checkbox]), .usr-form label select{display:block;width:100%;box-sizing:border-box;margin-top:5px} +.usr-note{align-self:end;color:var(--muted);font-size:13px;line-height:1.4;padding-bottom:10px} +.usr-checks{grid-column:1/-1;display:flex;gap:6px 18px;flex-wrap:wrap} +.usr-checks label{display:inline-flex;gap:6px;align-items:center;font-weight:400;font-size:13.5px} +.usr-act{grid-column:1/-1;display:flex;justify-content:space-between;align-items:center;gap:8px} +.usr-del{background:none !important;border:0 !important;color:var(--err);font-size:13.5px;font-weight:500;padding:6px 2px;cursor:pointer} +.usr-del:hover{text-decoration:underline} +@media (max-width:600px){.usr-form{grid-template-columns:minmax(0,1fr)} .usr-main small{white-space:normal}} +/* «Расширенные настройки» — под раскрытием, заголовком подблока */ +.adv-box>summary{display:flex;flex-direction:column;gap:2px;cursor:pointer;list-style:none} +.adv-box>summary::-webkit-details-marker{display:none} +.adv-box>summary .sum-h{font-size:16px;font-weight:650;color:var(--accent)} +.adv-box>summary .sum-h::before{content:"▸ ";color:var(--muted)} +.adv-box[open]>summary .sum-h::before{content:"▾ "} +.adv-box>summary .muted{font-size:13px} +.adv-h{font-size:14.5px;font-weight:650;margin:22px 0 8px} @media (max-width:820px) { .settings { grid-template-columns:1fr; } .settings-nav { flex-direction:row; overflow-x:auto; position:static; padding-bottom:8px; } @@ -390,6 +462,7 @@ details:has(> pre.copyable) { min-width:0; max-width:100%; } .dq-box-h { font-weight:600; font-size:14.5px; margin:0 0 10px; } .dq-box-h span { color:var(--muted); font-weight:400; font-size:13px; } .dq-lbl-row { display:flex; justify-content:space-between; align-items:baseline; gap:8px; } +button.dq-link, .dq-link { background:none !important; border:0 !important; padding:0 !important; color:var(--accent) !important; font-size:12.5px; font-weight:500; cursor:pointer; border-radius:4px; box-shadow:none !important; } .dq-link:hover { text-decoration:underline; } .dq-warn { margin:10px 0 0; padding:8px 12px; border-radius:8px; background:var(--warn-weak); color:var(--text-2); font-size:13px; } .dq-run { margin-top:16px; border:1px solid var(--border); border-radius:12px; padding:12px 16px; } diff --git a/internal/lkgateway/web/templates/part_accounts.html b/internal/lkgateway/web/templates/part_accounts.html new file mode 100644 index 0000000..0228365 --- /dev/null +++ b/internal/lkgateway/web/templates/part_accounts.html @@ -0,0 +1,117 @@ +{{/* Учётные записи: добавить сотрудника (роль плиткой, логин, пароль) и сотрудники из домена (подключение, + поиск сотрудников и групп, доступ группам). Общий блок шага мастера «Учётные записи» и раздела + Настройка → Пользователи. Вход: withRet <куда вернуться после сохранения>. */}} +{{define "accountsAdd"}}{{$U := .D.Users}} +
    + + +

    Кого добавить

    +
    + {{range $r := $U.Roles}} + + {{end}} +
    +
    + + + +
    +
    +
    + {{if $U.Modules}}
    Дополнительно к роли:{{range $U.Modules}}{{end}}
    {{end}} +

    Пароль передайте сотруднику лично; сменить его можно позже: Настройка → Пользователи → «Изменить».

    +
    +
    + +{{end}} + +{{define "accountsAD"}} + {{$A := $.D.Settings.Auth}}{{$D := adDraft}}{{$on := and $A.ADEnabled $A.ADBindUser}} +
    + Сотрудники из домена (Active Directory) — необязательно + {{if $on}} +
    Домен {{$A.ADDomain}} подключёнконтроллер {{$A.ADServerHost}} · служебная запись {{$A.ADBindUser}}{{if $A.ADCAPEM}} · сертификат контроллера проверяется{{end}}
    + +
    +
      + + + {{if $A.ADGroups}}
      Группы домена с доступом в bj — их сотрудники входят без отдельной учётной записи:
      + {{range $A.ADGroups}}
      {{.Name}} → {{roleTitle .Role}} +
      {{end}} +
      {{end}} + + {{end}} +
      {{if and $A.ADEnabled $A.ADBindUser}}Другой домен или учётная запись{{else}}Подключить домен{{end}} + {{/* пароль в страницу не попадает никогда — только пометка, что он есть */}} + {{$bu := $A.ADBindUser}}{{$pw := ""}}{{if $A.ADBindPassword}}{{$pw = "задан"}}{{end}}{{$fs := ""}}{{$fd := ""}}{{$adv := false}} + {{if $D}}{{$bu = $D.BindUser}}{{$pw = ""}}{{if $D.HasPassword}}{{$pw = "введён"}}{{end}}{{$fs = $D.Form.Server}}{{$fd = $D.Form.Domain}}{{$adv = $D.Form.Adv}}{{end}} +

      Введите учётную запись домена и пароль — домен и его контроллеры bj найдёт сам. Прав администратора домена не нужно; лучше отдельная служебная запись (например svc-bj): bj хранит её пароль, чтобы искать сотрудников.

      + +
      + + + +
      Расширенные настройки — если домен не найдётся сам +
      + + +
      +

      Пусто — bj ищет сам. Контроллер можно указать именем (bj попробует LDAPS 636, затем LDAP 389 со StartTLS) или адресом со схемой: ldaps://dc1.corp.example.ru:636.

      +
      +
      +
      + {{if $D}}

      Не подключено: {{$D.Err}}{{if not $D.Cert}} Поправьте и нажмите «Подключить» ещё раз — введённое сохранено.{{end}}

      + {{template "adTrustCard" (withRet $D $.Ret)}}{{end}} + +
      +
      +{{end}}