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 8933be7..b270aab 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 @@ -15,6 +15,7 @@ */ package xyz.playedu.api.controller.backend; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.MapUtils; @@ -39,8 +40,10 @@ 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; @@ -144,7 +147,7 @@ public class DepartmentController { data.put("users", new ArrayList<>()); data.put("children", departmentService.listByParentId(id)); - if (courseIds != null && courseIds.size() > 0) { + if (courseIds != null && !courseIds.isEmpty()) { data.put( "courses", courseService.chunks( @@ -156,7 +159,7 @@ public class DepartmentController { } })); } - if (userIds != null && userIds.size() > 0) { + if (userIds != null && !userIds.isEmpty()) { data.put( "users", userService.chunks( @@ -244,7 +247,7 @@ public class DepartmentController { PaginationResult users = userService.paginate(page, size, filter); List courses; - if (courseIdsStr != null && courseIdsStr.trim().length() > 0) { + if (courseIdsStr != null && !courseIdsStr.trim().isEmpty()) { // 指定了需要显示的线上课 courses = courseService.chunks( @@ -306,4 +309,63 @@ public class DepartmentController { return JsonResponse.data(data); } + + @BackendPermission(slug = BPermissionConstant.DEPARTMENT_CUD) + @PostMapping("/ldap-sync") + @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; + } + } + + return JsonResponse.success(); + } } diff --git a/playedu-common/src/main/java/xyz/playedu/common/constant/ConfigConstant.java b/playedu-common/src/main/java/xyz/playedu/common/constant/ConfigConstant.java index c903468..beaaef9 100644 --- a/playedu-common/src/main/java/xyz/playedu/common/constant/ConfigConstant.java +++ b/playedu-common/src/main/java/xyz/playedu/common/constant/ConfigConstant.java @@ -41,5 +41,4 @@ public class ConfigConstant { public static final String LDAP_ADMIN_USER = "ldap.admin_user"; public static final String LDAP_ADMIN_PASS = "ldap.admin_pass"; public static final String LDAP_BASE_DN = "ldap.base_dn"; - public static final String LDAP_USER_DN_PREFIX = "ldap.user_dn_prefix"; } diff --git a/playedu-common/src/main/java/xyz/playedu/common/service/AppConfigService.java b/playedu-common/src/main/java/xyz/playedu/common/service/AppConfigService.java index 39bbcc0..f36625d 100644 --- a/playedu-common/src/main/java/xyz/playedu/common/service/AppConfigService.java +++ b/playedu-common/src/main/java/xyz/playedu/common/service/AppConfigService.java @@ -18,6 +18,7 @@ package xyz.playedu.common.service; import com.baomidou.mybatisplus.extension.service.IService; import xyz.playedu.common.domain.AppConfig; +import xyz.playedu.common.types.LdapConfig; import xyz.playedu.common.types.config.MinioConfig; import java.util.HashMap; @@ -39,4 +40,6 @@ public interface AppConfigService extends IService { boolean enabledLdapLogin(); String defaultAvatar(); + + LdapConfig ldapConfig(); } diff --git a/playedu-common/src/main/java/xyz/playedu/common/service/DepartmentService.java b/playedu-common/src/main/java/xyz/playedu/common/service/DepartmentService.java index dcf10c6..252adb5 100644 --- a/playedu-common/src/main/java/xyz/playedu/common/service/DepartmentService.java +++ b/playedu-common/src/main/java/xyz/playedu/common/service/DepartmentService.java @@ -66,4 +66,6 @@ public interface DepartmentService extends IService { List chunk(List ids); Integer createWithChainList(List ou); + + Department findByName(String name, Integer parentId); } diff --git a/playedu-common/src/main/java/xyz/playedu/common/service/impl/AppConfigServiceImpl.java b/playedu-common/src/main/java/xyz/playedu/common/service/impl/AppConfigServiceImpl.java index 74157c6..970feab 100644 --- a/playedu-common/src/main/java/xyz/playedu/common/service/impl/AppConfigServiceImpl.java +++ b/playedu-common/src/main/java/xyz/playedu/common/service/impl/AppConfigServiceImpl.java @@ -21,8 +21,10 @@ import org.springframework.stereotype.Service; import xyz.playedu.common.constant.ConfigConstant; import xyz.playedu.common.domain.AppConfig; +import xyz.playedu.common.exception.ServiceException; import xyz.playedu.common.mapper.AppConfigMapper; import xyz.playedu.common.service.AppConfigService; +import xyz.playedu.common.types.LdapConfig; import xyz.playedu.common.types.config.MinioConfig; import java.util.ArrayList; @@ -117,4 +119,29 @@ public class AppConfigServiceImpl extends ServiceImpl config = keyValues(); + + LdapConfig ldapConfig = new LdapConfig(); + ldapConfig.setEnabled(config.get(ConfigConstant.LDAP_ENABLED).equals("1")); + ldapConfig.setUrl(config.get(ConfigConstant.LDAP_URL)); + ldapConfig.setAdminUser(config.get(ConfigConstant.LDAP_ADMIN_USER)); + ldapConfig.setAdminPass(config.get(ConfigConstant.LDAP_ADMIN_PASS)); + ldapConfig.setBaseDN(config.get(ConfigConstant.LDAP_BASE_DN)); + + if (!ldapConfig.getEnabled()) { + throw new ServiceException("LDAP服务未启用"); + } + + if (ldapConfig.getUrl().isEmpty() + || ldapConfig.getAdminUser().isEmpty() + || ldapConfig.getAdminPass().isEmpty() + || ldapConfig.getBaseDN().isEmpty()) { + throw new ServiceException("LDAP服务未配置"); + } + + return ldapConfig; + } } diff --git a/playedu-common/src/main/java/xyz/playedu/common/service/impl/DepartmentServiceImpl.java b/playedu-common/src/main/java/xyz/playedu/common/service/impl/DepartmentServiceImpl.java index 7efa721..d20a6bc 100644 --- a/playedu-common/src/main/java/xyz/playedu/common/service/impl/DepartmentServiceImpl.java +++ b/playedu-common/src/main/java/xyz/playedu/common/service/impl/DepartmentServiceImpl.java @@ -288,4 +288,9 @@ public class DepartmentServiceImpl extends ServiceImpl departments(LdapContext ldapContext, String baseDN) - throws NamingException { + public static List departments( + String url, String adminUser, String adminPass, String baseDN) throws NamingException { + LdapContext ldapContext = initContext(url, adminUser, adminPass); + SearchControls controls = new SearchControls(); controls.setSearchScope(SearchControls.SUBTREE_SCOPE); controls.setReturningAttributes(OU_RETURN_ATTRS); @@ -132,16 +134,42 @@ public class LdapUtil { return null; } + List ouScopes = new ArrayList<>(); + String[] rdnList = baseDN.toLowerCase().split(","); + for (int i = 0; i < rdnList.length; i++) { + if (rdnList[i].startsWith("ou=")) { + ouScopes.add(rdnList[i]); + } + } + String ouScopesStr = String.join(",", ouScopes); + List units = new ArrayList<>(); while (result.hasMoreElements()) { SearchResult item = result.nextElement(); if (item == null) { continue; } - units.add(item.getName()); + String name = item.getName(); + if (name.isEmpty()) { + name = ouScopesStr; + } else { + name = name + (ouScopesStr.isEmpty() ? "" : "," + ouScopesStr); + } + + units.add(name); } - return units; + 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; } public static LdapTransformUser loginByMailOrUid( diff --git a/playedu-system/src/main/java/xyz/playedu/system/checks/AppConfigCheck.java b/playedu-system/src/main/java/xyz/playedu/system/checks/AppConfigCheck.java index 58a7a22..82027a0 100644 --- a/playedu-system/src/main/java/xyz/playedu/system/checks/AppConfigCheck.java +++ b/playedu-system/src/main/java/xyz/playedu/system/checks/AppConfigCheck.java @@ -276,16 +276,6 @@ public class AppConfigCheck implements CommandLineRunner { setHelp("从LDAP根节点搜索用户"); } }, - new AppConfig() { - { - setName("附件用户DN"); - setSort(70); - setFieldType(BackendConstant.APP_CONFIG_FIELD_TYPE_TEXT); - setKeyName(ConfigConstant.LDAP_USER_DN_PREFIX); - setKeyValue(""); - setHelp("搜索用户时,基于基础DN的搜索范围限制"); - } - }, }); } }; diff --git a/playedu-system/src/main/java/xyz/playedu/system/checks/UpgradeCheck.java b/playedu-system/src/main/java/xyz/playedu/system/checks/UpgradeCheck.java index 678b334..c4081fb 100644 --- a/playedu-system/src/main/java/xyz/playedu/system/checks/UpgradeCheck.java +++ b/playedu-system/src/main/java/xyz/playedu/system/checks/UpgradeCheck.java @@ -37,6 +37,21 @@ public class UpgradeCheck implements CommandLineRunner { @Override public void run(String... args) throws Exception { upgrade_v1_beta7(); + upgrade_v1_4(); + } + + private void upgrade_v1_4() { + appConfigService.remove( + appConfigService + .query() + .getWrapper() + .in( + "key_name", + new ArrayList<>() { + { + add("ldap.user_dn_prefix"); + } + })); } private void upgrade_v1_beta7() {