mirror of
https://github.com/PlayEdu/PlayEdu
synced 2025-10-26 22:51:36 +08:00
@@ -35,4 +35,11 @@ public class ConfigConstant {
|
||||
public static final String MINIO_BUCKET = "minio.bucket";
|
||||
public static final String MINIO_ENDPOINT = "minio.endpoint";
|
||||
public static final String MINIO_DOMAIN = "minio.domain";
|
||||
|
||||
public static final String LDAP_ENABLED = "ldap.enabled";
|
||||
public static final String LDAP_URL = "ldap.url";
|
||||
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";
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public class FrontendConstant {
|
||||
add("/api/v1/system/config");
|
||||
add("/api/v1/system/image-captcha");
|
||||
add("/api/v1/auth/login/password");
|
||||
add("/api/v1/auth/login/ldap");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* 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 java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @TableName ldap_user
|
||||
*/
|
||||
@TableName(value = "ldap_user")
|
||||
public class LdapUser implements Serializable {
|
||||
/** */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Integer id;
|
||||
|
||||
/** 唯一特征值 */
|
||||
private String uuid;
|
||||
|
||||
/** 用户ID */
|
||||
private Integer userId;
|
||||
|
||||
/** cn */
|
||||
private String cn;
|
||||
|
||||
/** dn */
|
||||
private String dn;
|
||||
|
||||
/** ou */
|
||||
private String ou;
|
||||
|
||||
/** uid */
|
||||
private String uid;
|
||||
|
||||
/** 邮箱 */
|
||||
private String email;
|
||||
|
||||
/** */
|
||||
private Date createdAt;
|
||||
|
||||
/** */
|
||||
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 getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/** 用户ID */
|
||||
public void setUserId(Integer userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
/** cn */
|
||||
public String getCn() {
|
||||
return cn;
|
||||
}
|
||||
|
||||
/** cn */
|
||||
public void setCn(String cn) {
|
||||
this.cn = cn;
|
||||
}
|
||||
|
||||
/** dn */
|
||||
public String getDn() {
|
||||
return dn;
|
||||
}
|
||||
|
||||
/** dn */
|
||||
public void setDn(String dn) {
|
||||
this.dn = dn;
|
||||
}
|
||||
|
||||
/** ou */
|
||||
public String getOu() {
|
||||
return ou;
|
||||
}
|
||||
|
||||
/** ou */
|
||||
public void setOu(String ou) {
|
||||
this.ou = ou;
|
||||
}
|
||||
|
||||
/** uid */
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
/** uid */
|
||||
public void setUid(String uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
/** 邮箱 */
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
/** 邮箱 */
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
/** */
|
||||
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;
|
||||
}
|
||||
LdapUser other = (LdapUser) 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.getUserId() == null
|
||||
? other.getUserId() == null
|
||||
: this.getUserId().equals(other.getUserId()))
|
||||
&& (this.getCn() == null
|
||||
? other.getCn() == null
|
||||
: this.getCn().equals(other.getCn()))
|
||||
&& (this.getDn() == null
|
||||
? other.getDn() == null
|
||||
: this.getDn().equals(other.getDn()))
|
||||
&& (this.getOu() == null
|
||||
? other.getOu() == null
|
||||
: this.getOu().equals(other.getOu()))
|
||||
&& (this.getUid() == null
|
||||
? other.getUid() == null
|
||||
: this.getUid().equals(other.getUid()))
|
||||
&& (this.getEmail() == null
|
||||
? other.getEmail() == null
|
||||
: this.getEmail().equals(other.getEmail()))
|
||||
&& (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 + ((getUserId() == null) ? 0 : getUserId().hashCode());
|
||||
result = prime * result + ((getCn() == null) ? 0 : getCn().hashCode());
|
||||
result = prime * result + ((getDn() == null) ? 0 : getDn().hashCode());
|
||||
result = prime * result + ((getOu() == null) ? 0 : getOu().hashCode());
|
||||
result = prime * result + ((getUid() == null) ? 0 : getUid().hashCode());
|
||||
result = prime * result + ((getEmail() == null) ? 0 : getEmail().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(", userId=").append(userId);
|
||||
sb.append(", cn=").append(cn);
|
||||
sb.append(", dn=").append(dn);
|
||||
sb.append(", ou=").append(ou);
|
||||
sb.append(", uid=").append(uid);
|
||||
sb.append(", email=").append(email);
|
||||
sb.append(", createdAt=").append(createdAt);
|
||||
sb.append(", updatedAt=").append(updatedAt);
|
||||
sb.append(", serialVersionUID=").append(serialVersionUID);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package xyz.playedu.common.exception;
|
||||
|
||||
public class ServiceException extends Exception {
|
||||
public class ServiceException extends RuntimeException {
|
||||
public ServiceException() {}
|
||||
|
||||
public ServiceException(String message) {
|
||||
|
||||
@@ -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.LdapUser;
|
||||
|
||||
/**
|
||||
* @author tengyongzhi
|
||||
* @description 针对表【ldap_user】的数据库操作Mapper
|
||||
* @createDate 2023-08-31 14:33:19 @Entity xyz.playedu.common.domain.LdapUser
|
||||
*/
|
||||
public interface LdapUserMapper extends BaseMapper<LdapUser> {}
|
||||
@@ -35,4 +35,8 @@ public interface AppConfigService extends IService<AppConfig> {
|
||||
Map<String, String> keyValues();
|
||||
|
||||
MinioConfig getMinioConfig();
|
||||
|
||||
boolean enabledLdapLogin();
|
||||
|
||||
String defaultAvatar();
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public interface DepartmentService extends IService<Department> {
|
||||
|
||||
String childrenParentChain(Department department);
|
||||
|
||||
void create(String name, Integer parentId, Integer sort) throws NotFoundException;
|
||||
Integer create(String name, Integer parentId, Integer sort) throws NotFoundException;
|
||||
|
||||
void remoteRelateUsersByDepId(Integer depId);
|
||||
|
||||
@@ -64,4 +64,6 @@ public interface DepartmentService extends IService<Department> {
|
||||
Map<Integer, Integer> getDepartmentsUserCount();
|
||||
|
||||
List<Department> chunk(List<Integer> ids);
|
||||
|
||||
Integer createWithChainList(List<String> ou);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.LdapUser;
|
||||
import xyz.playedu.common.util.ldap.LdapTransformUser;
|
||||
|
||||
/**
|
||||
* @author tengyongzhi
|
||||
* @description 针对表【ldap_user】的数据库操作Service
|
||||
* @createDate 2023-08-31 11:59:27
|
||||
*/
|
||||
public interface LdapUserService extends IService<LdapUser> {
|
||||
LdapUser findByUUID(String id);
|
||||
|
||||
LdapUser store(LdapTransformUser ldapTransformUser);
|
||||
|
||||
void updateUserId(Integer id, Integer userId);
|
||||
|
||||
void updateCN(Integer id, String cn);
|
||||
|
||||
void updateOU(Integer id, String newOU);
|
||||
|
||||
void updateEmail(Integer id, String email);
|
||||
|
||||
void updateUid(Integer id, String uid);
|
||||
}
|
||||
@@ -80,4 +80,10 @@ public interface UserService extends IService<User> {
|
||||
Map<Integer, List<Integer>> getDepIdsGroup(List<Integer> userIds);
|
||||
|
||||
void changeAvatar(Integer userId, String avatar);
|
||||
|
||||
void updateName(Integer id, String cn);
|
||||
|
||||
void updateDepId(Integer id, Integer[] depIds);
|
||||
|
||||
void updateEmail(Integer id, String email);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public class AppConfigServiceImpl extends ServiceImpl<AppConfigMapper, AppConfig
|
||||
});
|
||||
});
|
||||
|
||||
if (list.size() > 0) {
|
||||
if (!list.isEmpty()) {
|
||||
updateBatchById(list);
|
||||
}
|
||||
}
|
||||
@@ -103,4 +103,18 @@ public class AppConfigServiceImpl extends ServiceImpl<AppConfigMapper, AppConfig
|
||||
minioConfig.setDomain(config.get(ConfigConstant.MINIO_DOMAIN));
|
||||
return minioConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enabledLdapLogin() {
|
||||
AppConfig appConfig =
|
||||
getOne(query().getWrapper().eq("key_name", ConfigConstant.LDAP_ENABLED));
|
||||
return "1".equals(appConfig.getKeyValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String defaultAvatar() {
|
||||
AppConfig appConfig =
|
||||
getOne(query().getWrapper().eq("key_name", ConfigConstant.MEMBER_DEFAULT_AVATAR));
|
||||
return appConfig.getKeyValue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package xyz.playedu.common.service.impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -108,7 +109,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
|
||||
private void updateParentChain(String newChildrenPC, String oldChildrenPC) {
|
||||
List<Department> children =
|
||||
list(query().getWrapper().like("parent_chain", oldChildrenPC + "%"));
|
||||
if (children.size() == 0) {
|
||||
if (children.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,7 +126,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
|
||||
.getParentChain()
|
||||
.replaceFirst(
|
||||
oldChildrenPC + ",",
|
||||
newChildrenPC.length() == 0
|
||||
newChildrenPC.isEmpty()
|
||||
? newChildrenPC
|
||||
: newChildrenPC + ',');
|
||||
}
|
||||
@@ -133,7 +134,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
|
||||
|
||||
// parentId计算
|
||||
int parentId = 0;
|
||||
if (pc != null && pc.length() > 0) {
|
||||
if (pc != null && !pc.isEmpty()) {
|
||||
String[] parentIds = pc.split(",");
|
||||
parentId = Integer.parseInt(parentIds[parentIds.length - 1]);
|
||||
}
|
||||
@@ -153,7 +154,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
|
||||
throw new NotFoundException("父级部门不存在");
|
||||
}
|
||||
String pc = parentDepartment.getParentChain();
|
||||
parentChain = pc == null || pc.length() == 0 ? parentId + "" : pc + "," + parentId;
|
||||
parentChain = pc == null || pc.isEmpty() ? parentId + "" : pc + "," + parentId;
|
||||
}
|
||||
return parentChain;
|
||||
}
|
||||
@@ -161,14 +162,14 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
|
||||
@Override
|
||||
public String childrenParentChain(Department department) {
|
||||
String prefix = department.getId() + "";
|
||||
if (department.getParentChain() != null && department.getParentChain().length() > 0) {
|
||||
if (department.getParentChain() != null && !department.getParentChain().isEmpty()) {
|
||||
prefix = department.getParentChain() + "," + prefix;
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create(String name, Integer parentId, Integer sort) throws NotFoundException {
|
||||
public Integer create(String name, Integer parentId, Integer sort) throws NotFoundException {
|
||||
String parentChain = "";
|
||||
if (parentId != 0) {
|
||||
parentChain = compParentChain(parentId);
|
||||
@@ -183,6 +184,8 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
|
||||
department.setUpdatedAt(new Date());
|
||||
|
||||
save(department);
|
||||
|
||||
return department.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -258,9 +261,31 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
|
||||
|
||||
@Override
|
||||
public List<Department> chunk(List<Integer> ids) {
|
||||
if (ids == null || ids.size() == 0) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return list(query().getWrapper().in("id", ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public Integer createWithChainList(List<String> ou) {
|
||||
if (ou == null || ou.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Department department = null;
|
||||
for (int i = 0; i < ou.size(); i++) {
|
||||
String name = ou.get(i);
|
||||
Integer parentId = department == null ? 0 : department.getId();
|
||||
department = getOne(query().getWrapper().eq("name", name).eq("parent_id", parentId));
|
||||
if (department == null) {
|
||||
Integer depId = create(name, parentId, i);
|
||||
// refresh
|
||||
department = new Department();
|
||||
department.setId(depId);
|
||||
}
|
||||
}
|
||||
return department.getId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.LdapUser;
|
||||
import xyz.playedu.common.mapper.LdapUserMapper;
|
||||
import xyz.playedu.common.service.LdapUserService;
|
||||
import xyz.playedu.common.util.StringUtil;
|
||||
import xyz.playedu.common.util.ldap.LdapTransformUser;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author tengyongzhi
|
||||
* @description 针对表【ldap_user】的数据库操作Service实现
|
||||
* @createDate 2023-08-31 11:59:27
|
||||
*/
|
||||
@Service
|
||||
public class LdapUserServiceImpl extends ServiceImpl<LdapUserMapper, LdapUser>
|
||||
implements LdapUserService {
|
||||
|
||||
@Override
|
||||
public LdapUser findByUUID(String id) {
|
||||
return getOne(query().getWrapper().eq("uuid", id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public LdapUser store(LdapTransformUser ldapTransformUser) {
|
||||
LdapUser user = new LdapUser();
|
||||
user.setUuid(ldapTransformUser.getId());
|
||||
user.setCn(ldapTransformUser.getCn());
|
||||
user.setDn(ldapTransformUser.getDn());
|
||||
user.setUid(ldapTransformUser.getUid());
|
||||
// ou
|
||||
user.setOu(String.join(",", ldapTransformUser.getOu()));
|
||||
// 邮箱可能不存在
|
||||
if (StringUtil.isNotEmpty(ldapTransformUser.getEmail())) {
|
||||
user.setEmail(ldapTransformUser.getEmail());
|
||||
}
|
||||
user.setCreatedAt(new Date());
|
||||
user.setUpdatedAt(new Date());
|
||||
|
||||
save(user);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserId(Integer id, Integer userId) {
|
||||
LdapUser user = new LdapUser();
|
||||
user.setId(id);
|
||||
user.setUserId(userId);
|
||||
updateById(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCN(Integer id, String cn) {
|
||||
LdapUser user = new LdapUser();
|
||||
user.setId(id);
|
||||
user.setCn(cn == null ? "" : cn);
|
||||
updateById(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOU(Integer id, String newOU) {
|
||||
LdapUser user = new LdapUser();
|
||||
user.setId(id);
|
||||
user.setOu(newOU == null ? "" : newOU);
|
||||
updateById(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEmail(Integer id, String email) {
|
||||
LdapUser user = new LdapUser();
|
||||
user.setId(id);
|
||||
user.setEmail(email == null ? "" : email);
|
||||
updateById(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUid(Integer id, String uid) {
|
||||
LdapUser user = new LdapUser();
|
||||
user.setId(id);
|
||||
user.setUid(uid);
|
||||
updateById(user);
|
||||
}
|
||||
}
|
||||
@@ -117,7 +117,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
user.setCreatedAt(new Date());
|
||||
user.setUpdatedAt(new Date());
|
||||
|
||||
if (idCard != null && idCard.length() > 0) {
|
||||
if (idCard != null && !idCard.isEmpty()) {
|
||||
user.setVerifyAt(new Date());
|
||||
user.setIsVerify(1);
|
||||
}
|
||||
@@ -144,14 +144,14 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
newUser.setAvatar(avatar);
|
||||
newUser.setIdCard(idCard);
|
||||
|
||||
if (password != null && password.length() > 0) {
|
||||
if (password != null && !password.isEmpty()) {
|
||||
newUser.setPassword(HelperUtil.MD5(password + user.getSalt()));
|
||||
}
|
||||
|
||||
if (newUser.getName() != null
|
||||
&& newUser.getName().length() > 0
|
||||
&& !newUser.getName().isEmpty()
|
||||
&& newUser.getIdCard() != null
|
||||
&& newUser.getIdCard().length() > 0) {
|
||||
&& !newUser.getIdCard().isEmpty()) {
|
||||
if (user.getVerifyAt() == null) {
|
||||
newUser.setIsVerify(1);
|
||||
newUser.setVerifyAt(new Date());
|
||||
@@ -204,7 +204,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
|
||||
@Override
|
||||
public List<User> chunks(List<Integer> ids, List<String> fields) {
|
||||
if (ids == null || ids.size() == 0) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return list(query().getWrapper().in("id", ids).select(fields));
|
||||
@@ -212,7 +212,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
|
||||
@Override
|
||||
public List<User> chunks(List<Integer> ids) {
|
||||
if (ids == null || ids.size() == 0) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return list(query().getWrapper().in("id", ids));
|
||||
@@ -250,7 +250,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
|
||||
@Override
|
||||
public Map<Integer, List<Integer>> getDepIdsGroup(List<Integer> userIds) {
|
||||
if (userIds == null || userIds.size() == 0) {
|
||||
if (userIds == null || userIds.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Map<Integer, List<UserDepartment>> data =
|
||||
@@ -273,4 +273,25 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
user.setAvatar(avatar);
|
||||
updateById(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateName(Integer id, String cn) {
|
||||
User user = new User();
|
||||
user.setId(id);
|
||||
user.setName(cn);
|
||||
updateById(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDepId(Integer id, Integer[] depIds) {
|
||||
userDepartmentService.resetStoreDepIds(id, depIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEmail(Integer id, String email) {
|
||||
User user = new User();
|
||||
user.setId(id);
|
||||
user.setEmail(email);
|
||||
updateById(user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class LdapTransformUser {
|
||||
private String id;
|
||||
|
||||
private String dn;
|
||||
|
||||
private String cn;
|
||||
|
||||
private List<String> ou;
|
||||
|
||||
private String email;
|
||||
|
||||
private String uid;
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* 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.extern.slf4j.Slf4j;
|
||||
|
||||
import xyz.playedu.common.exception.ServiceException;
|
||||
import xyz.playedu.common.util.StringUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.ldap.InitialLdapContext;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
|
||||
@Slf4j
|
||||
public class LdapUtil {
|
||||
|
||||
private static final String USER_OBJECT_CLASS =
|
||||
"(|(objectClass=person)(objectClass=posixAccount)(objectClass=inetOrgPerson)(objectClass=organizationalPerson))";
|
||||
|
||||
private static final String[] USER_RETURN_ATTRS =
|
||||
new String[] {
|
||||
"uid", // 用户的唯一识别符号,全局唯一,可以看做用户表的手机号,此字段可用于配合密码直接登录
|
||||
"cn", // CommonName -> 可以认作为人的名字,比如:张三。在LDAP中此字段是可以重复的,但是同一ou下不可重复
|
||||
"mail", // 邮箱,此值不一定存在,全局唯一,可配合密码直接登录
|
||||
"email", // 邮箱,同上
|
||||
"entryUUID",
|
||||
};
|
||||
private static final String[] OU_RETURN_ATTRS = new String[] {"ou"};
|
||||
|
||||
public static LdapContext initContext(String url, String adminUser, String adminPass)
|
||||
throws NamingException {
|
||||
Hashtable<String, String> context = new Hashtable<>();
|
||||
context.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
context.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
// 服务地址
|
||||
context.put(Context.PROVIDER_URL, url);
|
||||
// 管理员账户和密码
|
||||
context.put(Context.SECURITY_PRINCIPAL, adminUser);
|
||||
context.put(Context.SECURITY_CREDENTIALS, adminPass);
|
||||
return new InitialLdapContext(context, null);
|
||||
}
|
||||
|
||||
public static List<HashMap<String, String>> users(LdapContext ldapContext, String baseDN)
|
||||
throws NamingException {
|
||||
SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
controls.setReturningAttributes(USER_RETURN_ATTRS);
|
||||
controls.setReturningObjFlag(true);
|
||||
|
||||
NamingEnumeration<SearchResult> result = null;
|
||||
try {
|
||||
result = ldapContext.search(baseDN, USER_OBJECT_CLASS, controls);
|
||||
} catch (NamingException e) {
|
||||
log.error("LDAP用户查询失败", e);
|
||||
} finally {
|
||||
closeContext(ldapContext);
|
||||
}
|
||||
|
||||
if (result == null || !result.hasMoreElements()) {
|
||||
log.info("LDAP服务中没有用户");
|
||||
return null;
|
||||
}
|
||||
|
||||
List<HashMap<String, String>> users = new ArrayList<>();
|
||||
while (result.hasMoreElements()) {
|
||||
SearchResult item = result.nextElement();
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
Attributes attributes = item.getAttributes();
|
||||
log.info("name={},attributes={}", item.getName(), attributes);
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
public static List<String> departments(LdapContext ldapContext, String baseDN)
|
||||
throws NamingException {
|
||||
SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
controls.setReturningAttributes(OU_RETURN_ATTRS);
|
||||
controls.setReturningObjFlag(true);
|
||||
|
||||
String filter = "(objectClass=organizationalUnit)";
|
||||
NamingEnumeration<SearchResult> result = null;
|
||||
try {
|
||||
result = ldapContext.search(baseDN, filter, controls);
|
||||
} catch (NamingException e) {
|
||||
log.error("LDAP部门查询失败", e);
|
||||
} finally {
|
||||
closeContext(ldapContext);
|
||||
}
|
||||
|
||||
if (result == null || !result.hasMoreElements()) {
|
||||
log.info("LDAP部门为空");
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> units = new ArrayList<>();
|
||||
while (result.hasMoreElements()) {
|
||||
SearchResult item = result.nextElement();
|
||||
if (item == null) {
|
||||
continue;
|
||||
}
|
||||
units.add(item.getName());
|
||||
}
|
||||
|
||||
return units;
|
||||
}
|
||||
|
||||
public static LdapTransformUser loginByMailOrUid(
|
||||
String url,
|
||||
String adminUser,
|
||||
String adminPass,
|
||||
String baseDN,
|
||||
String mail,
|
||||
String uid,
|
||||
String password)
|
||||
throws ServiceException, NamingException {
|
||||
if (StringUtil.isEmpty(mail) && StringUtil.isEmpty(uid)) {
|
||||
throw new ServiceException("mail和Uid不能同时为空");
|
||||
}
|
||||
|
||||
SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
controls.setReturningAttributes(USER_RETURN_ATTRS);
|
||||
controls.setReturningObjFlag(true);
|
||||
controls.setCountLimit(1);
|
||||
|
||||
String userFilter = "";
|
||||
if (StringUtil.isNotEmpty(mail)) {
|
||||
userFilter = String.format("(|(mail=%s)(email=%s))", mail, mail);
|
||||
} else if (StringUtil.isNotEmpty(uid)) {
|
||||
userFilter = String.format("(uid=%s)", uid);
|
||||
}
|
||||
|
||||
String filter = String.format("(&%s%s)", userFilter, USER_OBJECT_CLASS);
|
||||
|
||||
LdapContext ldapContext = initContext(url, adminUser, adminPass);
|
||||
NamingEnumeration<SearchResult> result = null;
|
||||
try {
|
||||
result = ldapContext.search(baseDN, filter, controls);
|
||||
} catch (NamingException e) {
|
||||
log.error("通过mail或uid登录失败", e);
|
||||
} finally {
|
||||
closeContext(ldapContext);
|
||||
}
|
||||
|
||||
if (result == null || !result.hasMoreElements()) {
|
||||
log.info("用户不存在");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 根据mail或uid查询出来的用户
|
||||
SearchResult item = result.nextElement();
|
||||
Attributes attributes = item.getAttributes();
|
||||
|
||||
String email =
|
||||
attributes.get("mail") == null ? null : (String) attributes.get("mail").get();
|
||||
if (email == null) {
|
||||
email = attributes.get("email") == null ? null : (String) attributes.get("email").get();
|
||||
}
|
||||
|
||||
LdapTransformUser ldapUser = new LdapTransformUser();
|
||||
ldapUser.setDn(item.getName());
|
||||
ldapUser.setId((String) attributes.get("entryUUID").get());
|
||||
ldapUser.setCn((String) attributes.get("cn").get());
|
||||
ldapUser.setUid((String) attributes.get("uid").get());
|
||||
ldapUser.setEmail(email);
|
||||
|
||||
// 使用用户dn+提交的密码去登录ldap系统
|
||||
// 登录成功则意味着密码正确
|
||||
// 登录失败则意味着密码错误
|
||||
try {
|
||||
ldapContext = initContext(url, ldapUser.getDn() + "," + baseDN, password);
|
||||
log.info("LDAP登录成功");
|
||||
} catch (Exception e) {
|
||||
// 无法登录->密码错误
|
||||
log.info("LDAP用户提交的密码错误");
|
||||
return null;
|
||||
} finally {
|
||||
ldapContext.close();
|
||||
}
|
||||
|
||||
// ou计算
|
||||
String[] rdnList = ldapUser.getDn().split(",");
|
||||
List<String> ou = new ArrayList<>();
|
||||
for (String s : rdnList) {
|
||||
if (StringUtil.startsWith(s, "ou=")) {
|
||||
ou.add(s.replace("ou=", ""));
|
||||
}
|
||||
}
|
||||
Collections.reverse(ou);
|
||||
ldapUser.setOu(ou);
|
||||
|
||||
return ldapUser;
|
||||
}
|
||||
|
||||
public static void closeContext(LdapContext ldapCtx) {
|
||||
if (ldapCtx == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ldapCtx.close();
|
||||
} catch (NamingException e) {
|
||||
log.error("Failed to close ldap context", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
playedu-common/src/main/resources/mapper/LdapUserMapper.xml
Normal file
26
playedu-common/src/main/resources/mapper/LdapUserMapper.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="xyz.playedu.common.mapper.LdapUserMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="xyz.playedu.common.domain.LdapUser">
|
||||
<id property="id" column="id" jdbcType="INTEGER"/>
|
||||
<result property="uuid" column="uuid" jdbcType="VARCHAR"/>
|
||||
<result property="userId" column="user_id" jdbcType="INTEGER"/>
|
||||
<result property="cn" column="cn" jdbcType="VARCHAR"/>
|
||||
<result property="dn" column="dn" jdbcType="VARCHAR"/>
|
||||
<result property="ou" column="ou" jdbcType="VARCHAR"/>
|
||||
<result property="uid" column="uid" jdbcType="VARCHAR"/>
|
||||
<result property="email" column="email" jdbcType="VARCHAR"/>
|
||||
<result property="createdAt" column="created_at" jdbcType="TIMESTAMP"/>
|
||||
<result property="updatedAt" column="updated_at" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,uuid,user_id,
|
||||
cn,dn,ou,
|
||||
uid,email,created_at,
|
||||
updated_at
|
||||
</sql>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user