refactor: config + lldaplib 收敛到 LLDAP 形态(读只读、删 OpenLDAP 写路径与密码包)
- config 重写:删 user-ou/inactive-ou/group-root-* / group-object-class / group-member-attr / initial-password;新增 lldap 写通道 + webhook + confirm-base-url + 两套 schedule + guard - ldaplib 收拢为只读:属性常量/DN 归入 attrs.go;删 ops.go 写路径与 internal/password - config.example.yml 重写成 LLDAP 形态 - 组命名修订(呼应 AGENTS.md 约束12):用部门稳定索引 cn=<dept_id> 做组身份, mirror_departments 增 group_id 列并跨快照保留,可读中文名只走 DB 展示
This commit is contained in:
@@ -40,18 +40,7 @@ func NewEntry(dn string, attrs map[string]string, members []string) *Entry {
|
||||
return e
|
||||
}
|
||||
|
||||
// userReadAttrs 是读取用户条目时需要取回的属性。
|
||||
// 刻意不读 userPassword:同步永远不需要比对或改写密码。
|
||||
var userReadAttrs = []string{
|
||||
AttrUID, AttrCN, AttrSN, AttrGivenName, AttrDisplayName, AttrMail,
|
||||
AttrMobile, AttrEmployeeNumber, AttrDepartmentNumber, AttrPostalAddress,
|
||||
AttrBusinessCategory, AttrEmployeeType, AttrDescription,
|
||||
}
|
||||
|
||||
// groupReadAttrs 读取分组时额外取回成员列表,以便检测成员漂移。
|
||||
// groupReadAttrs 读取分组时同时请求两种成员属性与 objectClass。
|
||||
// 缺省的属性不会报错,只是不返回,因此同时请求是安全的。
|
||||
var groupReadAttrs = []string{AttrCN, AttrDescription, AttrObjectClass, AttrMember, AttrUniqueMember}
|
||||
// userReadAttrs / groupReadAttrs 的定义见 attrs.go。
|
||||
|
||||
// ListUsers 读取某个 OU 下的全部用户条目(不递归)。
|
||||
func (c *Conn) ListUsers(ouDN string) (map[string]*Entry, error) {
|
||||
@@ -74,10 +63,11 @@ func (c *Conn) ListUsers(ouDN string) (map[string]*Entry, error) {
|
||||
}
|
||||
|
||||
// ListGroups 读取指定子树下的全部分组条目,按 DN 小写为键。
|
||||
// LLDAP 分组 objectClass 固定为 groupOfUniqueNames。
|
||||
func (c *Conn) ListGroups(rootDN string) (map[string]*Entry, error) {
|
||||
sr, err := c.conn.Search(ldap.NewSearchRequest(
|
||||
rootDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
|
||||
fmt.Sprintf("(objectClass=%s)", c.group.ObjectClass), groupReadAttrs, nil,
|
||||
fmt.Sprintf("(objectClass=%s)", groupObjectClass), groupReadAttrs, nil,
|
||||
))
|
||||
if err != nil {
|
||||
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
|
||||
@@ -123,28 +113,6 @@ func (c *Conn) ExistsDN(dn string) (bool, error) {
|
||||
return len(sr.Entries) > 0, nil
|
||||
}
|
||||
|
||||
// EnsureOU 确保某个 OU 存在,不存在则创建。用于首次同步时准备 ou=Inactive 等。
|
||||
func (c *Conn) EnsureOU(dn, name string) error {
|
||||
exists, err := c.ExistsDN(dn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
add := ldap.NewAddRequest(dn, nil)
|
||||
add.Attribute(AttrObjectClass, ObjectClassOU)
|
||||
add.Attribute("ou", []string{name})
|
||||
if err := c.conn.Add(add); err != nil {
|
||||
if ldap.IsErrorWithCode(err, ldap.LDAPResultEntryAlreadyExists) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("创建 OU %s 失败: %w", dn, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// entryFrom 把 LDAP 条目转成精简表示。
|
||||
// 单值属性存进 Attributes;多值属性原样保留在 multi 中。
|
||||
func entryFrom(e *ldap.Entry) *Entry {
|
||||
|
||||
Reference in New Issue
Block a user