test: 集成测试改用真 LLDAP 容器;修复两处物化缺陷
- 集成测试重构:syncer e2e/materialize、ldaplib 读路径、lldapgql 全改用本地 LLDAP 容器(LDAP 3890 / GraphQL /api/graphql 17170),删旧 OpenLDAP 断言 - 修复 1:ActiveUsers 不填 DepartmentIDs(存于关系表),BuildFromMirror 拿到空成员; 新增 ActiveUsersWithDepts,物化 plan 用之 - 修复 2:deleted 用户重新可见后不回 active,无法重建;RevertToActive 纳入 deleted, 快照 reconcile 对其置回 active + 作废 token - 关键安全回归单测保留并配变异验证:未确认不删、非受管不删、admin 永不移出、 删除最后阶段、绝不碰密码。全量单测+vet+集成全绿
This commit is contained in:
@@ -257,12 +257,13 @@ func (s *Store) MarkDeleted(uid string) error {
|
||||
|
||||
// RevertToActive 用户重新在飞书可见:撤销离职流程回 active。
|
||||
//
|
||||
// 只有真正进入删除(deleted)后的用户不能回退——他已经从 LLDAP 删了,
|
||||
// 下一轮物化会以「重建」处理。还在双确认流程内的都可回退。
|
||||
// 覆盖 deleted:已从 LLDAP 物理删除的用户再次可见意味着重新入职,置回 active
|
||||
// 后物化会以「重建」把它再写进 LLDAP。仍在双确认流程内的(candidate/pending/
|
||||
// confirmed)同样回退,未用 token 由调用方一并作废。
|
||||
func (s *Store) RevertToActive(uid string) error {
|
||||
return s.db.Model(&MirrorUser{}).
|
||||
Where("uid = ? AND state IN ?", uid,
|
||||
[]string{StateLeaveCandidate, StatePendingConfirm, StateConfirmedLeave}).
|
||||
[]string{StateLeaveCandidate, StatePendingConfirm, StateConfirmedLeave, StateDeleted}).
|
||||
Update("state", StateActive).Error
|
||||
}
|
||||
|
||||
@@ -278,6 +279,25 @@ func (s *Store) ActiveUsers() ([]*MirrorUser, error) {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ActiveUsersWithDepts 返回在职用户并填充各自的 DepartmentIDs(来自关系表)。
|
||||
//
|
||||
// DepartmentIDs 存于 mirror_user_departments,不落 MirrorUser.DepartmentIDs;
|
||||
// 物化期望状态(BuildFromMirror 的组归属)依赖它,必须在此补齐。
|
||||
func (s *Store) ActiveUsersWithDepts() ([]*MirrorUser, error) {
|
||||
users, err := s.ActiveUsers()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, u := range users {
|
||||
ids, err := s.UserDeptIDs(u.UID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u.DepartmentIDs = ids
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// UsersByState 返回指定生命周期状态的全部用户。
|
||||
func (s *Store) UsersByState(state string) ([]*MirrorUser, error) {
|
||||
var out []*MirrorUser
|
||||
|
||||
@@ -175,11 +175,11 @@ func TestStateMachine(t *testing.T) {
|
||||
if err := st.ToPendingConfirm("alice"); err == nil {
|
||||
t.Errorf("deleted 状态的用户应无法转 pending_confirm,却成功了")
|
||||
}
|
||||
// deleted 后 revert 不应生效(已物理删除,不能回退,交给「重建」处理)。
|
||||
// 已删除用户重新在飞书可见:revert 置回 active(重新入职/重建)。
|
||||
if err := st.RevertToActive("alice"); err != nil {
|
||||
t.Fatalf("RevertToActive 不应报错: %v", err)
|
||||
}
|
||||
assertState(t, st, "alice", StateDeleted)
|
||||
assertState(t, st, "alice", StateActive)
|
||||
|
||||
// 双确认流程内可回退(重新入职)。
|
||||
if err := st.ReplaceMirror(&MirrorSnapshot{
|
||||
|
||||
Reference in New Issue
Block a user