diff --git a/playedu-api/src/main/java/xyz/playedu/api/controller/backend/DepartmentController.java b/playedu-api/src/main/java/xyz/playedu/api/controller/backend/DepartmentController.java index b270aab..0d4457c 100644 --- a/playedu-api/src/main/java/xyz/playedu/api/controller/backend/DepartmentController.java +++ b/playedu-api/src/main/java/xyz/playedu/api/controller/backend/DepartmentController.java @@ -30,20 +30,18 @@ import xyz.playedu.api.request.backend.DepartmentRequest; import xyz.playedu.api.request.backend.DepartmentSortRequest; import xyz.playedu.common.annotation.BackendPermission; import xyz.playedu.common.annotation.Log; +import xyz.playedu.common.bus.LDAPBus; import xyz.playedu.common.constant.BPermissionConstant; import xyz.playedu.common.constant.BusinessTypeConstant; import xyz.playedu.common.context.BCtx; import xyz.playedu.common.domain.Department; import xyz.playedu.common.domain.User; import xyz.playedu.common.exception.NotFoundException; -import xyz.playedu.common.service.AppConfigService; import xyz.playedu.common.service.DepartmentService; import xyz.playedu.common.service.UserService; import xyz.playedu.common.types.JsonResponse; -import xyz.playedu.common.types.LdapConfig; import xyz.playedu.common.types.paginate.PaginationResult; import xyz.playedu.common.types.paginate.UserPaginateFilter; -import xyz.playedu.common.util.ldap.LdapUtil; import xyz.playedu.course.domain.Course; import xyz.playedu.course.domain.UserCourseRecord; import xyz.playedu.course.service.CourseDepartmentService; @@ -70,7 +68,7 @@ public class DepartmentController { @Autowired private ApplicationContext ctx; - @Autowired private AppConfigService appConfigService; + @Autowired private LDAPBus ldapBus; @GetMapping("/index") @Log(title = "部门-列表", businessType = BusinessTypeConstant.GET) @@ -104,7 +102,7 @@ public class DepartmentController { @Log(title = "部门-新建", businessType = BusinessTypeConstant.INSERT) public JsonResponse store(@RequestBody @Validated DepartmentRequest req) throws NotFoundException { - if (appConfigService.enabledLdapLogin()) { + if (ldapBus.enabledLDAP()) { return JsonResponse.error("已启用LDAP服务,禁止添加部门"); } departmentService.create(req.getName(), req.getParentId(), req.getSort()); @@ -124,7 +122,7 @@ public class DepartmentController { @Log(title = "部门-编辑", businessType = BusinessTypeConstant.UPDATE) public JsonResponse update(@PathVariable Integer id, @RequestBody DepartmentRequest req) throws NotFoundException { - if (appConfigService.enabledLdapLogin()) { + if (ldapBus.enabledLDAP()) { return JsonResponse.error("已启用LDAP服务,禁止添加部门"); } Department department = departmentService.findOrFail(id); @@ -136,7 +134,7 @@ public class DepartmentController { @GetMapping("/{id}/destroy") @Log(title = "部门-批量删除", businessType = BusinessTypeConstant.DELETE) public JsonResponse preDestroy(@PathVariable Integer id) { - if (appConfigService.enabledLdapLogin()) { + if (ldapBus.enabledLDAP()) { return JsonResponse.error("已启用LDAP服务,禁止添加部门"); } List courseIds = courseDepartmentService.getCourseIdsByDepId(id); @@ -180,7 +178,7 @@ public class DepartmentController { @DeleteMapping("/{id}") @Log(title = "部门-删除", businessType = BusinessTypeConstant.DELETE) public JsonResponse destroy(@PathVariable Integer id) throws NotFoundException { - if (appConfigService.enabledLdapLogin()) { + if (ldapBus.enabledLDAP()) { return JsonResponse.error("已启用LDAP服务,禁止添加部门"); } Department department = departmentService.findOrFail(id); @@ -202,7 +200,7 @@ public class DepartmentController { @Log(title = "部门-更新父级", businessType = BusinessTypeConstant.UPDATE) public JsonResponse updateParent(@RequestBody @Validated DepartmentParentRequest req) throws NotFoundException { - if (appConfigService.enabledLdapLogin()) { + if (ldapBus.enabledLDAP()) { return JsonResponse.error("已启用LDAP服务,禁止添加部门"); } departmentService.changeParent(req.getId(), req.getParentId(), req.getIds()); @@ -315,57 +313,7 @@ public class DepartmentController { @Log(title = "部门-LDAP同步", businessType = BusinessTypeConstant.INSERT) @SneakyThrows public JsonResponse ldapSync() { - LdapConfig ldapConfig = appConfigService.ldapConfig(); - - List ouList = - LdapUtil.departments( - ldapConfig.getUrl(), - ldapConfig.getAdminUser(), - ldapConfig.getAdminPass(), - ldapConfig.getBaseDN()); - - if (ouList == null || ouList.isEmpty()) { - return JsonResponse.error("部门为空"); - } - - HashMap depIdKeyByName = new HashMap<>(); - Integer sort = 0; - - for (String department : ouList) { - String[] tmp = department.toLowerCase().split(","); - String prevName = ""; - for (String s : tmp) { - // 控制部门排序 - sort++; - // 当前的子部门名 - String tmpName = s.replace("ou=", ""); - // 父部门id - Integer parentId = 0; - // 部门的链名=>父部门1,父部门2,子部门 - String fullName = tmpName; - if (!prevName.isEmpty()) { - fullName = prevName + "," + tmpName; - parentId = depIdKeyByName.get(prevName); - } - - // 检查是否已经创建 - Integer depId = depIdKeyByName.get(tmpName); - if (depId == null) { - // 检查是否已经创建 - Department tmpDep = departmentService.findByName(tmpName, parentId); - if (tmpDep == null) { - // 创建部门 - Integer tmpDepId = departmentService.create(tmpName, parentId, sort); - depIdKeyByName.put(fullName, tmpDepId); - } else { - depIdKeyByName.put(fullName, tmpDep.getId()); - } - } - - prevName = fullName; - } - } - + ldapBus.departmentSync(); return JsonResponse.success(); } } diff --git a/playedu-common/src/main/java/xyz/playedu/common/bus/LDAPBus.java b/playedu-common/src/main/java/xyz/playedu/common/bus/LDAPBus.java new file mode 100644 index 0000000..4e3db8c --- /dev/null +++ b/playedu-common/src/main/java/xyz/playedu/common/bus/LDAPBus.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2023 杭州白书科技有限公司 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package xyz.playedu.common.bus; + +import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import xyz.playedu.common.domain.Department; +import xyz.playedu.common.domain.LdapDepartment; +import xyz.playedu.common.exception.NotFoundException; +import xyz.playedu.common.service.AppConfigService; +import xyz.playedu.common.service.DepartmentService; +import xyz.playedu.common.service.LdapDepartmentService; +import xyz.playedu.common.types.LdapConfig; +import xyz.playedu.common.util.ldap.LdapTransformDepartment; +import xyz.playedu.common.util.ldap.LdapUtil; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import javax.naming.NamingException; + +@Component +@Slf4j +public class LDAPBus { + + @Autowired private AppConfigService appConfigService; + + @Autowired private DepartmentService departmentService; + + @Autowired private LdapDepartmentService ldapDepartmentService; + + public boolean enabledLDAP() { + return appConfigService.enabledLdapLogin(); + } + + public void departmentSync() throws NamingException, NotFoundException { + LdapConfig ldapConfig = appConfigService.ldapConfig(); + + List ouList = + LdapUtil.departments( + ldapConfig.getUrl(), + ldapConfig.getAdminUser(), + ldapConfig.getAdminPass(), + ldapConfig.getBaseDN()); + + if (ouList == null || ouList.isEmpty()) { + return; + } + + // 读取已经同步的记录 + Map ldapDepartments = + ldapDepartmentService.all().stream() + .collect(Collectors.toMap(LdapDepartment::getUuid, e -> e)); + + // 本地缓存表 + HashMap depIdKeyByName = new HashMap<>(); + // 全局排序计数 + Integer sort = 0; + + // 新建+编辑的处理 + for (LdapTransformDepartment ldapTransformDepartment : ouList) { + String uuid = ldapTransformDepartment.getUuid(); + String dn = ldapTransformDepartment.getDn(); + String[] tmpChains = dn.replace("ou=", "").split(","); + String prevName = ""; + + // 同步记录 + LdapDepartment tmpLdapDepartment = ldapDepartments.get(uuid); + if (tmpLdapDepartment != null && tmpLdapDepartment.getDn().equals(dn)) { + // 当前部门已经同步 && 未发生改变 + continue; + } + + // 执行到这里的有两种情况: + // 1.部门未同步 + // 2.部门已同步,但是发生了变化 + // 2.1 部门名称修改 + // 2.2 部门上级修改 + + int length = tmpChains.length; + for (int i = 0; i < length; i++) { + sort++; + int parentId = 0; + + String tmpName = tmpChains[i]; + + // 部门的链名=>父部门1,父部门2,子部门 + String fullName = tmpName; + if (!prevName.isEmpty()) { + fullName = prevName + "," + tmpName; + // 取父级ID + parentId = depIdKeyByName.get(prevName); + } + + // 最后一个记录 && 已存在部门-发生了变动 + if (i + 1 == length && tmpLdapDepartment != null) { + Department tmpDepartment = + departmentService.findOrFail(tmpLdapDepartment.getDepartmentId()); + departmentService.update(tmpDepartment, tmpName, parentId, sort); + } else { + // 检查本地是否有缓存 + Integer depId = depIdKeyByName.get(fullName); + if (depId == null) { + Department tmpDep = departmentService.findByName(tmpName, parentId); + if (tmpDep != null) { + depId = tmpDep.getId(); + } else { + depId = departmentService.create(tmpName, parentId, sort); + // 创建同步记录 + ldapDepartmentService.create(depId, uuid, dn); + } + // 写入本地缓存 + depIdKeyByName.put(fullName, depId); + } + } + + // 父级叠加 + prevName = fullName; + } + } + + // 删除的处理 + List uuidList = ouList.stream().map(LdapTransformDepartment::getUuid).toList(); + List ldapDepartmentList = + ldapDepartmentService.notChunkByUUIDList(uuidList); + for (LdapDepartment ldapDepartment : ldapDepartmentList) { + // 删除本地部门 + departmentService.destroy(ldapDepartment.getDepartmentId()); + // 删除关联记录 + ldapDepartmentService.destroy(ldapDepartment.getId()); + } + } + + public void userSync() {} +} diff --git a/playedu-common/src/main/java/xyz/playedu/common/domain/LdapDepartment.java b/playedu-common/src/main/java/xyz/playedu/common/domain/LdapDepartment.java new file mode 100644 index 0000000..c4e40f3 --- /dev/null +++ b/playedu-common/src/main/java/xyz/playedu/common/domain/LdapDepartment.java @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2023 杭州白书科技有限公司 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package xyz.playedu.common.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; +import java.util.Date; + +@TableName(value = "ldap_department") +public class LdapDepartment implements Serializable { + /** */ + @TableId(type = IdType.AUTO) + private Integer id; + + /** 唯一特征值 */ + private String uuid; + + /** 部门ID */ + @JsonProperty("department_id") + private Integer departmentId; + + /** dn */ + private String dn; + + /** */ + @JsonProperty("created_at") + private Date createdAt; + + /** */ + @JsonProperty("updated_at") + private Date updatedAt; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; + + /** */ + public Integer getId() { + return id; + } + + /** */ + public void setId(Integer id) { + this.id = id; + } + + /** 唯一特征值 */ + public String getUuid() { + return uuid; + } + + /** 唯一特征值 */ + public void setUuid(String uuid) { + this.uuid = uuid; + } + + /** 部门ID */ + public Integer getDepartmentId() { + return departmentId; + } + + /** 部门ID */ + public void setDepartmentId(Integer departmentId) { + this.departmentId = departmentId; + } + + /** dn */ + public String getDn() { + return dn; + } + + /** dn */ + public void setDn(String dn) { + this.dn = dn; + } + + /** */ + public Date getCreatedAt() { + return createdAt; + } + + /** */ + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + /** */ + public Date getUpdatedAt() { + return updatedAt; + } + + /** */ + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass() != that.getClass()) { + return false; + } + LdapDepartment other = (LdapDepartment) that; + return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId())) + && (this.getUuid() == null + ? other.getUuid() == null + : this.getUuid().equals(other.getUuid())) + && (this.getDepartmentId() == null + ? other.getDepartmentId() == null + : this.getDepartmentId().equals(other.getDepartmentId())) + && (this.getDn() == null + ? other.getDn() == null + : this.getDn().equals(other.getDn())) + && (this.getCreatedAt() == null + ? other.getCreatedAt() == null + : this.getCreatedAt().equals(other.getCreatedAt())) + && (this.getUpdatedAt() == null + ? other.getUpdatedAt() == null + : this.getUpdatedAt().equals(other.getUpdatedAt())); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getId() == null) ? 0 : getId().hashCode()); + result = prime * result + ((getUuid() == null) ? 0 : getUuid().hashCode()); + result = prime * result + ((getDepartmentId() == null) ? 0 : getDepartmentId().hashCode()); + result = prime * result + ((getDn() == null) ? 0 : getDn().hashCode()); + result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode()); + result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode()); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + sb.append("Hash = ").append(hashCode()); + sb.append(", id=").append(id); + sb.append(", uuid=").append(uuid); + sb.append(", departmentId=").append(departmentId); + sb.append(", dn=").append(dn); + sb.append(", createdAt=").append(createdAt); + sb.append(", updatedAt=").append(updatedAt); + sb.append(", serialVersionUID=").append(serialVersionUID); + sb.append("]"); + return sb.toString(); + } +} diff --git a/playedu-common/src/main/java/xyz/playedu/common/mapper/LdapDepartmentMapper.java b/playedu-common/src/main/java/xyz/playedu/common/mapper/LdapDepartmentMapper.java new file mode 100644 index 0000000..6cacf70 --- /dev/null +++ b/playedu-common/src/main/java/xyz/playedu/common/mapper/LdapDepartmentMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 杭州白书科技有限公司 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package xyz.playedu.common.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import xyz.playedu.common.domain.LdapDepartment; + +/** + * @author tengyongzhi + * @description 针对表【ldap_department】的数据库操作Mapper + * @createDate 2023-11-13 15:46:06 @Entity xyz.playedu.common.domain.LdapDepartment + */ +public interface LdapDepartmentMapper extends BaseMapper {} diff --git a/playedu-common/src/main/java/xyz/playedu/common/service/LdapDepartmentService.java b/playedu-common/src/main/java/xyz/playedu/common/service/LdapDepartmentService.java new file mode 100644 index 0000000..3b72336 --- /dev/null +++ b/playedu-common/src/main/java/xyz/playedu/common/service/LdapDepartmentService.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 杭州白书科技有限公司 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package xyz.playedu.common.service; + +import com.baomidou.mybatisplus.extension.service.IService; + +import xyz.playedu.common.domain.LdapDepartment; + +import java.util.List; + +public interface LdapDepartmentService extends IService { + + List all(); + + List notChunkByUUIDList(List uuidList); + + void destroy(Integer id); + + void create(Integer depId, String uuid, String dn); +} diff --git a/playedu-common/src/main/java/xyz/playedu/common/service/impl/LdapDepartmentServiceImpl.java b/playedu-common/src/main/java/xyz/playedu/common/service/impl/LdapDepartmentServiceImpl.java new file mode 100644 index 0000000..b177bf7 --- /dev/null +++ b/playedu-common/src/main/java/xyz/playedu/common/service/impl/LdapDepartmentServiceImpl.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 杭州白书科技有限公司 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package xyz.playedu.common.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import org.springframework.stereotype.Service; + +import xyz.playedu.common.domain.LdapDepartment; +import xyz.playedu.common.mapper.LdapDepartmentMapper; +import xyz.playedu.common.service.LdapDepartmentService; + +import java.util.Date; +import java.util.List; + +@Service +public class LdapDepartmentServiceImpl extends ServiceImpl + implements LdapDepartmentService { + + @Override + public List all() { + return list(); + } + + @Override + public List notChunkByUUIDList(List uuidList) { + return list(query().getWrapper().notIn("uuid", uuidList)); + } + + @Override + public void destroy(Integer id) { + remove(query().getWrapper().eq("id", id)); + } + + @Override + public void create(Integer depId, String uuid, String dn) { + LdapDepartment ldapDepartment = new LdapDepartment(); + ldapDepartment.setDepartmentId(depId); + ldapDepartment.setDn(dn); + ldapDepartment.setUuid(uuid); + ldapDepartment.setCreatedAt(new Date()); + ldapDepartment.setUpdatedAt(new Date()); + + save(ldapDepartment); + } +} diff --git a/playedu-common/src/main/java/xyz/playedu/common/util/ldap/LdapTransformDepartment.java b/playedu-common/src/main/java/xyz/playedu/common/util/ldap/LdapTransformDepartment.java new file mode 100644 index 0000000..c4a55ab --- /dev/null +++ b/playedu-common/src/main/java/xyz/playedu/common/util/ldap/LdapTransformDepartment.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2023 杭州白书科技有限公司 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package xyz.playedu.common.util.ldap; + +import lombok.Data; + +@Data +public class LdapTransformDepartment { + private String uuid; + private String dn; +} diff --git a/playedu-common/src/main/java/xyz/playedu/common/util/ldap/LdapUtil.java b/playedu-common/src/main/java/xyz/playedu/common/util/ldap/LdapUtil.java index 34a6d18..f7b9d70 100644 --- a/playedu-common/src/main/java/xyz/playedu/common/util/ldap/LdapUtil.java +++ b/playedu-common/src/main/java/xyz/playedu/common/util/ldap/LdapUtil.java @@ -61,7 +61,7 @@ public class LdapUtil { // 公用属性 "mail", }; - private static final String[] OU_RETURN_ATTRS = new String[] {"ou"}; + private static final String[] OU_RETURN_ATTRS = new String[] {"ou", "usncreated"}; public static LdapContext initContext(String url, String adminUser, String adminPass) throws NamingException { @@ -110,7 +110,7 @@ public class LdapUtil { return users; } - public static List departments( + public static List departments( String url, String adminUser, String adminPass, String baseDN) throws NamingException { LdapContext ldapContext = initContext(url, adminUser, adminPass); @@ -137,12 +137,24 @@ public class LdapUtil { // baseDN中的ou作用域 String ouScopesStr = baseDNOuScope(baseDN); - List units = new ArrayList<>(); + List units = new ArrayList<>(); while (result.hasMoreElements()) { SearchResult item = result.nextElement(); if (item == null) { continue; } + Attributes attributes = item.getAttributes(); + if (attributes == null) { + continue; + } + + // 唯一特征值 + String uSNCreated = (String) attributes.get("uSNCreated").get(); + if (StringUtil.isEmpty(uSNCreated)) { + continue; + } + + // 组织DN String name = item.getName(); if (name.isEmpty()) { name = ouScopesStr; @@ -150,20 +162,19 @@ public class LdapUtil { name = name + (ouScopesStr.isEmpty() ? "" : "," + ouScopesStr); } - units.add(name); + // 将DN反转 + List tmp = new ArrayList<>(List.of(name.split(","))); + Collections.reverse(tmp); + name = String.join(",", tmp); + + LdapTransformDepartment ldapDepartment = new LdapTransformDepartment(); + ldapDepartment.setUuid(uSNCreated); + ldapDepartment.setDn(name.toLowerCase()); + + units.add(ldapDepartment); } - List reverseUnits = new ArrayList<>(); - if (!units.isEmpty()) { - units.forEach( - item -> { - List tmp = new ArrayList<>(List.of(item.split(","))); - Collections.reverse(tmp); - reverseUnits.add(String.join(",", tmp)); - }); - } - - return reverseUnits; + return units; } public static LdapTransformUser loginByMailOrUid( @@ -200,13 +211,13 @@ public class LdapUtil { try { result = ldapContext.search(baseDN, filter, controls); } catch (NamingException e) { - log.error("通过mail或uid登录失败", e); + log.error("LDAP-通过mail或uid登录失败", e); } finally { closeContext(ldapContext); } if (result == null || !result.hasMoreElements()) { - log.info("用户不存在"); + log.info("LDAP-用户不存在"); return null; } @@ -251,23 +262,19 @@ public class LdapUtil { Collections.reverse(ou); ldapUser.setOu(ou); - log.info("ldapUser={}", ldapUser); - // 使用用户dn+提交的密码去登录ldap系统 // 登录成功则意味着密码正确 // 登录失败则意味着密码错误 try { ldapContext = initContext(url, ldapUser.getDn() + "," + baseDN, password); - log.info("LDAP登录成功"); + return ldapUser; } catch (Exception e) { // 无法登录->密码错误 - log.info("LDAP用户提交的密码错误"); + log.error("LDAP-登录失败", e); return null; } finally { ldapContext.close(); } - - return ldapUser; } private static String baseDNOuScope(String baseDN) { @@ -288,7 +295,7 @@ public class LdapUtil { try { ldapCtx.close(); } catch (NamingException e) { - log.error("Failed to close ldap context", e); + log.error("LDAP-资源释放失败", e); } } } diff --git a/playedu-common/src/main/resources/mapper/LdapDepartmentMapper.xml b/playedu-common/src/main/resources/mapper/LdapDepartmentMapper.xml new file mode 100644 index 0000000..120e66a --- /dev/null +++ b/playedu-common/src/main/resources/mapper/LdapDepartmentMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + id,uuid,department_id, + dn,created_at,updated_at + + diff --git a/playedu-system/src/main/java/xyz/playedu/system/checks/MigrationCheck.java b/playedu-system/src/main/java/xyz/playedu/system/checks/MigrationCheck.java index e1b42ae..b1f166a 100644 --- a/playedu-system/src/main/java/xyz/playedu/system/checks/MigrationCheck.java +++ b/playedu-system/src/main/java/xyz/playedu/system/checks/MigrationCheck.java @@ -713,6 +713,27 @@ public class MigrationCheck implements CommandLineRunner { """); } }); + add( + new HashMap<>() { + { + put("table", "ldap_department"); + put("name", "20231113_15_44_17_ldap_department"); + put( + "sql", + """ + CREATE TABLE `ldap_department` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `uuid` varchar(64) NOT NULL DEFAULT '' COMMENT '唯一特征值', + `department_id` int(11) NOT NULL DEFAULT 0 COMMENT '部门ID', + `dn` varchar(120) NOT NULL DEFAULT '' COMMENT 'dn', + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `unique_uuid` (`uuid`) USING BTREE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + """); + } + }); } };