fix: 修复CSP白屏并优化LDAP配置

This commit is contained in:
Logan.Li committed 2026-07-25 22:28:16 +08:00
1 parent a14d9e62e6
commit c7f59f2cbf
12 files changed
+930 -70

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
// Package ldaputil normalizes LDAP server addresses supplied by administrators.
package ldaputil
import (
"fmt"
"net"
"net/url"
"strings"
)
// DialURL accepts an IP address or domain name, with an optional port. Bare
// addresses use LDAPS on port 636. Existing ldap:// and ldaps:// values remain
// supported for backward compatibility.
func DialURL(address string) (string, error) {
address = strings.TrimSpace(address)
if address == "" {
return "", fmt.Errorf("LDAP 服务器地址不能为空")
}
if strings.Contains(address, "://") {
u, err := url.Parse(address)
if err != nil || (u.Scheme != "ldap" && u.Scheme != "ldaps") || u.Host == "" || u.Path != "" || u.RawQuery != "" || u.Fragment != "" {
return "", fmt.Errorf("LDAP 服务器地址格式无效")
}
port := "389"
if u.Scheme == "ldaps" {
port = "636"
}
host, err := withDefaultPort(u.Host, port)
if err != nil {
return "", err
}
u.Host = host
return u.String(), nil
}
host, err := withDefaultPort(address, "636")
if err != nil {
return "", err
}
return "ldaps://" + host, nil
}
func withDefaultPort(address, defaultPort string) (string, error) {
if strings.ContainsAny(address, " \t\r\n/?#@") {
return "", fmt.Errorf("LDAP 服务器地址格式无效")
}
if host, port, err := net.SplitHostPort(address); err == nil {
if host == "" || port == "" {
return "", fmt.Errorf("LDAP 服务器地址格式无效")
}
return address, nil
}
host := strings.TrimSuffix(strings.TrimPrefix(address, "["), "]")
if host == "" || (strings.Contains(host, ":") && net.ParseIP(host) == nil) {
return "", fmt.Errorf("LDAP 服务器地址格式无效")
}
return net.JoinHostPort(host, defaultPort), nil
}
// Hostname returns the hostname or IP for TLS ServerName selection.
func Hostname(dialURL string) string {
u, err := url.Parse(dialURL)
if err != nil {
return ""
}
return u.Hostname()
}
+32
View File
@@ -0,0 +1,32 @@
package ldaputil
import "testing"
func TestDialURL(t *testing.T) {
tests := []struct {
address string
want string
}{
{"8.217.205.92", "ldaps://8.217.205.92:636"},
{"ldap.opsx.vip", "ldaps://ldap.opsx.vip:636"},
{"ldap.opsx.vip:1636", "ldaps://ldap.opsx.vip:1636"},
{"2001:db8::1", "ldaps://[2001:db8::1]:636"},
{"ldap://ldap.opsx.vip", "ldap://ldap.opsx.vip:389"},
{"ldaps://ldap.opsx.vip", "ldaps://ldap.opsx.vip:636"},
{" ldaps://8.217.205.92 ", "ldaps://8.217.205.92:636"},
}
for _, tt := range tests {
got, err := DialURL(tt.address)
if err != nil || got != tt.want {
t.Errorf("DialURL(%q) = %q, %v; want %q", tt.address, got, err, tt.want)
}
}
}
func TestDialURLRejectsInvalidAddress(t *testing.T) {
for _, address := range []string{"", "ldap.opsx.vip/path", "ldap.opsx.vip:", "https://ldap.opsx.vip"} {
if _, err := DialURL(address); err == nil {
t.Errorf("DialURL(%q) succeeded; want error", address)
}
}
}