Files
Bridge-and-Join-s/internal/lkgateway/onboarding_test.go
T

147 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package lkgateway
import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func TestAccPrefix(t *testing.T) {
for in, want := range map[string]string{"ВТНКЦ": "ВТНКЦ", " БР ": "БР", "AB_1": "AB_1", "a'b": "", "x%": "", "": ""} {
if got := cleanAccPrefix(in); got != want {
t.Errorf("cleanAccPrefix(%q)=%q, want %q", in, got, want)
}
}
if q := accSQL("LIKE N'{ACC}%'"); !strings.Contains(q, "N'ВТНКЦ%'") {
t.Errorf("accSQL по умолчанию: %s", q)
}
}
func TestDoneNSDUnknownProfile(t *testing.T) {
var s Settings
s.NSD.IGWBaseURL, s.NSD.Profile = "http://localhost:8090", "prod"
if doneNSD(s) {
t.Fatal("профиль prod неизвестен bj — шаг не должен считаться выполненным")
}
s.NSD.Profile = "prod-gost"
if !doneNSD(s) {
t.Fatal("prod-gost — известный профиль")
}
}
func TestStoreCertKindAndExpiry(t *testing.T) {
bundle := map[string]bool{}
own := NSDStoreCert{Kind: "x509", Subject: "O=Предприятие 1046,CN=Сотрудник 1046,INN=078000001046", SubjectCN: "Сотрудник 1046", IssuerCN: "Тестовый УЦ", Serial: "AA01"}
nsd := NSDStoreCert{Kind: "x509", Subject: "O=НКО АО НРД,CN=Петров,INN=007702165310", SubjectCN: "Петров", IssuerCN: "Тестовый УЦ", Serial: "BB02"}
ca := NSDStoreCert{Kind: "x509", SubjectCN: "Тестовый УЦ", SelfSigned: true}
for c, want := range map[*NSDStoreCert]string{&own: "own", &nsd: "counterpart", &ca: "ca"} {
if got := storeCertKind(*c, bundle); got != want {
t.Errorf("%s: %s, want %s", c.SubjectCN, got, want)
}
}
if subjectINN(nsd.Subject) != "7702165310" {
t.Errorf("subjectINN: %q", subjectINN(nsd.Subject))
}
// уведомления: за 20 дней — одно (отметка 30), повторно не шлётся; за 5 дней — следующее (7)
dir := t.TempDir()
certExpiry.file = filepath.Join(dir, "cert-expiry.json")
rc, err := NewRuntimeConfig(filepath.Join(dir, "setup.json"))
if err != nil {
t.Fatal(err)
}
own.NotAfter = time.Now().AddDate(0, 0, 20).Format("02.01.2006")
st := rc.Snapshot().NSDCerts
st.LastStore = []NSDStoreCert{own, nsd, ca}
_ = rc.UpdateNSDCerts(st)
count := func() int { return len(rc.Snapshot().News.Items) }
certExpiryTick(rc)
n1 := count()
certExpiryTick(rc)
if n1 != 1 || count() != 1 {
t.Fatalf("за 20 дней: ожидалось одно уведомление, было %d, затем %d", n1, count())
}
own.NotAfter = time.Now().AddDate(0, 0, 5).Format("02.01.2006")
st.LastStore = []NSDStoreCert{own}
_ = rc.UpdateNSDCerts(st)
certExpiryTick(rc)
if count() != 2 {
t.Fatalf("за 5 дней: ожидалось второе уведомление, всего %d", count())
}
raw, _ := os.ReadFile(certExpiry.file)
if !strings.Contains(string(raw), "7") {
t.Fatalf("отметка 7 не сохранена: %s", raw)
}
}
func TestSafeReturnPathKeepsStep(t *testing.T) {
for in, want := range map[string]string{
"/admin/wizard?step=4": "/admin/wizard?step=4",
"/admin/wizard?step=3&sub=done&flash=x": "/admin/wizard?step=3&sub=done",
"/admin/setup#sec-org": "/admin/setup",
"/admin/wizard?step=4%0d%0aX": "/admin/wizard",
"//evil.example/admin": "",
"/admin/x?a=<script>": "/admin/x",
} {
if got := safeReturnPath(in); got != want {
t.Errorf("safeReturnPath(%q)=%q, want %q", in, got, want)
}
}
}
func TestFirstRunRestoreNeedsCode(t *testing.T) {
if !authExempt("/first-run/backup/list") || authExempt("/first-runx") {
t.Fatal("пути восстановления при первичной настройке должны быть без входа, но не шире")
}
mux := http.NewServeMux()
registerFirstRunRestore(mux)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, httptest.NewRequest(http.MethodPost, "/first-run/backup/restore", strings.NewReader("code=1234&name=2026-10-05_1445")))
if !strings.Contains(rec.Body.String(), `"ok":false`) {
t.Fatalf("без ожидающей первичной настройки восстановление не должно запускаться: %s", rec.Body.String())
}
}
func TestHTTPSSelfSignedAndRedirect(t *testing.T) {
old := tlsDir
tlsDir = t.TempDir()
defer func() { tlsDir = old }()
if err := ensureSelfSigned(false); err != nil {
t.Fatal(err)
}
if cn, until, err := tlsCertInfo(); err != nil || cn == "" || certDaysLeft(until) < 1000 {
t.Fatalf("сертификат: %q %v %v", cn, until, err)
}
if _, err := loadTLSCert(nil); err != nil {
t.Fatal(err)
}
rc, _ := NewRuntimeConfig(t.TempDir() + "/setup.json")
_ = rc.UpdateHTTPS(HTTPSSettings{Redirect: true})
h := httpsRedirect(rc, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusTeapot) }))
cases := []struct {
path, remote string
want int
}{
{"/admin/setup", "10.10.10.5:5000", http.StatusFound},
{"/api/v1/lk/x", "10.10.10.5:5000", http.StatusTeapot},
{"/healthz", "10.10.10.5:5000", http.StatusTeapot},
{"/admin/setup", "127.0.0.1:5000", http.StatusTeapot},
}
for _, c := range cases {
req := httptest.NewRequest(http.MethodGet, "http://10.10.10.6:8080"+c.path, nil)
req.RemoteAddr = c.remote
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Code != c.want {
t.Errorf("%s с %s: %d, ожидалось %d", c.path, c.remote, rec.Code, c.want)
}
if c.want == http.StatusFound && rec.Header().Get("Location") != "https://10.10.10.6:8443/admin/setup" {
t.Errorf("перенаправление: %s", rec.Header().Get("Location"))
}
}
}