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:
2026-09-29 23:48:49 +08:00
parent 10ed3984dc
commit 979a98d502
16 changed files with 387 additions and 1031 deletions
+69
View File
@@ -0,0 +1,69 @@
package ldaplib
// LDAP 属性名与 DN 构造等纯工具,集中在此,供读取与映射共用。
//
// 刻意不含任何写操作:本包定位为 LLDAP 的「读」原语,一切写入走 lldapgql。
// 保留这些常量是因为 diff/映射/预览仍在比对 LDAP 属性,去掉会让比对散落各处。
import (
"github.com/go-ldap/ldap/v3"
)
// 属性名常量。
const (
AttrObjectClass = "objectClass"
AttrUID = "uid"
AttrCN = "cn"
AttrSN = "sn"
AttrGivenName = "givenName"
AttrDisplayName = "displayName"
AttrMail = "mail"
AttrMobile = "mobile"
AttrEmployeeNumber = "employeeNumber"
AttrDepartmentNumber = "departmentNumber"
AttrPostalAddress = "postalAddress"
AttrBusinessCategory = "businessCategory"
AttrEmployeeType = "employeeType"
AttrDescription = "description"
AttrMember = "member"
AttrUniqueMember = "uniqueMember"
AttrUserPassword = "userPassword"
)
// memberAttrs 列出可能承载组成员关系的属性名。
// LLDAP 组对内同时响应 member 与 uniqueMember,读取两种都认,否则会漏掉成员。
var memberAttrs = []string{AttrMember, AttrUniqueMember}
// groupObjectClass 是 LLDAP 分组的 LDAP objectClass。
var groupObjectClass = "groupOfUniqueNames"
// userReadAttrs 是读取用户条目时需要取回的属性。
// 刻意不读 userPassword:同步永远不需要比对或改写密码。
var userReadAttrs = []string{
AttrUID, AttrCN, AttrSN, AttrGivenName, AttrDisplayName, AttrMail,
AttrMobile, AttrEmployeeNumber, AttrDepartmentNumber, AttrPostalAddress,
AttrBusinessCategory, AttrEmployeeType, AttrDescription,
}
// groupReadAttrs 读取分组时额外取回成员列表。
// 同时请求 member 与 uniqueMember 是安全的:缺省的属性不会报错,只是不返回。
var groupReadAttrs = []string{AttrCN, AttrDescription, AttrObjectClass, AttrMember, AttrUniqueMember}
// UserReadAttrs 返回读取用户条目所需的属性列表。
func UserReadAttrs() []string { return append([]string{}, userReadAttrs...) }
// EscapeDN 导出 DN 转义,供拼装 RDN 使用。
func EscapeDN(s string) string { return ldap.EscapeDN(s) }
// EscapeFilter 导出过滤器转义。
func EscapeFilter(s string) string { return ldap.EscapeFilter(s) }
// UserDN 按 uid 与用户 OU 拼接用户 DN。
func UserDN(uid, ouDN string) string {
return "uid=" + EscapeDN(uid) + "," + ouDN
}
// GroupDN 拼接部门组 DN(cn 已含拍平拼音链)。
func GroupDN(cn, parentDN string) string {
return "cn=" + EscapeDN(cn) + "," + parentDN
}