mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-09 17:37:20 -06:00
Allows an LDAP auth source to list multiple comma-separated servers in the Host field so logins continue working when one server is unreachable. Entries can be plain hosts using the configured Port and Security Protocol fields or `ldap://`, `ldaps://`, or `ldap+starttls://` URLs with their own port and protocol (as proposed in https://github.com/go-gitea/gitea/pull/31649#issuecomment-2505555133), with TLS protocol consistency enforced so an entry cannot silently downgrade encryption. Hosts are tried in order with a 250 ms head start each so an unresponsive server does not block logins for the full 60 s connect timeout, and only connection failures fail over to the next host so failed binds are not retried across servers. Existing single-host configurations continue to work unchanged without a migration. Docs: https://gitea.com/gitea/docs/pulls/635 Fixes https://github.com/go-gitea/gitea/issues/6898 /claim #6898 --------- Co-authored-by: silverwind <me@silverwind.io>
42 lines
1.2 KiB
Go
42 lines
1.2 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package ldap
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/http/httptest"
|
|
"net/netip"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestDial(t *testing.T) {
|
|
silent, err := net.Listen("tcp", "127.0.0.1:0")
|
|
require.NoError(t, err)
|
|
defer silent.Close()
|
|
tlsServer := httptest.NewTLSServer(nil)
|
|
defer tlsServer.Close()
|
|
|
|
conn, err := dial(&Source{Host: " , ldap://127.0.0.1:1 , 127.0.0.1 , ", Port: int(netip.MustParseAddrPort(silent.Addr().String()).Port())})
|
|
require.NoError(t, err)
|
|
conn.Close()
|
|
|
|
start := time.Now()
|
|
conn, err = dial(&Source{Host: fmt.Sprintf("ldaps://%s, ldaps://%s", silent.Addr(), tlsServer.Listener.Addr()), SecurityProtocol: SecurityProtocolLDAPS, SkipVerify: true})
|
|
require.NoError(t, err)
|
|
assert.Less(t, time.Since(start), 10*time.Second)
|
|
conn.Close()
|
|
|
|
_, err = dial(&Source{Host: "ldaps://127.0.0.1:1, ldap://127.0.0.1", SecurityProtocol: SecurityProtocolStartTLS})
|
|
assert.ErrorContains(t, err, "ldaps://127.0.0.1:1: ")
|
|
assert.ErrorContains(t, err, "ldap://127.0.0.1: unsupported LDAP URL")
|
|
|
|
_, err = dial(&Source{Host: " , "})
|
|
assert.EqualError(t, err, "no LDAP host configured")
|
|
}
|