feat(系统设置): ldap测试连接,测试登录接口
This commit is contained in:
parent
c4b5d2dd55
commit
7e2015a13e
|
@ -0,0 +1,84 @@
|
||||||
|
package io.metersphere.sdk.ldap;
|
||||||
|
|
||||||
|
import javax.net.SocketFactory;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
public class CustomSSLSocketFactory extends SSLSocketFactory {
|
||||||
|
private SSLSocketFactory socketFactory;
|
||||||
|
|
||||||
|
public CustomSSLSocketFactory() {
|
||||||
|
try {
|
||||||
|
SSLContext ctx = SSLContext.getInstance("TLS");
|
||||||
|
ctx.init(null, new TrustManager[]{new DummyTrustmanager()}, new SecureRandom());
|
||||||
|
socketFactory = ctx.getSocketFactory();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SocketFactory getDefault() {
|
||||||
|
return new CustomSSLSocketFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getDefaultCipherSuites() {
|
||||||
|
return socketFactory.getDefaultCipherSuites();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getSupportedCipherSuites() {
|
||||||
|
return socketFactory.getSupportedCipherSuites();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(Socket socket, String string, int num, boolean bool) throws IOException {
|
||||||
|
return socketFactory.createSocket(socket, string, num, bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(String string, int num) throws IOException, UnknownHostException {
|
||||||
|
return socketFactory.createSocket(string, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(String string, int num, InetAddress netAdd, int i) throws IOException, UnknownHostException {
|
||||||
|
return socketFactory.createSocket(string, num, netAdd, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(InetAddress netAdd, int num) throws IOException {
|
||||||
|
return socketFactory.createSocket(netAdd, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(InetAddress netAdd1, int num, InetAddress netAdd2, int i) throws IOException {
|
||||||
|
return socketFactory.createSocket(netAdd1, num, netAdd2, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 证书
|
||||||
|
*/
|
||||||
|
public static class DummyTrustmanager implements X509TrustManager {
|
||||||
|
public void checkClientTrusted(X509Certificate[] cert, String string) throws CertificateException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkServerTrusted(X509Certificate[] cert, String string) throws CertificateException {
|
||||||
|
}
|
||||||
|
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return new X509Certificate[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package io.metersphere.sdk.ldap;
|
||||||
|
|
||||||
|
import org.springframework.ldap.core.support.LdapContextSource;
|
||||||
|
|
||||||
|
import javax.naming.Context;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
public class SSLLdapContextSource extends LdapContextSource {
|
||||||
|
public Hashtable<String, Object> getAnonymousEnv() {
|
||||||
|
Hashtable<String, Object> anonymousEnv = super.getAnonymousEnv();
|
||||||
|
anonymousEnv.put("java.naming.security.protocol", "ssl");
|
||||||
|
anonymousEnv.put("java.naming.ldap.factory.socket", CustomSSLSocketFactory.class.getName());
|
||||||
|
anonymousEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||||
|
return anonymousEnv;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
package io.metersphere.sdk.ldap.service;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.exception.MSException;
|
||||||
|
import io.metersphere.sdk.ldap.SSLLdapContextSource;
|
||||||
|
import io.metersphere.sdk.ldap.vo.LdapLoginRequest;
|
||||||
|
import io.metersphere.sdk.ldap.vo.LdapRequest;
|
||||||
|
import io.metersphere.sdk.util.*;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.shiro.realm.ldap.LdapUtils;
|
||||||
|
import org.springframework.ldap.AuthenticationException;
|
||||||
|
import org.springframework.ldap.InvalidNameException;
|
||||||
|
import org.springframework.ldap.InvalidSearchFilterException;
|
||||||
|
import org.springframework.ldap.NameNotFoundException;
|
||||||
|
import org.springframework.ldap.core.DirContextOperations;
|
||||||
|
import org.springframework.ldap.core.LdapTemplate;
|
||||||
|
import org.springframework.ldap.core.support.AbstractContextMapper;
|
||||||
|
import org.springframework.ldap.core.support.DefaultDirObjectFactory;
|
||||||
|
import org.springframework.ldap.core.support.LdapContextSource;
|
||||||
|
import org.springframework.ldap.query.SearchScope;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.naming.directory.DirContext;
|
||||||
|
import javax.naming.ldap.LdapContext;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.springframework.ldap.query.LdapQueryBuilder.query;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public class LdapService {
|
||||||
|
|
||||||
|
|
||||||
|
public void testConnect(LdapRequest request) {
|
||||||
|
getConnect(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LdapTemplate getConnect(LdapRequest request) {
|
||||||
|
String credentials = EncryptUtils.aesDecrypt(request.getLadpPassword()).toString();
|
||||||
|
LdapContextSource sourceLdapCtx;
|
||||||
|
if (StringUtils.startsWithIgnoreCase(request.getLdapUrl(), "ldaps://")) {
|
||||||
|
sourceLdapCtx = new SSLLdapContextSource();
|
||||||
|
// todo 这里加上strategy 会报错
|
||||||
|
} else {
|
||||||
|
sourceLdapCtx = new LdapContextSource();
|
||||||
|
}
|
||||||
|
sourceLdapCtx.setUrl(request.getLdapUrl());
|
||||||
|
sourceLdapCtx.setUserDn(request.getLadpDn());
|
||||||
|
sourceLdapCtx.setPassword(credentials);
|
||||||
|
sourceLdapCtx.setDirObjectFactory(DefaultDirObjectFactory.class);
|
||||||
|
sourceLdapCtx.afterPropertiesSet();
|
||||||
|
LdapTemplate ldapTemplate = new LdapTemplate(sourceLdapCtx);
|
||||||
|
ldapTemplate.setIgnorePartialResultException(true);
|
||||||
|
Map<String, Object> baseEnv = new Hashtable<>();
|
||||||
|
baseEnv.put("com.sun.jndi.ldap.connect.timeout", "3000");
|
||||||
|
baseEnv.put("com.sun.jndi.ldap.read.timeout", "3000");
|
||||||
|
sourceLdapCtx.setBaseEnvironmentProperties(baseEnv);
|
||||||
|
ldapTemplate.setDefaultSearchScope(SearchScope.SUBTREE.getId());
|
||||||
|
try {
|
||||||
|
authenticate(request.getLadpDn(), credentials, ldapTemplate);
|
||||||
|
} catch (AuthenticationException e) {
|
||||||
|
LogUtils.error(e.getMessage(), e);
|
||||||
|
throw new MSException(Translator.get("ldap_connect_fail_user"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error(e.getMessage(), e);
|
||||||
|
throw new MSException(Translator.get("ldap_connect_fail"));
|
||||||
|
}
|
||||||
|
return ldapTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean authenticate(String dn, String credentials, LdapTemplate ldapTemplate) throws AuthenticationException {
|
||||||
|
DirContext ctx = null;
|
||||||
|
try {
|
||||||
|
ctx = ldapTemplate.getContextSource().getContext(dn, credentials);
|
||||||
|
return true;
|
||||||
|
} finally {
|
||||||
|
// It is imperative that the created DirContext instance is always closed
|
||||||
|
LdapUtils.closeContext((LdapContext) ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试登录
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public DirContextOperations testLogin(LdapLoginRequest request) {
|
||||||
|
String credentials = request.getPassword();
|
||||||
|
DirContextOperations dirContextOperations = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
LdapTemplate ldapTemplate = getLdapTemplate(request);
|
||||||
|
// 获取LDAP用户相关信息
|
||||||
|
dirContextOperations = getContextMapper(request, ldapTemplate);
|
||||||
|
// 执行登录认证
|
||||||
|
authenticate(String.valueOf(dirContextOperations.getDn()), credentials, ldapTemplate);
|
||||||
|
} catch (AuthenticationException e) {
|
||||||
|
LogUtils.error(e.getMessage(), e);
|
||||||
|
throw new MSException(Translator.get("authentication_failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查属性是否存在
|
||||||
|
getMappingAttr("name", dirContextOperations, request);
|
||||||
|
return dirContextOperations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LdapTemplate getLdapTemplate(LdapLoginRequest request) {
|
||||||
|
LdapRequest ldapRequest = new LdapRequest();
|
||||||
|
BeanUtils.copyBean(ldapRequest, request);
|
||||||
|
LdapTemplate ldapTemplate = getConnect(ldapRequest);
|
||||||
|
return ldapTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getMappingAttr(String attr, DirContextOperations dirContext, LdapLoginRequest request) {
|
||||||
|
// 检查LDAP映射属性
|
||||||
|
String mapping = request.getLdapUserMapping();
|
||||||
|
Map jsonObject = JSON.parseObject(mapping, Map.class);
|
||||||
|
String mapAttr = (String) jsonObject.get(attr);
|
||||||
|
String result = dirContext.getStringAttribute(mapAttr);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirContextOperations getContextMapper(LdapLoginRequest request, LdapTemplate ldapTemplate) {
|
||||||
|
String filter = request.getLdapUserFilter();
|
||||||
|
String[] arr = request.getLdapUserOu().split("|");
|
||||||
|
|
||||||
|
List<DirContextOperations> result = null;
|
||||||
|
// 多OU
|
||||||
|
for (String ou : arr) {
|
||||||
|
try {
|
||||||
|
result = ldapTemplate.search(query().base(ou.trim()).filter(filter, request.getUsername()), new MsContextMapper());
|
||||||
|
if (result.size() == 1) {
|
||||||
|
return result.get(0);
|
||||||
|
}
|
||||||
|
} catch (NameNotFoundException | InvalidNameException e) {
|
||||||
|
LogUtils.error(e.getMessage(), e);
|
||||||
|
throw new MSException(Translator.get("login_fail_ou_error"));
|
||||||
|
} catch (InvalidSearchFilterException e) {
|
||||||
|
LogUtils.error(e.getMessage(), e);
|
||||||
|
throw new MSException(Translator.get("login_fail_filter_error"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.size() != 1) {
|
||||||
|
throw new MSException(Translator.get("user_not_found_or_not_unique"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MsContextMapper extends AbstractContextMapper<DirContextOperations> {
|
||||||
|
@Override
|
||||||
|
public DirContextOperations doMapFromContext(DirContextOperations context) {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package io.metersphere.sdk.ldap.vo;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.dto.LoginRequest;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class LdapLoginRequest extends LoginRequest implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "LDAP地址", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{ldap_url_is_null}")
|
||||||
|
private String ldapUrl;
|
||||||
|
|
||||||
|
@Schema(description = "LDAP绑定DN", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{ldap_dn_is_null}")
|
||||||
|
private String ldapDn;
|
||||||
|
|
||||||
|
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{ldap_password_is_null}")
|
||||||
|
private String ldapPassword;
|
||||||
|
|
||||||
|
@Schema(description = "用户过滤器", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{ldap_user_filter_is_null}")
|
||||||
|
private String ldapUserFilter;
|
||||||
|
|
||||||
|
@Schema(description = "用户OU", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{ldap_ou_is_null}")
|
||||||
|
private String ldapUserOu;
|
||||||
|
|
||||||
|
@Schema(description = "LDAP属性映射", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{ldap_user_mapping_is_null}")
|
||||||
|
private String ldapUserMapping;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package io.metersphere.sdk.ldap.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class LdapRequest implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "LDAP地址", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{ldap_url_is_null}")
|
||||||
|
private String ldapUrl;
|
||||||
|
|
||||||
|
@Schema(description = "LDAP绑定DN", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{ldap_dn_is_null}")
|
||||||
|
private String ladpDn;
|
||||||
|
|
||||||
|
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{ldap_password_is_null}")
|
||||||
|
private String ladpPassword;
|
||||||
|
}
|
|
@ -4,6 +4,9 @@ import com.github.pagehelper.Page;
|
||||||
import com.github.pagehelper.PageHelper;
|
import com.github.pagehelper.PageHelper;
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
import io.metersphere.sdk.dto.BasePageRequest;
|
import io.metersphere.sdk.dto.BasePageRequest;
|
||||||
|
import io.metersphere.sdk.ldap.service.LdapService;
|
||||||
|
import io.metersphere.sdk.ldap.vo.LdapLoginRequest;
|
||||||
|
import io.metersphere.sdk.ldap.vo.LdapRequest;
|
||||||
import io.metersphere.sdk.log.annotation.Log;
|
import io.metersphere.sdk.log.annotation.Log;
|
||||||
import io.metersphere.sdk.log.constants.OperationLogType;
|
import io.metersphere.sdk.log.constants.OperationLogType;
|
||||||
import io.metersphere.sdk.util.PageUtils;
|
import io.metersphere.sdk.util.PageUtils;
|
||||||
|
@ -17,6 +20,7 @@ import io.metersphere.system.service.AuthSourceService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.Data;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
@ -27,10 +31,14 @@ import java.util.List;
|
||||||
@Tag(name = "认证设置")
|
@Tag(name = "认证设置")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/system/authsource")
|
@RequestMapping("/system/authsource")
|
||||||
|
@Data
|
||||||
public class AuthSourceController {
|
public class AuthSourceController {
|
||||||
@Resource
|
@Resource
|
||||||
private AuthSourceService authSourceService;
|
private AuthSourceService authSourceService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LdapService ldapService;
|
||||||
|
|
||||||
@PostMapping("/list")
|
@PostMapping("/list")
|
||||||
@Operation(summary = "认证设置列表查询")
|
@Operation(summary = "认证设置列表查询")
|
||||||
@RequiresPermissions(PermissionConstants.SYSTEM_PARAMETER_SETTING_AUTH_READ)
|
@RequiresPermissions(PermissionConstants.SYSTEM_PARAMETER_SETTING_AUTH_READ)
|
||||||
|
@ -76,7 +84,21 @@ public class AuthSourceController {
|
||||||
@Operation(summary = "更新状态")
|
@Operation(summary = "更新状态")
|
||||||
@RequiresPermissions(PermissionConstants.SYSTEM_PARAMETER_SETTING_AUTH_READ_UPDATE)
|
@RequiresPermissions(PermissionConstants.SYSTEM_PARAMETER_SETTING_AUTH_READ_UPDATE)
|
||||||
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request.getId())", msClass = AuthSourceLogService.class)
|
@Log(type = OperationLogType.UPDATE, expression = "#msClass.updateLog(#request.getId())", msClass = AuthSourceLogService.class)
|
||||||
public AuthSource updateStatus(@Validated @RequestBody AuthSourceStatusRequest request ) {
|
public AuthSource updateStatus(@Validated @RequestBody AuthSourceStatusRequest request) {
|
||||||
return authSourceService.updateStatus(request.getId(), request.getEnable());
|
return authSourceService.updateStatus(request.getId(), request.getEnable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/ldap/test-connect")
|
||||||
|
@Operation(summary = "ladp测试连接")
|
||||||
|
@RequiresPermissions(PermissionConstants.SYSTEM_PARAMETER_SETTING_AUTH_READ_UPDATE)
|
||||||
|
public void ldapTestConnect(@Validated @RequestBody LdapRequest request) {
|
||||||
|
ldapService.testConnect(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/ldap/test-login")
|
||||||
|
@RequiresPermissions(PermissionConstants.SYSTEM_PARAMETER_SETTING_AUTH_READ_UPDATE)
|
||||||
|
public void testLogin(@RequestBody LdapLoginRequest request) {
|
||||||
|
ldapService.testLogin(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import io.metersphere.system.domain.SystemParameter;
|
||||||
import io.metersphere.system.mapper.SystemParameterMapper;
|
import io.metersphere.system.mapper.SystemParameterMapper;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
@ -62,6 +63,11 @@ public class BaseDisplayService {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
String[] split = systemParameter.getParamValue().split("[.\n]");
|
||||||
|
if (StringUtils.equalsAnyIgnoreCase("svg", split[split.length - 1])) {
|
||||||
|
contentType = MediaType.valueOf("image/svg+xml");
|
||||||
|
}
|
||||||
|
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.contentType(contentType)
|
.contentType(contentType)
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
|
||||||
|
|
|
@ -5,18 +5,26 @@ import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
import io.metersphere.sdk.constants.SessionConstants;
|
import io.metersphere.sdk.constants.SessionConstants;
|
||||||
import io.metersphere.sdk.controller.handler.ResultHolder;
|
import io.metersphere.sdk.controller.handler.ResultHolder;
|
||||||
import io.metersphere.sdk.dto.BasePageRequest;
|
import io.metersphere.sdk.dto.BasePageRequest;
|
||||||
|
import io.metersphere.sdk.ldap.service.LdapService;
|
||||||
|
import io.metersphere.sdk.ldap.vo.LdapLoginRequest;
|
||||||
|
import io.metersphere.sdk.ldap.vo.LdapRequest;
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
import io.metersphere.sdk.util.Pager;
|
import io.metersphere.sdk.util.Pager;
|
||||||
import io.metersphere.system.domain.AuthSource;
|
import io.metersphere.system.domain.AuthSource;
|
||||||
import io.metersphere.system.request.AuthSourceRequest;
|
import io.metersphere.system.request.AuthSourceRequest;
|
||||||
import io.metersphere.system.request.AuthSourceStatusRequest;
|
import io.metersphere.system.request.AuthSourceStatusRequest;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
import org.junit.jupiter.api.Order;
|
import org.junit.jupiter.api.Order;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.ldap.core.DirContextAdapter;
|
||||||
|
import org.springframework.ldap.core.DirContextOperations;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.springframework.test.web.servlet.ResultMatcher;
|
import org.springframework.test.web.servlet.ResultMatcher;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
@ -50,13 +58,22 @@ public class AuthSourceControllerTests extends BaseTest {
|
||||||
|
|
||||||
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
|
private static final ResultMatcher ERROR_REQUEST_MATCHER = status().is5xxServerError();
|
||||||
|
|
||||||
|
public static final String LDAP_TEST_CONNECT = "/system/authsource/ldap/test-connect";
|
||||||
|
|
||||||
|
public static final String LDAP_TEST_LOGIN = "/system/authsource/ldap/test-login";
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private LdapService ldapService;
|
||||||
|
@Resource
|
||||||
|
AuthSourceController authSourceController;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(1)
|
@Order(1)
|
||||||
public void testAddSource() throws Exception {
|
public void testAddSource() throws Exception {
|
||||||
AuthSourceRequest authSource = new AuthSourceRequest();
|
AuthSourceRequest authSource = new AuthSourceRequest();
|
||||||
authSource.setName("测试CAS");
|
authSource.setName("测试CAS");
|
||||||
authSource.setType("CAS");
|
authSource.setType("CAS");
|
||||||
this.requestPost(AUTH_SOURCE_ADD, authSource,ERROR_REQUEST_MATCHER);
|
this.requestPost(AUTH_SOURCE_ADD, authSource, ERROR_REQUEST_MATCHER);
|
||||||
authSource.setConfiguration("123");
|
authSource.setConfiguration("123");
|
||||||
this.requestPost(AUTH_SOURCE_ADD, authSource);
|
this.requestPost(AUTH_SOURCE_ADD, authSource);
|
||||||
|
|
||||||
|
@ -180,4 +197,46 @@ public class AuthSourceControllerTests extends BaseTest {
|
||||||
.andExpect(resultMatcher).andDo(print())
|
.andExpect(resultMatcher).andDo(print())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(11)
|
||||||
|
public void testLdapConnectMock() throws Exception {
|
||||||
|
authSourceController.setLdapService(ldapService);
|
||||||
|
LdapRequest ldapRequest = getRequest("ldaps://127.1.1.1", "cn=admin,dc=example,dc=org", "admin");
|
||||||
|
Mockito.doNothing().when(ldapService).testConnect(ldapRequest);
|
||||||
|
this.requestPostAndReturn(LDAP_TEST_CONNECT, ldapRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(12)
|
||||||
|
public void testLdapLoginMock() throws Exception {
|
||||||
|
authSourceController.setLdapService(ldapService);
|
||||||
|
LdapLoginRequest loginRequest = getLoginRequest("ldap://127.1.1.1", "cn=admin,dc=example,dc=org", "admin", "cn=admin,dc=example,dc=org", "(|(uid={0})(mail={0}))", "{\"username\":\"uid\",\"name\":\"cn\",\"email\":\"mail\"}", "admin", "admin");
|
||||||
|
DirContextOperations operations = new DirContextAdapter();
|
||||||
|
Mockito.when(ldapService.testLogin(loginRequest)).thenReturn(operations);
|
||||||
|
this.requestPostAndReturn(LDAP_TEST_LOGIN, loginRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LdapLoginRequest getLoginRequest(String ldapUrl, String ldapDn, String ldapPassword, String ldapUserOu, String ldapUserFilter, String ldapUserMapping, String username, String password) {
|
||||||
|
LdapLoginRequest loginRequest = new LdapLoginRequest();
|
||||||
|
loginRequest.setLdapUrl(ldapUrl);
|
||||||
|
loginRequest.setLdapDn(ldapDn);
|
||||||
|
loginRequest.setLdapPassword(ldapPassword);
|
||||||
|
loginRequest.setLdapUserOu(ldapUserOu);
|
||||||
|
loginRequest.setLdapUserFilter(ldapUserFilter);
|
||||||
|
loginRequest.setLdapUserMapping(ldapUserMapping);
|
||||||
|
loginRequest.setUsername(username);
|
||||||
|
loginRequest.setPassword(password);
|
||||||
|
return loginRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private LdapRequest getRequest(String ldapUrl, String ldapDn, String ldapPassword) {
|
||||||
|
LdapRequest ldapRequest = new LdapRequest();
|
||||||
|
ldapRequest.setLdapUrl(ldapUrl);
|
||||||
|
ldapRequest.setLadpDn(ldapDn);
|
||||||
|
ldapRequest.setLadpPassword(ldapPassword);
|
||||||
|
return ldapRequest;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package io.metersphere.system.controller.param;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class LdapLoginRequestDefinition {
|
||||||
|
|
||||||
|
@NotBlank(message = "{ldap_url_is_null}")
|
||||||
|
private String ldapUrl;
|
||||||
|
|
||||||
|
@NotBlank(message = "{ldap_dn_is_null}")
|
||||||
|
private String ldapDn;
|
||||||
|
|
||||||
|
@NotBlank(message = "{ldap_password_is_null}")
|
||||||
|
private String ldapPassword;
|
||||||
|
|
||||||
|
@NotBlank(message = "{ldap_user_filter_is_null}")
|
||||||
|
private String ldapUserFilter;
|
||||||
|
|
||||||
|
@NotBlank(message = "{ldap_ou_is_null}")
|
||||||
|
private String ldapUserOu;
|
||||||
|
|
||||||
|
@NotBlank(message = "{ldap_user_mapping_is_null}")
|
||||||
|
private String ldapUserMapping;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package io.metersphere.system.controller.param;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class LdapRequestDefinition {
|
||||||
|
|
||||||
|
@NotBlank(message = "{ldap_url_is_null}")
|
||||||
|
private String ldapUrl;
|
||||||
|
|
||||||
|
@NotBlank(message = "{ldap_dn_is_null}")
|
||||||
|
private String ladpDn;
|
||||||
|
|
||||||
|
@NotBlank(message = "{ldap_password_is_null}")
|
||||||
|
private String ladpPassword;
|
||||||
|
}
|
Loading…
Reference in New Issue