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:
@@ -101,10 +101,8 @@ func (r *SnapshotRunner) RunSnapshot(ctx context.Context) (*SnapshotRunResult, e
|
||||
|
||||
// buildMirror 把飞书快照转成镜像存储层需要的输入。
|
||||
//
|
||||
// 部门拍平命名与 DN 由 mapping.FlatDeptInfo 一次性算好并持久化到
|
||||
// mirror_departments,物化阶段直接复用、WebUI 亦可展示。
|
||||
// 部门组 DN 用稳定索引派生(mapping.DeptGroupDN),可读中文名只落 name 列供展示。
|
||||
func (r *SnapshotRunner) buildMirror(snap *feishu.Snapshot) *store.MirrorSnapshot {
|
||||
flat := mapping.FlatDeptInfo(snap.Departments, r.cfg.Ldap.BaseDN)
|
||||
deptName := make(map[string]string, len(snap.Departments))
|
||||
for _, d := range snap.Departments {
|
||||
deptName[d.ID] = d.Name
|
||||
@@ -112,10 +110,9 @@ func (r *SnapshotRunner) buildMirror(snap *feishu.Snapshot) *store.MirrorSnapsho
|
||||
|
||||
depts := make([]*store.MirrorDepartment, 0, len(snap.Departments))
|
||||
for _, d := range snap.Departments {
|
||||
f := flat[d.ID]
|
||||
depts = append(depts, &store.MirrorDepartment{
|
||||
DeptID: d.ID, Name: d.Name, PinyinName: f.Chain, DN: f.DN,
|
||||
ParentID: d.ParentID, Level: f.Level, State: store.StateActive,
|
||||
DeptID: d.ID, Name: d.Name, DN: mapping.DeptGroupDN(d.ID, r.cfg.Ldap.BaseDN),
|
||||
ParentID: d.ParentID, Level: deptLevel(d.ID, snap.Departments), State: store.StateActive,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -144,6 +141,28 @@ func (r *SnapshotRunner) buildMirror(snap *feishu.Snapshot) *store.MirrorSnapsho
|
||||
return &store.MirrorSnapshot{Users: users, Departments: depts, Skipped: skipped}
|
||||
}
|
||||
|
||||
// deptLevel 计算部门在树中的层级,根为 0。带步数上限防环。
|
||||
func deptLevel(id string, depts []*feishu.Department) int {
|
||||
byID := make(map[string]*feishu.Department, len(depts))
|
||||
for _, d := range depts {
|
||||
byID[d.ID] = d
|
||||
}
|
||||
depth := 0
|
||||
cur := id
|
||||
for i := 0; i < 64; i++ {
|
||||
d, ok := byID[cur]
|
||||
if !ok || d.ParentID == "" || d.ParentID == "0" {
|
||||
return depth
|
||||
}
|
||||
if _, ok := byID[d.ParentID]; !ok {
|
||||
return depth // 父不在同步范围内,视为根
|
||||
}
|
||||
depth++
|
||||
cur = d.ParentID
|
||||
}
|
||||
return depth
|
||||
}
|
||||
|
||||
// toMirrorUser 把飞书用户域模型转成镜像用户。字段语义与 mapping 一致,
|
||||
// business_category 展开为部门中文名便于人工阅读。
|
||||
func toMirrorUser(u *feishu.User, uid string, deptName map[string]string) *store.MirrorUser {
|
||||
|
||||
Reference in New Issue
Block a user