diff --git a/internal/lkgateway/keywizard.go b/internal/lkgateway/keywizard.go index 383f889..972bed2 100644 --- a/internal/lkgateway/keywizard.go +++ b/internal/lkgateway/keywizard.go @@ -105,6 +105,39 @@ type keyWizardData struct { Drives []flashDrive SuggestContour string // контур по сертификату в архиве: test3 (издатель «Тестовый УЦ») | prod | "" (не понятно) SuggestIssuer string + WantContour string // контур, для которого открыли установку (кнопка «Установить ключ» у канала) + InWizard bool // блок — на шаге мастера: формы возвращают туда же +} + +// keyWizView — данные блока установки ключа (want — контур, у которого нажали «Установить ключ»). +func (h *setupHandlers) keyWizView(want string, inWizard bool) *keyWizardData { + if h.keyWiz == nil { // обработчики без мастера ключа (тесты) + h.keyWiz = newKeyWizardState() + } + h.keyWiz.mu.Lock() + st := h.keyWiz + h.keyWiz.mu.Unlock() + d := &keyWizardData{State: st, InWizard: inWizard} + if want == "test3" || want == "prod" { + d.WantContour = want + } + if st.StagingID != "" && !st.Done { // список флешек — на шаге выбора носителя (архив уже загружен) + d.Drives = listFlashDrives() + d.SuggestContour, d.SuggestIssuer = keyArchiveContour(filepath.Join("/var/lib/bj/media/iso", st.StagingID)) + } + return d +} + +// keyWizBack — куда вернуться после действия: на шаг мастера (ret=wizard) или на отдельную страницу. +func keyWizBack(r *http.Request) string { + u := "/admin/setup/keywizard?" + if r.FormValue("ret") == "wizard" { + u = "/admin/wizard?step=8&" + } + if c := r.FormValue("want"); c == "test3" || c == "prod" { + u += "contour=" + c + "&" + } + return u } // keyArchiveContour — контур ключа по сертификатам в распакованном архиве (не самоподписанным — это УЦ): @@ -229,25 +262,17 @@ func (h *setupHandlers) renderKeyWizard(w http.ResponseWriter, r *http.Request) } h.keyWiz.mu.Lock() h.keyWiz.Flash = r.URL.Query().Get("flash") - st := h.keyWiz h.keyWiz.mu.Unlock() - // Список флешек нужен на шаге выбора носителя (когда архив уже загружен). - var drives []flashDrive - if st.StagingID != "" && !st.Done { - drives = listFlashDrives() - } - d := keyWizardData{page: nowPage("Установка ключа", "setup"), State: st, Drives: drives} - if st.StagingID != "" && !st.Done { - d.SuggestContour, d.SuggestIssuer = keyArchiveContour(filepath.Join("/var/lib/bj/media/iso", st.StagingID)) - } - render(w, h.tpl.a.keyWizard, d) + d := h.keyWizView(r.URL.Query().Get("contour"), false) + d.page = nowPage("Установка ключа", "setup") + render(w, h.tpl.a.keyWizard, *d) } func (h *setupHandlers) keyWizardReset(w http.ResponseWriter, r *http.Request) { h.keyWiz.mu.Lock() h.keyWiz.reset() h.keyWiz.mu.Unlock() - http.Redirect(w, r, "/admin/setup/keywizard", http.StatusSeeOther) + http.Redirect(w, r, strings.TrimRight(keyWizBack(r), "?&"), http.StatusSeeOther) } // keyWizardUpload — шаг 1: приём .7z + пароль, распаковка, инспекция. @@ -320,7 +345,7 @@ func (h *setupHandlers) keyWizardUpload(w http.ResponseWriter, r *http.Request) h.keyWiz.set(1, "active", "") h.keyWiz.mu.Unlock() - http.Redirect(w, r, "/admin/setup/keywizard", http.StatusSeeOther) + http.Redirect(w, r, strings.TrimRight(keyWizBack(r), "?&"), http.StatusSeeOther) } // keyWizardInstall — шаги 2-5: запись на флешку, справочник, проверка, готово. @@ -427,7 +452,7 @@ func (h *setupHandlers) keyWizardInstall(w http.ResponseWriter, r *http.Request) if dev { final += " Финальная проверка — тестовым документом роботу." } - http.Redirect(w, r, "/admin/setup/keywizard?flash="+urlQ(final), http.StatusSeeOther) + http.Redirect(w, r, keyWizBack(r)+"flash="+urlQ(final), http.StatusSeeOther) } // restartAndVerifyISH перезапускает Интеграционный шлюз и проверяет, что он @@ -635,7 +660,7 @@ func runKeymediaOp(ctx context.Context, action string, fields map[string]string) } func (h *setupHandlers) keyWizFlash(w http.ResponseWriter, r *http.Request, msg string) { - http.Redirect(w, r, "/admin/setup/keywizard?flash="+urlQ(msg), http.StatusSeeOther) + http.Redirect(w, r, keyWizBack(r)+"flash="+urlQ(msg), http.StatusSeeOther) } func fallback(s, def string) string { diff --git a/internal/lkgateway/onboarding_test.go b/internal/lkgateway/onboarding_test.go index f9108b5..c4c0e5d 100644 --- a/internal/lkgateway/onboarding_test.go +++ b/internal/lkgateway/onboarding_test.go @@ -758,3 +758,19 @@ func TestIgateInstallStatus(t *testing.T) { t.Fatalf("готово: %+v", st) } } + +// Установка ключа из мастера возвращает на шаг «Ключ подписи» (с выбранным контуром), со страницы — на страницу. +func TestKeyWizBack(t *testing.T) { + for form, want := range map[string]string{ + "ret=wizard&want=prod": "/admin/wizard?step=8&contour=prod&", + "ret=wizard": "/admin/wizard?step=8&", + "": "/admin/setup/keywizard?", + "want=evil": "/admin/setup/keywizard?", + } { + r := httptest.NewRequest(http.MethodPost, "/admin/setup/keywizard/reset", strings.NewReader(form)) + r.Header.Set("Content-Type", "application/x-www-form-urlencoded") + if got := keyWizBack(r); got != want { + t.Errorf("%q: %q, ожидалось %q", form, got, want) + } + } +} diff --git a/internal/lkgateway/setup.go b/internal/lkgateway/setup.go index 7a828ca..eab2644 100644 --- a/internal/lkgateway/setup.go +++ b/internal/lkgateway/setup.go @@ -185,6 +185,8 @@ type WizardData struct { AutoDone []string // шаги до текущего, уже выполненные без участия пользователя, — с пояснением Certs []cryptocli.Certificate Flash string + KeyWiz *keyWizardData // шаг «Ключ подписи»: установка ключа прямо в мастере + IgateOK bool // ИШ на сервере установлен (ключ ставится в его профиль) // главы мастера (wizchapters.go): путь этой установки, соседние шаги, шапка Path []int Chapters []WizChapter @@ -322,6 +324,9 @@ func (h *setupHandlers) renderWizard(w http.ResponseWriter, r *http.Request) { fd.InWizard = true d.Fancy = &fd } + if step == 8 { + d.KeyWiz, d.IgateOK = h.keyWizView(r.URL.Query().Get("contour"), true), igateInstalled() + } if step == 3 { d.Sub = depoWizardSub(r.URL.Query().Get("sub")) d.DepoUser, d.DepoPass = depoSetupLogin(s.Fancy), s.Fancy.Password diff --git a/internal/lkgateway/web/templates/admin_keywizard.html b/internal/lkgateway/web/templates/admin_keywizard.html index 8c00cc9..f0c5312 100644 --- a/internal/lkgateway/web/templates/admin_keywizard.html +++ b/internal/lkgateway/web/templates/admin_keywizard.html @@ -6,109 +6,7 @@ Загрузите архив НРД → запись на носитель → справочник сертификатов → проверка → готово -{{$s := .State}} - -{{/* ===== Лента шагов ===== */}} -
Ключ установлен на флешку, справочник сертификатов сформирован, Валидата проверена.
- {{if $s.Backup}}Бэкап прежнего носителя: {{$s.Backup}}
Архив распакован. Ключ: {{fallbackTpl $s.VDK "—"}}.
- Выберите носитель — запись сделает бэкап, запишет ключ и справочник
- сертификатов, дотянет CRL и перезапустит ИШ.
Выберите .7z-архив с ключом от НРД и введите пароль архива.
- -Ключ электронной подписи организации для обмена с НРД. Его выдаёт Удостоверяющий центр Московской биржи: вам передадут архив ключа и пароль.
- {{if not .Done.NSD}}{{if .Certs}}Установить другой ключ{{else}}Установить ключ{{end}} архив → носитель → справочник → проверка подписи
+ {{if not .IgateOK}}Ключ установлен на флешку, справочник сертификатов сформирован, Валидата проверена.
+ {{if $s.Backup}}Бэкап прежнего носителя: {{$s.Backup}}
Архив распакован. Ключ: {{fallbackTpl $s.VDK "—"}}.
+ Выберите носитель — запись сделает бэкап, запишет ключ и справочник
+ сертификатов, дотянет CRL и перезапустит ИШ.
Выберите .7z-архив с ключом от НРД и введите пароль архива.
+ +