package lkgateway import ( "errors" "net/http" "net/http/httptest" "net/url" "strings" "testing" ) func TestADDNToDomain(t *testing.T) { if got := adDNToDomain("DC=corp,DC=fontvielle,DC=ru"); got != "corp.fontvielle.ru" { t.Fatal(got) } if v := adVariants("dc1.corp.local"); len(v) != 2 || v[0].url != "ldaps://dc1.corp.local" || !v[1].startTLS { t.Fatalf("%+v", v) } if v := adVariants("ldaps://dc1:636"); len(v) != 1 || v[0].startTLS { t.Fatalf("%+v", v) } } func TestADExplain(t *testing.T) { a := AuthSettings{ADServer: "ldaps://10.10.10.6", ADDomain: "corp.local"} for _, c := range []struct{ err, want string }{ {"x509: cannot validate certificate for 10.10.10.6 because it doesn't contain any IP SANs", "укажите имя контроллера"}, {"x509: certificate is valid for dc1.corp.local, not dc9", "dc1.corp.local"}, {"dial tcp 10.10.10.6:636: connect: connection refused", "порту 636"}, {"dial tcp: lookup dc9.corp.local: no such host", "не находится в DNS"}, } { if got := adExplain(errors.New(c.err), a, nil); !strings.Contains(got, c.want) { t.Errorf("%s → %s", c.err, got) } } } // Контроллер с сертификатом неизвестного центра: введённое не теряется, «Доверять» запоминает сертификат, // прежние настройки входа не портятся. func TestADConnectKeepsDraftAndTrust(t *testing.T) { adDraftClear() defer adDraftClear() dc := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) defer dc.Close() srv := "ldaps://" + strings.TrimPrefix(dc.URL, "https://") rc := testRC(t) h := &setupHandlers{rc: rc} post := func(path string, v url.Values) string { w := httptest.NewRecorder() r := httptest.NewRequest(http.MethodPost, path, strings.NewReader(v.Encode())) r.Header.Set("Content-Type", "application/x-www-form-urlencoded") switch path { case "/admin/setup/users/ad-connect": h.adConnect(w, r) default: h.adTrust(w, r) } loc, _ := url.QueryUnescape(w.Header().Get("Location")) return loc } loc := post("/admin/setup/users/ad-connect", url.Values{"ad_bind_user": {"svc-bj"}, "ad_bind_password": {"pw1"}, "ad_domain": {"corp.test"}, "ad_server": {srv}}) if !strings.Contains(loc, "центром сертификации") { t.Fatalf("нет понятной причины: %s", loc) } d := adDraftForView() if d == nil || d.Cert == nil || d.BindUser != "svc-bj" || !d.HasPassword || d.Form.Server != srv || d.Form.Domain != "corp.test" { t.Fatalf("черновик: %+v", d) } if rc.Snapshot().Auth.ADEnabled || rc.Snapshot().Auth.ADServer != "" { t.Fatal("неудачная попытка изменила настройки входа") } // повтор без пароля — пароль берётся из черновика post("/admin/setup/users/ad-connect", url.Values{"ad_bind_user": {"svc-bj"}, "ad_domain": {"corp.test"}, "ad_server": {srv}}) if a := adDraftAuth(); a == nil || a.ADBindPassword != "pw1" { t.Fatal("пароль из черновика потерян") } // чужой отпечаток не принимается if loc := post("/admin/setup/users/ad-trust", url.Values{"fp": {"00:11"}}); !strings.Contains(loc, "устарел") { t.Fatalf("чужой отпечаток: %s", loc) } fp := adDraftForView().Cert.SHA256 loc = post("/admin/setup/users/ad-trust", url.Values{"fp": {fp}}) if strings.Contains(loc, "центром сертификации") { t.Fatalf("после «Доверять» TLS всё ещё не проходит: %s", loc) } if a := adDraftAuth(); a == nil || a.ADCAPEM == "" { t.Fatal("сертификат не запомнен в черновике") } } // Группа домена из мастера: доступ с ролью, повтор меняет роль (без дублей), «убрать» — снимает. func TestADGroupSave(t *testing.T) { rc := testRC(t) h := &setupHandlers{rc: rc} post := func(v url.Values) { w := httptest.NewRecorder() r := httptest.NewRequest(http.MethodPost, "/admin/setup/users/ad-group", strings.NewReader(v.Encode())) r.Header.Set("Content-Type", "application/x-www-form-urlencoded") h.adGroupSave(w, r) } post(url.Values{"group": {"Depo"}, "role": {"operator"}}) post(url.Values{"group": {"depo"}, "role": {"viewer"}}) g := rc.Snapshot().Auth.ADGroups if len(g) != 1 || g[0].Role != "viewer" { t.Fatalf("группы: %+v", g) } if adGroupRoleOf(rc.Snapshot().Auth, "DEPO") != "viewer" { t.Fatal("роль группы не находится") } post(url.Values{"group": {"Depo"}, "remove": {"1"}}) if len(rc.Snapshot().Auth.ADGroups) != 0 { t.Fatal("группа не убрана") } }