mirror of
https://gitee.com/dolphinscheduler/DolphinScheduler.git
synced 2024-12-01 03:37:46 +08:00
Merge branch 'dev' of https://github.com/apache/incubator-dolphinscheduler into dev
This commit is contained in:
commit
0f2684c00b
@ -14,6 +14,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.api.security;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.EnumValue;
|
||||
@ -24,6 +25,7 @@ import com.baomidou.mybatisplus.annotation.EnumValue;
|
||||
public enum AuthenticationType {
|
||||
|
||||
PASSWORD(0, "verify via user name and password"),
|
||||
LDAP(1, "verify via LDAP server"),
|
||||
;
|
||||
|
||||
AuthenticationType(int code, String desc) {
|
||||
|
@ -14,13 +14,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.api.security;
|
||||
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public interface Authenticator {
|
||||
/**
|
||||
* Verifying legality via username and password
|
||||
|
@ -14,9 +14,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.api.security;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.dolphinscheduler.api.security.impl.ldap.LdapAuthenticator;
|
||||
import org.apache.dolphinscheduler.api.security.impl.pwd.PasswordAuthenticator;
|
||||
import org.apache.dolphinscheduler.common.utils.StringUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -58,6 +62,9 @@ public class SecurityConfig {
|
||||
case PASSWORD:
|
||||
authenticator = new PasswordAuthenticator();
|
||||
break;
|
||||
case LDAP:
|
||||
authenticator = new LdapAuthenticator();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + authenticationType);
|
||||
}
|
||||
|
@ -14,9 +14,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dolphinscheduler.api.security;
|
||||
|
||||
package org.apache.dolphinscheduler.api.security.impl;
|
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.security.Authenticator;
|
||||
import org.apache.dolphinscheduler.api.service.SessionService;
|
||||
import org.apache.dolphinscheduler.api.service.UsersService;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
@ -24,26 +26,38 @@ import org.apache.dolphinscheduler.common.Constants;
|
||||
import org.apache.dolphinscheduler.common.enums.Flag;
|
||||
import org.apache.dolphinscheduler.dao.entity.Session;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class PasswordAuthenticator implements Authenticator {
|
||||
private static final Logger logger = LoggerFactory.getLogger(PasswordAuthenticator.class);
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public abstract class AbstractAuthenticator implements Authenticator {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AbstractAuthenticator.class);
|
||||
|
||||
@Autowired
|
||||
private UsersService userService;
|
||||
@Autowired
|
||||
private SessionService sessionService;
|
||||
|
||||
/**
|
||||
* user login and return user in db
|
||||
*
|
||||
* @param userId user identity field
|
||||
* @param password user login password
|
||||
* @param extra extra user login field
|
||||
* @return user object in databse
|
||||
*/
|
||||
public abstract User login(String userId, String password, String extra);
|
||||
|
||||
@Override
|
||||
public Result<Map<String, String>> authenticate(String username, String password, String extra) {
|
||||
public Result<Map<String, String>> authenticate(String userId, String password, String extra) {
|
||||
Result<Map<String, String>> result = new Result<>();
|
||||
// verify username and password
|
||||
User user = userService.queryUser(username, password);
|
||||
User user = login(userId, password, extra);
|
||||
if (user == null) {
|
||||
result.setCode(Status.USER_NAME_PASSWD_ERROR.getCode());
|
||||
result.setMsg(Status.USER_NAME_PASSWD_ERROR.getMsg());
|
||||
@ -64,7 +78,7 @@ public class PasswordAuthenticator implements Authenticator {
|
||||
result.setMsg(Status.LOGIN_SESSION_FAILED.getMsg());
|
||||
return result;
|
||||
}
|
||||
logger.info("sessionId : {}" , sessionId);
|
||||
logger.info("sessionId : {}", sessionId);
|
||||
result.setData(Collections.singletonMap(Constants.SESSION_ID, sessionId));
|
||||
result.setCode(Status.SUCCESS.getCode());
|
||||
result.setMsg(Status.LOGIN_SUCCESS.getMsg());
|
||||
@ -81,4 +95,5 @@ public class PasswordAuthenticator implements Authenticator {
|
||||
//get user object from session
|
||||
return userService.queryUser(session.getUserId());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.api.security.impl.ldap;
|
||||
|
||||
import org.apache.dolphinscheduler.api.security.impl.AbstractAuthenticator;
|
||||
import org.apache.dolphinscheduler.api.service.UsersService;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class LdapAuthenticator extends AbstractAuthenticator {
|
||||
@Autowired
|
||||
private UsersService usersService;
|
||||
@Autowired
|
||||
LdapService ldapService;
|
||||
|
||||
@Override
|
||||
public User login(String userId, String password, String extra) {
|
||||
User user = null;
|
||||
String ldapEmail = ldapService.ldapLogin(userId, password);
|
||||
if (ldapEmail != null) {
|
||||
//check if user exist
|
||||
user = usersService.getUserByUserName(userId);
|
||||
if (user == null) {
|
||||
user = usersService.createUser(ldapService.getUserType(userId), userId, ldapEmail);
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.api.security.impl.ldap;
|
||||
|
||||
import org.apache.dolphinscheduler.common.enums.UserType;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
import javax.naming.ldap.InitialLdapContext;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Configuration
|
||||
public class LdapService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LdapService.class);
|
||||
|
||||
@Value("${security.authentication.ldap.user.admin:null}")
|
||||
private String adminUserId;
|
||||
|
||||
@Value("${ldap.urls:null}")
|
||||
private String ldapUrls;
|
||||
|
||||
@Value("${ldap.base.dn:null}")
|
||||
private String ldapBaseDn;
|
||||
|
||||
@Value("${ldap.username:null}")
|
||||
private String ldapSecurityPrincipal;
|
||||
|
||||
@Value("${ldap.password:null}")
|
||||
private String ldapPrincipalPassword;
|
||||
|
||||
@Value("${ldap.user.identity.attribute:null}")
|
||||
private String ldapUserIdentifyingAttribute;
|
||||
|
||||
@Value("${ldap.user.email.attribute:null}")
|
||||
private String ldapEmailAttribute;
|
||||
|
||||
/***
|
||||
* get user type by configured admin userId
|
||||
* @param userId login userId
|
||||
* @return user type
|
||||
*/
|
||||
public UserType getUserType(String userId) {
|
||||
return adminUserId.equalsIgnoreCase(userId) ? UserType.ADMIN_USER : UserType.GENERAL_USER;
|
||||
}
|
||||
|
||||
/**
|
||||
* login by userId and return user email
|
||||
*
|
||||
* @param userId user identity id
|
||||
* @param userPwd user login password
|
||||
* @return user email
|
||||
*/
|
||||
public String ldapLogin(String userId, String userPwd) {
|
||||
Properties searchEnv = getManagerLdapEnv();
|
||||
try {
|
||||
//Connect to the LDAP server and Authenticate with a service user of whom we know the DN and credentials
|
||||
LdapContext ctx = new InitialLdapContext(searchEnv, null);
|
||||
SearchControls sc = new SearchControls();
|
||||
sc.setReturningAttributes(new String[]{ldapEmailAttribute});
|
||||
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
||||
String searchFilter = String.format("(%s=%s)", ldapUserIdentifyingAttribute, userId);
|
||||
//Search for the user you want to authenticate, search him with some attribute
|
||||
NamingEnumeration<SearchResult> results = ctx.search(ldapBaseDn, searchFilter, sc);
|
||||
if (results.hasMore()) {
|
||||
// get the users DN (distinguishedName) from the result
|
||||
SearchResult result = results.next();
|
||||
NamingEnumeration attrs = result.getAttributes().getAll();
|
||||
while (attrs.hasMore()) {
|
||||
//Open another connection to the LDAP server with the found DN and the password
|
||||
searchEnv.put(Context.SECURITY_PRINCIPAL, result.getNameInNamespace());
|
||||
searchEnv.put(Context.SECURITY_CREDENTIALS, userPwd);
|
||||
try {
|
||||
new InitialDirContext(searchEnv);
|
||||
} catch (Exception e) {
|
||||
logger.warn("invalid ldap credentials or ldap search error", e);
|
||||
return null;
|
||||
}
|
||||
Attribute attr = (Attribute) attrs.next();
|
||||
if (attr.getID().equals(ldapEmailAttribute)) {
|
||||
return (String) attr.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
logger.error("ldap search error", e);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/***
|
||||
* get ldap env fot ldap server search
|
||||
* @return Properties
|
||||
*/
|
||||
Properties getManagerLdapEnv() {
|
||||
Properties env = new Properties();
|
||||
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
|
||||
env.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
env.put(Context.SECURITY_PRINCIPAL, ldapSecurityPrincipal);
|
||||
env.put(Context.SECURITY_CREDENTIALS, ldapPrincipalPassword);
|
||||
env.put(Context.PROVIDER_URL, ldapUrls);
|
||||
return env;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.api.security.impl.pwd;
|
||||
|
||||
import org.apache.dolphinscheduler.api.security.impl.AbstractAuthenticator;
|
||||
import org.apache.dolphinscheduler.api.service.UsersService;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public class PasswordAuthenticator extends AbstractAuthenticator {
|
||||
@Autowired
|
||||
private UsersService userService;
|
||||
|
||||
@Override
|
||||
public User login(String userId, String password, String extra) {
|
||||
return userService.queryUser(userId, password);
|
||||
}
|
||||
}
|
@ -14,10 +14,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.api.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.apache.dolphinscheduler.api.dto.resources.ResourceComponent;
|
||||
import org.apache.dolphinscheduler.api.dto.resources.visitor.ResourceTreeVisitor;
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
@ -29,20 +28,49 @@ import org.apache.dolphinscheduler.common.Constants;
|
||||
import org.apache.dolphinscheduler.common.enums.Flag;
|
||||
import org.apache.dolphinscheduler.common.enums.ResourceType;
|
||||
import org.apache.dolphinscheduler.common.enums.UserType;
|
||||
import org.apache.dolphinscheduler.common.utils.*;
|
||||
import org.apache.dolphinscheduler.dao.entity.*;
|
||||
import org.apache.dolphinscheduler.dao.mapper.*;
|
||||
import org.apache.dolphinscheduler.common.utils.CollectionUtils;
|
||||
import org.apache.dolphinscheduler.common.utils.EncryptionUtils;
|
||||
import org.apache.dolphinscheduler.common.utils.HadoopUtils;
|
||||
import org.apache.dolphinscheduler.common.utils.PropertyUtils;
|
||||
import org.apache.dolphinscheduler.common.utils.StringUtils;
|
||||
import org.apache.dolphinscheduler.dao.entity.AlertGroup;
|
||||
import org.apache.dolphinscheduler.dao.entity.DatasourceUser;
|
||||
import org.apache.dolphinscheduler.dao.entity.ProjectUser;
|
||||
import org.apache.dolphinscheduler.dao.entity.Resource;
|
||||
import org.apache.dolphinscheduler.dao.entity.ResourcesUser;
|
||||
import org.apache.dolphinscheduler.dao.entity.Tenant;
|
||||
import org.apache.dolphinscheduler.dao.entity.UDFUser;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.mapper.AlertGroupMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.DataSourceUserMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ProcessDefinitionMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectUserMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ResourceMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ResourceUserMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.TenantMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.UDFUserMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.UserMapper;
|
||||
import org.apache.dolphinscheduler.dao.utils.ResourceProcessDefinitionUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
/**
|
||||
* user service
|
||||
@ -109,7 +137,7 @@ public class UsersService extends BaseService {
|
||||
String msg = this.checkUserParams(userName, userPassword, email, phone);
|
||||
|
||||
if (!StringUtils.isEmpty(msg)) {
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,msg);
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, msg);
|
||||
return result;
|
||||
}
|
||||
if (!isAdmin(loginUser)) {
|
||||
@ -126,12 +154,12 @@ public class UsersService extends BaseService {
|
||||
|
||||
Tenant tenant = tenantMapper.queryById(tenantId);
|
||||
// resource upload startup
|
||||
if (PropertyUtils.getResUploadStartupState()){
|
||||
if (PropertyUtils.getResUploadStartupState()) {
|
||||
// if tenant not exists
|
||||
if (!HadoopUtils.getInstance().exists(HadoopUtils.getHdfsTenantDir(tenant.getTenantCode()))){
|
||||
if (!HadoopUtils.getInstance().exists(HadoopUtils.getHdfsTenantDir(tenant.getTenantCode()))) {
|
||||
createTenantDirIfNotExists(tenant.getTenantCode());
|
||||
}
|
||||
String userPath = HadoopUtils.getHdfsUserDir(tenant.getTenantCode(),user.getId());
|
||||
String userPath = HadoopUtils.getHdfsUserDir(tenant.getTenantCode(), user.getId());
|
||||
HadoopUtils.getInstance().mkdir(userPath);
|
||||
}
|
||||
|
||||
@ -142,12 +170,12 @@ public class UsersService extends BaseService {
|
||||
|
||||
@Transactional(rollbackFor = RuntimeException.class)
|
||||
public User createUser(String userName,
|
||||
String userPassword,
|
||||
String email,
|
||||
int tenantId,
|
||||
String phone,
|
||||
String queue,
|
||||
int state) {
|
||||
String userPassword,
|
||||
String email,
|
||||
int tenantId,
|
||||
String phone,
|
||||
String queue,
|
||||
int state) {
|
||||
User user = new User();
|
||||
Date now = new Date();
|
||||
|
||||
@ -161,7 +189,7 @@ public class UsersService extends BaseService {
|
||||
user.setUserType(UserType.GENERAL_USER);
|
||||
user.setCreateTime(now);
|
||||
user.setUpdateTime(now);
|
||||
if (StringUtils.isEmpty(queue)){
|
||||
if (StringUtils.isEmpty(queue)) {
|
||||
queue = "";
|
||||
}
|
||||
user.setQueue(queue);
|
||||
@ -171,8 +199,40 @@ public class UsersService extends BaseService {
|
||||
return user;
|
||||
}
|
||||
|
||||
/***
|
||||
* create User for ldap login
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public User createUser(UserType userType, String userId, String email) {
|
||||
User user = new User();
|
||||
Date now = new Date();
|
||||
|
||||
user.setUserName(userId);
|
||||
user.setEmail(email);
|
||||
// create general users, administrator users are currently built-in
|
||||
user.setUserType(userType);
|
||||
user.setCreateTime(now);
|
||||
user.setUpdateTime(now);
|
||||
user.setQueue("");
|
||||
|
||||
// save user
|
||||
userMapper.insert(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* get user by user name
|
||||
*
|
||||
* @param userName user name
|
||||
* @return exist user or null
|
||||
*/
|
||||
public User getUserByUserName(String userName) {
|
||||
return userMapper.queryByUserNameAccurately(userName);
|
||||
}
|
||||
|
||||
/**
|
||||
* query user by id
|
||||
*
|
||||
* @param id id
|
||||
* @return user info
|
||||
*/
|
||||
@ -182,6 +242,7 @@ public class UsersService extends BaseService {
|
||||
|
||||
/**
|
||||
* query user
|
||||
*
|
||||
* @param name name
|
||||
* @return user info
|
||||
*/
|
||||
@ -203,6 +264,7 @@ public class UsersService extends BaseService {
|
||||
|
||||
/**
|
||||
* get user id by user name
|
||||
*
|
||||
* @param name user name
|
||||
* @return if name empty 0, user not exists -1, user exist user id
|
||||
*/
|
||||
@ -242,7 +304,7 @@ public class UsersService extends BaseService {
|
||||
IPage<User> scheduleList = userMapper.queryUserPaging(page, searchVal);
|
||||
|
||||
PageInfo<User> pageInfo = new PageInfo<>(pageNo, pageSize);
|
||||
pageInfo.setTotalCount((int)scheduleList.getTotal());
|
||||
pageInfo.setTotalCount((int) scheduleList.getTotal());
|
||||
pageInfo.setLists(scheduleList.getRecords());
|
||||
result.put(Constants.DATA_LIST, pageInfo);
|
||||
putMsg(result, Status.SUCCESS);
|
||||
@ -261,7 +323,7 @@ public class UsersService extends BaseService {
|
||||
* @param email email
|
||||
* @param tenantId tennat id
|
||||
* @param phone phone
|
||||
* @param queue queue
|
||||
* @param queue queue
|
||||
* @return update result code
|
||||
* @throws Exception exception
|
||||
*/
|
||||
@ -286,8 +348,8 @@ public class UsersService extends BaseService {
|
||||
}
|
||||
if (StringUtils.isNotEmpty(userName)) {
|
||||
|
||||
if (!CheckUtils.checkUserName(userName)){
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,userName);
|
||||
if (!CheckUtils.checkUserName(userName)) {
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, userName);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -300,23 +362,23 @@ public class UsersService extends BaseService {
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(userPassword)) {
|
||||
if (!CheckUtils.checkPassword(userPassword)){
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,userPassword);
|
||||
if (!CheckUtils.checkPassword(userPassword)) {
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, userPassword);
|
||||
return result;
|
||||
}
|
||||
user.setUserPassword(EncryptionUtils.getMd5(userPassword));
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(email)) {
|
||||
if (!CheckUtils.checkEmail(email)){
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,email);
|
||||
if (!CheckUtils.checkEmail(email)) {
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, email);
|
||||
return result;
|
||||
}
|
||||
user.setEmail(email);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(phone) && !CheckUtils.checkPhone(phone)) {
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,phone);
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, phone);
|
||||
return result;
|
||||
}
|
||||
user.setPhone(phone);
|
||||
@ -332,13 +394,13 @@ public class UsersService extends BaseService {
|
||||
Tenant newTenant = tenantMapper.queryById(tenantId);
|
||||
if (newTenant != null) {
|
||||
// if hdfs startup
|
||||
if (PropertyUtils.getResUploadStartupState() && oldTenant != null){
|
||||
if (PropertyUtils.getResUploadStartupState() && oldTenant != null) {
|
||||
String newTenantCode = newTenant.getTenantCode();
|
||||
String oldResourcePath = HadoopUtils.getHdfsResDir(oldTenant.getTenantCode());
|
||||
String oldUdfsPath = HadoopUtils.getHdfsUdfDir(oldTenant.getTenantCode());
|
||||
|
||||
// if old tenant dir exists
|
||||
if (HadoopUtils.getInstance().exists(oldResourcePath)){
|
||||
if (HadoopUtils.getInstance().exists(oldResourcePath)) {
|
||||
String newResourcePath = HadoopUtils.getHdfsResDir(newTenantCode);
|
||||
String newUdfsPath = HadoopUtils.getHdfsUdfDir(newTenantCode);
|
||||
|
||||
@ -361,18 +423,18 @@ public class UsersService extends BaseService {
|
||||
}
|
||||
|
||||
//Delete the user from the old tenant directory
|
||||
String oldUserPath = HadoopUtils.getHdfsUserDir(oldTenant.getTenantCode(),userId);
|
||||
String oldUserPath = HadoopUtils.getHdfsUserDir(oldTenant.getTenantCode(), userId);
|
||||
HadoopUtils.getInstance().delete(oldUserPath, true);
|
||||
}else {
|
||||
} else {
|
||||
// if old tenant dir not exists , create
|
||||
createTenantDirIfNotExists(oldTenant.getTenantCode());
|
||||
}
|
||||
|
||||
if (HadoopUtils.getInstance().exists(HadoopUtils.getHdfsTenantDir(newTenant.getTenantCode()))){
|
||||
if (HadoopUtils.getInstance().exists(HadoopUtils.getHdfsTenantDir(newTenant.getTenantCode()))) {
|
||||
//create user in the new tenant directory
|
||||
String newUserPath = HadoopUtils.getHdfsUserDir(newTenant.getTenantCode(),user.getId());
|
||||
String newUserPath = HadoopUtils.getHdfsUserDir(newTenant.getTenantCode(), user.getId());
|
||||
HadoopUtils.getInstance().mkdir(newUserPath);
|
||||
}else {
|
||||
} else {
|
||||
// if new tenant dir not exists , create
|
||||
createTenantDirIfNotExists(newTenant.getTenantCode());
|
||||
}
|
||||
@ -414,7 +476,7 @@ public class UsersService extends BaseService {
|
||||
|
||||
if (user != null) {
|
||||
if (PropertyUtils.getResUploadStartupState()) {
|
||||
String userPath = HadoopUtils.getHdfsUserDir(user.getTenantCode(),id);
|
||||
String userPath = HadoopUtils.getHdfsUserDir(user.getTenantCode(), id);
|
||||
if (HadoopUtils.getInstance().exists(userPath)) {
|
||||
HadoopUtils.getInstance().delete(userPath, true);
|
||||
}
|
||||
@ -493,7 +555,7 @@ public class UsersService extends BaseService {
|
||||
return result;
|
||||
}
|
||||
User user = userMapper.selectById(userId);
|
||||
if(user == null){
|
||||
if (user == null) {
|
||||
putMsg(result, Status.USER_NOT_EXIST, userId);
|
||||
return result;
|
||||
}
|
||||
@ -504,7 +566,7 @@ public class UsersService extends BaseService {
|
||||
// need authorize resource id set
|
||||
for (String resourceFullId : resourceFullIdArr) {
|
||||
String[] resourceIdArr = resourceFullId.split("-");
|
||||
for (int i=0;i<=resourceIdArr.length-1;i++) {
|
||||
for (int i = 0; i <= resourceIdArr.length - 1; i++) {
|
||||
int resourceIdValue = Integer.parseInt(resourceIdArr[i]);
|
||||
needAuthorizeResIds.add(resourceIdValue);
|
||||
}
|
||||
@ -531,7 +593,7 @@ public class UsersService extends BaseService {
|
||||
if (CollectionUtils.isNotEmpty(resourceIdSet)) {
|
||||
logger.error("can't be deleted,because it is used of process definition");
|
||||
for (Integer resId : resourceIdSet) {
|
||||
logger.error("resource id:{} is used of process definition {}",resId,resourceProcessMap.get(resId));
|
||||
logger.error("resource id:{} is used of process definition {}", resId, resourceProcessMap.get(resId));
|
||||
}
|
||||
putMsg(result, Status.RESOURCE_IS_USED);
|
||||
return result;
|
||||
@ -558,7 +620,7 @@ public class UsersService extends BaseService {
|
||||
resourcesUser.setResourcesId(resourceIdValue);
|
||||
if (resource.isDirectory()) {
|
||||
resourcesUser.setPerm(Constants.AUTHORIZE_READABLE_PERM);
|
||||
}else{
|
||||
} else {
|
||||
resourcesUser.setPerm(Constants.AUTHORIZE_WRITABLE_PERM);
|
||||
}
|
||||
|
||||
@ -591,7 +653,7 @@ public class UsersService extends BaseService {
|
||||
return result;
|
||||
}
|
||||
User user = userMapper.selectById(userId);
|
||||
if(user == null){
|
||||
if (user == null) {
|
||||
putMsg(result, Status.USER_NOT_EXIST, userId);
|
||||
return result;
|
||||
}
|
||||
@ -626,7 +688,7 @@ public class UsersService extends BaseService {
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @param userId user id
|
||||
* @param datasourceIds data source id array
|
||||
* @param datasourceIds data source id array
|
||||
* @return grant result code
|
||||
*/
|
||||
@Transactional(rollbackFor = RuntimeException.class)
|
||||
@ -639,7 +701,7 @@ public class UsersService extends BaseService {
|
||||
return result;
|
||||
}
|
||||
User user = userMapper.selectById(userId);
|
||||
if(user == null){
|
||||
if (user == null) {
|
||||
putMsg(result, Status.USER_NOT_EXIST, userId);
|
||||
return result;
|
||||
}
|
||||
@ -738,7 +800,7 @@ public class UsersService extends BaseService {
|
||||
return result;
|
||||
}
|
||||
|
||||
List<User> userList = userMapper.selectList(null );
|
||||
List<User> userList = userMapper.selectList(null);
|
||||
result.put(Constants.DATA_LIST, userList);
|
||||
putMsg(result, Status.SUCCESS);
|
||||
|
||||
@ -782,7 +844,7 @@ public class UsersService extends BaseService {
|
||||
return result;
|
||||
}
|
||||
|
||||
List<User> userList = userMapper.selectList(null );
|
||||
List<User> userList = userMapper.selectList(null);
|
||||
List<User> resultUsers = new ArrayList<>();
|
||||
Set<User> userSet = null;
|
||||
if (userList != null && userList.size() > 0) {
|
||||
@ -833,11 +895,6 @@ public class UsersService extends BaseService {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param userName
|
||||
* @param password
|
||||
* @param email
|
||||
* @param phone
|
||||
* @return if check failed return the field, otherwise return null
|
||||
*/
|
||||
private String checkUserParams(String userName, String password, String email, String phone) {
|
||||
@ -862,35 +919,36 @@ public class UsersService extends BaseService {
|
||||
|
||||
/**
|
||||
* copy resource files
|
||||
*
|
||||
* @param resourceComponent resource component
|
||||
* @param srcBasePath src base path
|
||||
* @param dstBasePath dst base path
|
||||
* @throws IOException io exception
|
||||
* @param srcBasePath src base path
|
||||
* @param dstBasePath dst base path
|
||||
* @throws IOException io exception
|
||||
*/
|
||||
private void copyResourceFiles(ResourceComponent resourceComponent, String srcBasePath, String dstBasePath) throws IOException {
|
||||
List<ResourceComponent> components = resourceComponent.getChildren();
|
||||
|
||||
if (CollectionUtils.isNotEmpty(components)) {
|
||||
for (ResourceComponent component:components) {
|
||||
for (ResourceComponent component : components) {
|
||||
// verify whether exist
|
||||
if (!HadoopUtils.getInstance().exists(String.format("%s/%s",srcBasePath,component.getFullName()))){
|
||||
logger.error("resource file: {} not exist,copy error",component.getFullName());
|
||||
if (!HadoopUtils.getInstance().exists(String.format("%s/%s", srcBasePath, component.getFullName()))) {
|
||||
logger.error("resource file: {} not exist,copy error", component.getFullName());
|
||||
throw new ServiceException(Status.RESOURCE_NOT_EXIST);
|
||||
}
|
||||
|
||||
if (!component.isDirctory()) {
|
||||
// copy it to dst
|
||||
HadoopUtils.getInstance().copy(String.format("%s/%s",srcBasePath,component.getFullName()),String.format("%s/%s",dstBasePath,component.getFullName()),false,true);
|
||||
HadoopUtils.getInstance().copy(String.format("%s/%s", srcBasePath, component.getFullName()), String.format("%s/%s", dstBasePath, component.getFullName()), false, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(CollectionUtils.isEmpty(component.getChildren())) {
|
||||
if (CollectionUtils.isEmpty(component.getChildren())) {
|
||||
// if not exist,need create it
|
||||
if (!HadoopUtils.getInstance().exists(String.format("%s/%s",dstBasePath,component.getFullName()))) {
|
||||
HadoopUtils.getInstance().mkdir(String.format("%s/%s",dstBasePath,component.getFullName()));
|
||||
if (!HadoopUtils.getInstance().exists(String.format("%s/%s", dstBasePath, component.getFullName()))) {
|
||||
HadoopUtils.getInstance().mkdir(String.format("%s/%s", dstBasePath, component.getFullName()));
|
||||
}
|
||||
}else{
|
||||
copyResourceFiles(component,srcBasePath,dstBasePath);
|
||||
} else {
|
||||
copyResourceFiles(component, srcBasePath, dstBasePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -899,10 +957,10 @@ public class UsersService extends BaseService {
|
||||
/**
|
||||
* register user, default state is 0, default tenant_id is 1, no phone, no queue
|
||||
*
|
||||
* @param userName user name
|
||||
* @param userPassword user password
|
||||
* @param userName user name
|
||||
* @param userPassword user password
|
||||
* @param repeatPassword repeat password
|
||||
* @param email email
|
||||
* @param email email
|
||||
* @return register result code
|
||||
* @throws Exception exception
|
||||
*/
|
||||
@ -914,7 +972,7 @@ public class UsersService extends BaseService {
|
||||
String msg = this.checkUserParams(userName, userPassword, email, "");
|
||||
|
||||
if (!StringUtils.isEmpty(msg)) {
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR,msg);
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -932,7 +990,7 @@ public class UsersService extends BaseService {
|
||||
* activate user, only system admin have permission, change user state code 0 to 1
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @param userName user name
|
||||
* @param userName user name
|
||||
* @return create result code
|
||||
*/
|
||||
public Map<String, Object> activateUser(User loginUser, String userName) {
|
||||
@ -944,7 +1002,7 @@ public class UsersService extends BaseService {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!CheckUtils.checkUserName(userName)){
|
||||
if (!CheckUtils.checkUserName(userName)) {
|
||||
putMsg(result, Status.REQUEST_PARAMS_NOT_VALID_ERROR, userName);
|
||||
return result;
|
||||
}
|
||||
|
@ -45,6 +45,18 @@ spring.messages.basename=i18n/messages
|
||||
# Authentication types (supported types: PASSWORD)
|
||||
security.authentication.type=PASSWORD
|
||||
|
||||
|
||||
#============================================================================
|
||||
# LDAP Config
|
||||
# mock ldap server from https://www.forumsys.com/tutorials/integration-how-to/ldap/online-ldap-test-server/
|
||||
#============================================================================
|
||||
# admin userId
|
||||
#security.authentication.ldap.user.admin=read-only-admin
|
||||
# ldap server config
|
||||
#ldap.urls=ldap://ldap.forumsys.com:389/
|
||||
#ldap.base.dn=dc=example,dc=com
|
||||
#ldap.username=cn=read-only-admin,dc=example,dc=com
|
||||
#ldap.password=password
|
||||
#ldap.user.identity.attribute=uid
|
||||
#ldap.user.email.attribute=mail
|
||||
|
||||
|
||||
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.api.security;
|
||||
|
||||
import org.apache.dolphinscheduler.api.ApiApplicationServer;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = ApiApplicationServer.class)
|
||||
@TestPropertySource(properties = {
|
||||
"security.authentication.type=LDAP",
|
||||
})
|
||||
public class SecurityConfigLDAPTest {
|
||||
|
||||
@Autowired
|
||||
private SecurityConfig securityConfig;
|
||||
|
||||
@Test
|
||||
public void testAuthenticator() {
|
||||
Authenticator authenticator = securityConfig.authenticator();
|
||||
Assert.assertNotNull(authenticator);
|
||||
}
|
||||
}
|
@ -14,9 +14,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.api.security;
|
||||
|
||||
import org.apache.dolphinscheduler.api.ApiApplicationServer;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -30,7 +32,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||
@TestPropertySource(properties = {
|
||||
"security.authentication.type=PASSWORD",
|
||||
})
|
||||
public class SecurityConfigTest {
|
||||
public class SecurityConfigPasswordTest {
|
||||
|
||||
@Autowired
|
||||
private SecurityConfig securityConfig;
|
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.api.security.impl.ldap;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.dolphinscheduler.api.ApiApplicationServer;
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.service.SessionService;
|
||||
import org.apache.dolphinscheduler.api.service.UsersService;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.enums.Flag;
|
||||
import org.apache.dolphinscheduler.common.enums.UserType;
|
||||
import org.apache.dolphinscheduler.dao.entity.Session;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = ApiApplicationServer.class)
|
||||
@TestPropertySource(
|
||||
properties = {
|
||||
"security.authentication.type=LDAP",
|
||||
"security.authentication.ldap.user.admin=read-only-admin",
|
||||
"ldap.urls=ldap://ldap.forumsys.com:389/",
|
||||
"ldap.base.dn=dc=example,dc=com",
|
||||
"ldap.username=cn=read-only-admin,dc=example,dc=com",
|
||||
"ldap.password=password",
|
||||
"ldap.user.identity.attribute=uid",
|
||||
"ldap.user.email.attribute=mail",
|
||||
})
|
||||
public class LdapAuthenticatorTest {
|
||||
private static Logger logger = LoggerFactory.getLogger(LdapAuthenticatorTest.class);
|
||||
@Autowired
|
||||
protected AutowireCapableBeanFactory beanFactory;
|
||||
@MockBean
|
||||
private LdapService ldapService;
|
||||
@MockBean
|
||||
private SessionService sessionService;
|
||||
@MockBean
|
||||
private UsersService usersService;
|
||||
|
||||
private LdapAuthenticator ldapAuthenticator;
|
||||
|
||||
//test param
|
||||
private User mockUser;
|
||||
private Session mockSession;
|
||||
|
||||
private String ldapUid = "test";
|
||||
private String ldapUserPwd = "password";
|
||||
private String ldapEmail = "test@example.com";
|
||||
private String ip = "127.0.0.1";
|
||||
private UserType userType = UserType.GENERAL_USER;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ldapAuthenticator = new LdapAuthenticator();
|
||||
beanFactory.autowireBean(ldapAuthenticator);
|
||||
|
||||
mockUser = new User();
|
||||
mockUser.setId(1);
|
||||
mockUser.setUserName(ldapUid);
|
||||
mockUser.setEmail(ldapEmail);
|
||||
mockUser.setUserType(userType);
|
||||
mockUser.setState(Flag.YES.getCode());
|
||||
|
||||
mockSession = new Session();
|
||||
mockSession.setId(UUID.randomUUID().toString());
|
||||
mockSession.setIp(ip);
|
||||
mockSession.setUserId(1);
|
||||
mockSession.setLastLoginTime(new Date());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticate() {
|
||||
when(usersService.createUser(userType, ldapUid, ldapEmail)).thenReturn(mockUser);
|
||||
when(usersService.getUserByUserName(ldapUid)).thenReturn(mockUser);
|
||||
when(sessionService.createSession(mockUser, ip)).thenReturn(mockSession.getId());
|
||||
|
||||
when(ldapService.ldapLogin(ldapUid, ldapUserPwd)).thenReturn(ldapEmail);
|
||||
|
||||
Result result = ldapAuthenticator.authenticate(ldapUid, ldapUserPwd, ip);
|
||||
Assert.assertEquals(Status.SUCCESS.getCode(), (int) result.getCode());
|
||||
logger.info(result.toString());
|
||||
|
||||
when(sessionService.createSession(mockUser, ip)).thenReturn(null);
|
||||
result = ldapAuthenticator.authenticate(ldapUid, ldapUserPwd, ip);
|
||||
Assert.assertEquals(Status.LOGIN_SESSION_FAILED.getCode(), (int) result.getCode());
|
||||
|
||||
when(sessionService.createSession(mockUser, ip)).thenReturn(mockSession.getId());
|
||||
when(usersService.getUserByUserName(ldapUid)).thenReturn(null);
|
||||
result = ldapAuthenticator.authenticate(ldapUid, ldapUserPwd, ip);
|
||||
Assert.assertEquals(Status.USER_NAME_PASSWD_ERROR.getCode(), (int) result.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAuthUser() {
|
||||
HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
|
||||
when(usersService.queryUser(mockUser.getId())).thenReturn(mockUser);
|
||||
when(sessionService.getSession(request)).thenReturn(mockSession);
|
||||
|
||||
User user = ldapAuthenticator.getAuthUser(request);
|
||||
Assert.assertNotNull(user);
|
||||
|
||||
when(sessionService.getSession(request)).thenReturn(null);
|
||||
user = ldapAuthenticator.getAuthUser(request);
|
||||
Assert.assertNull(user);
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.api.security.impl.ldap;
|
||||
|
||||
import org.apache.dolphinscheduler.api.ApiApplicationServer;
|
||||
import org.apache.dolphinscheduler.common.enums.UserType;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = ApiApplicationServer.class)
|
||||
@TestPropertySource(
|
||||
properties = {
|
||||
"security.authentication.type=LDAP",
|
||||
"security.authentication.ldap.user.admin=read-only-admin",
|
||||
"ldap.urls=ldap://ldap.forumsys.com:389/",
|
||||
"ldap.base.dn=dc=example,dc=com",
|
||||
"ldap.username=cn=read-only-admin,dc=example,dc=com",
|
||||
"ldap.password=password",
|
||||
"ldap.user.identity.attribute=uid",
|
||||
"ldap.user.email.attribute=mail",
|
||||
})
|
||||
public class LdapServiceTest {
|
||||
@Autowired
|
||||
protected AutowireCapableBeanFactory beanFactory;
|
||||
|
||||
private LdapService ldapService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ldapService = new LdapService();
|
||||
beanFactory.autowireBean(ldapService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUserType() {
|
||||
UserType userType = ldapService.getUserType("read-only-admin");
|
||||
Assert.assertEquals(UserType.ADMIN_USER, userType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ldapLogin() {
|
||||
String email = ldapService.ldapLogin("tesla", "password");
|
||||
Assert.assertEquals("tesla@ldap.forumsys.com", email);
|
||||
|
||||
String email2 = ldapService.ldapLogin("tesla", "error password");
|
||||
Assert.assertNull(email2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ldapLoginError() {
|
||||
String email = ldapService.ldapLogin("tesla", "password");
|
||||
Assert.assertEquals("tesla@ldap.forumsys.com", email);
|
||||
|
||||
String email2 = ldapService.ldapLogin("tesla", "error password");
|
||||
Assert.assertNull(email2);
|
||||
}
|
||||
}
|
@ -14,7 +14,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dolphinscheduler.api.security;
|
||||
|
||||
package org.apache.dolphinscheduler.api.security.impl.pwd;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.dolphinscheduler.api.ApiApplicationServer;
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
@ -23,12 +26,17 @@ import org.apache.dolphinscheduler.api.service.UsersService;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.dao.entity.Session;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import static org.mockito.Mockito.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -36,9 +44,6 @@ import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = ApiApplicationServer.class)
|
||||
@ -58,7 +63,7 @@ public class PasswordAuthenticatorTest {
|
||||
private Session mockSession;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
public void setUp() {
|
||||
authenticator = new PasswordAuthenticator();
|
||||
beanFactory.autowireBean(authenticator);
|
||||
|
||||
@ -76,6 +81,13 @@ public class PasswordAuthenticatorTest {
|
||||
mockSession.setLastLoginTime(new Date());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogin() {
|
||||
when(usersService.queryUser("test", "test")).thenReturn(mockUser);
|
||||
User login = authenticator.login("test", "test", "127.0.0.1");
|
||||
Assert.assertNotNull(login);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticate() {
|
||||
when(usersService.queryUser("test", "test")).thenReturn(mockUser);
|
@ -14,10 +14,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.dolphinscheduler.api.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.utils.PageInfo;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
@ -29,7 +32,19 @@ import org.apache.dolphinscheduler.common.utils.EncryptionUtils;
|
||||
import org.apache.dolphinscheduler.dao.entity.Resource;
|
||||
import org.apache.dolphinscheduler.dao.entity.Tenant;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.mapper.*;
|
||||
import org.apache.dolphinscheduler.dao.mapper.AlertGroupMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.DataSourceUserMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ProjectUserMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ResourceMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.ResourceUserMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.TenantMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.UDFUserMapper;
|
||||
import org.apache.dolphinscheduler.dao.mapper.UserMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
@ -42,13 +57,8 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class UsersServiceTest {
|
||||
@ -73,30 +83,34 @@ public class UsersServiceTest {
|
||||
@Mock
|
||||
private ResourceMapper resourceMapper;
|
||||
|
||||
private String queueName ="UsersServiceTestQueue";
|
||||
|
||||
private String queueName = "UsersServiceTestQueue";
|
||||
|
||||
@Before
|
||||
public void before(){
|
||||
|
||||
|
||||
public void before() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void after(){
|
||||
public void after() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateUser(){
|
||||
public void testCreateUserForLdap() {
|
||||
String userName = "user1";
|
||||
String email = "user1@ldap.com";
|
||||
User user = usersService.createUser(UserType.ADMIN_USER, userName, email);
|
||||
Assert.assertNotNull(user);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateUser() {
|
||||
User user = new User();
|
||||
user.setUserType(UserType.ADMIN_USER);
|
||||
String userName = "userTest0001~";
|
||||
String userPassword = "userTest";
|
||||
String email = "123@qq.com";
|
||||
int tenantId = Integer.MAX_VALUE;
|
||||
String phone= "13456432345";
|
||||
String phone = "13456432345";
|
||||
int state = 1;
|
||||
try {
|
||||
//userName error
|
||||
@ -119,7 +133,7 @@ public class UsersServiceTest {
|
||||
Assert.assertEquals(Status.REQUEST_PARAMS_NOT_VALID_ERROR, result.get(Constants.STATUS));
|
||||
|
||||
email = "122222@qq.com";
|
||||
phone ="2233";
|
||||
phone = "2233";
|
||||
//phone error
|
||||
result = usersService.createUser(user, userName, userPassword, email, tenantId, phone, queueName, state);
|
||||
logger.info(result.toString());
|
||||
@ -137,20 +151,19 @@ public class UsersServiceTest {
|
||||
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error(Status.CREATE_USER_ERROR.getMsg(),e);
|
||||
logger.error(Status.CREATE_USER_ERROR.getMsg(), e);
|
||||
Assert.assertTrue(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryUser(){
|
||||
|
||||
public void testQueryUser() {
|
||||
String userName = "userTest0001";
|
||||
String userPassword = "userTest0001";
|
||||
when(userMapper.queryUserByNamePassword(userName,EncryptionUtils.getMd5(userPassword))).thenReturn(getGeneralUser());
|
||||
User queryUser = usersService.queryUser(userName, userPassword);
|
||||
when(userMapper.queryUserByNamePassword(userName, EncryptionUtils.getMd5(userPassword))).thenReturn(getGeneralUser());
|
||||
User queryUser = usersService.queryUser(userName, userPassword);
|
||||
logger.info(queryUser.toString());
|
||||
Assert.assertTrue(queryUser!=null);
|
||||
Assert.assertTrue(queryUser != null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -176,11 +189,8 @@ public class UsersServiceTest {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testQueryUserList(){
|
||||
|
||||
|
||||
public void testQueryUserList() {
|
||||
User user = new User();
|
||||
|
||||
//no operate
|
||||
@ -190,37 +200,34 @@ public class UsersServiceTest {
|
||||
|
||||
//success
|
||||
user.setUserType(UserType.ADMIN_USER);
|
||||
when(userMapper.selectList(null )).thenReturn(getUserList());
|
||||
when(userMapper.selectList(null)).thenReturn(getUserList());
|
||||
result = usersService.queryUserList(user);
|
||||
List<User> userList = (List<User>) result.get(Constants.DATA_LIST);
|
||||
Assert.assertTrue(userList.size()>0);
|
||||
Assert.assertTrue(userList.size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryUserListPage(){
|
||||
|
||||
|
||||
public void testQueryUserListPage() {
|
||||
User user = new User();
|
||||
IPage<User> page = new Page<>(1,10);
|
||||
IPage<User> page = new Page<>(1, 10);
|
||||
page.setRecords(getUserList());
|
||||
when(userMapper.queryUserPaging(any(Page.class), eq("userTest"))).thenReturn(page);
|
||||
|
||||
//no operate
|
||||
Map<String, Object> result = usersService.queryUserList(user,"userTest",1,10);
|
||||
Map<String, Object> result = usersService.queryUserList(user, "userTest", 1, 10);
|
||||
logger.info(result.toString());
|
||||
Assert.assertEquals(Status.USER_NO_OPERATION_PERM, result.get(Constants.STATUS));
|
||||
|
||||
//success
|
||||
user.setUserType(UserType.ADMIN_USER);
|
||||
result = usersService.queryUserList(user,"userTest",1,10);
|
||||
result = usersService.queryUserList(user, "userTest", 1, 10);
|
||||
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
|
||||
PageInfo<User> pageInfo = (PageInfo<User>) result.get(Constants.DATA_LIST);
|
||||
Assert.assertTrue(pageInfo.getLists().size()>0);
|
||||
PageInfo<User> pageInfo = (PageInfo<User>) result.get(Constants.DATA_LIST);
|
||||
Assert.assertTrue(pageInfo.getLists().size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateUser(){
|
||||
|
||||
public void testUpdateUser() {
|
||||
String userName = "userTest0001";
|
||||
String userPassword = "userTest0001";
|
||||
try {
|
||||
@ -235,48 +242,46 @@ public class UsersServiceTest {
|
||||
logger.info(result.toString());
|
||||
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
|
||||
} catch (Exception e) {
|
||||
logger.error("update user error",e);
|
||||
logger.error("update user error", e);
|
||||
Assert.assertTrue(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteUserById(){
|
||||
|
||||
public void testDeleteUserById() {
|
||||
User loginUser = new User();
|
||||
try {
|
||||
when(userMapper.queryTenantCodeByUserId(1)).thenReturn(getUser());
|
||||
when(userMapper.selectById(1)).thenReturn(getUser());
|
||||
|
||||
//no operate
|
||||
Map<String, Object> result = usersService.deleteUserById(loginUser,3);
|
||||
Map<String, Object> result = usersService.deleteUserById(loginUser, 3);
|
||||
logger.info(result.toString());
|
||||
Assert.assertEquals(Status.USER_NO_OPERATION_PERM, result.get(Constants.STATUS));
|
||||
|
||||
// user not exist
|
||||
loginUser.setUserType(UserType.ADMIN_USER);
|
||||
result = usersService.deleteUserById(loginUser,3);
|
||||
result = usersService.deleteUserById(loginUser, 3);
|
||||
logger.info(result.toString());
|
||||
Assert.assertEquals(Status.USER_NOT_EXIST, result.get(Constants.STATUS));
|
||||
|
||||
//success
|
||||
result = usersService.deleteUserById(loginUser,1);
|
||||
result = usersService.deleteUserById(loginUser, 1);
|
||||
logger.info(result.toString());
|
||||
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
|
||||
} catch (Exception e) {
|
||||
logger.error("delete user error",e);
|
||||
Assert.assertTrue(false);
|
||||
logger.error("delete user error", e);
|
||||
Assert.assertTrue(false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantProject(){
|
||||
|
||||
public void testGrantProject() {
|
||||
when(userMapper.selectById(1)).thenReturn(getUser());
|
||||
User loginUser = new User();
|
||||
String projectIds= "100000,120000";
|
||||
String projectIds = "100000,120000";
|
||||
Map<String, Object> result = usersService.grantProject(loginUser, 1, projectIds);
|
||||
logger.info(result.toString());
|
||||
Assert.assertEquals(Status.USER_NO_OPERATION_PERM, result.get(Constants.STATUS));
|
||||
@ -292,8 +297,7 @@ public class UsersServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantResources(){
|
||||
|
||||
public void testGrantResources() {
|
||||
String resourceIds = "100000,120000";
|
||||
when(userMapper.selectById(1)).thenReturn(getUser());
|
||||
User loginUser = new User();
|
||||
@ -317,8 +321,7 @@ public class UsersServiceTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testGrantUDFFunction(){
|
||||
|
||||
public void testGrantUDFFunction() {
|
||||
String udfIds = "100000,120000";
|
||||
when(userMapper.selectById(1)).thenReturn(getUser());
|
||||
User loginUser = new User();
|
||||
@ -337,8 +340,7 @@ public class UsersServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGrantDataSource(){
|
||||
|
||||
public void testGrantDataSource() {
|
||||
String datasourceIds = "100000,120000";
|
||||
when(userMapper.selectById(1)).thenReturn(getUser());
|
||||
User loginUser = new User();
|
||||
@ -365,8 +367,7 @@ public class UsersServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUserInfo(){
|
||||
|
||||
public void getUserInfo() {
|
||||
User loginUser = new User();
|
||||
loginUser.setUserName("admin");
|
||||
loginUser.setUserType(UserType.ADMIN_USER);
|
||||
@ -376,7 +377,7 @@ public class UsersServiceTest {
|
||||
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
|
||||
User tempUser = (User) result.get(Constants.DATA_LIST);
|
||||
//check userName
|
||||
Assert.assertEquals("admin",tempUser.getUserName());
|
||||
Assert.assertEquals("admin", tempUser.getUserName());
|
||||
|
||||
//get general user
|
||||
loginUser.setUserType(null);
|
||||
@ -387,13 +388,12 @@ public class UsersServiceTest {
|
||||
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
|
||||
tempUser = (User) result.get(Constants.DATA_LIST);
|
||||
//check userName
|
||||
Assert.assertEquals("userTest0001",tempUser.getUserName());
|
||||
Assert.assertEquals("userTest0001", tempUser.getUserName());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testQueryAllGeneralUsers(){
|
||||
|
||||
public void testQueryAllGeneralUsers() {
|
||||
User loginUser = new User();
|
||||
//no operate
|
||||
Map<String, Object> result = usersService.queryAllGeneralUsers(loginUser);
|
||||
@ -410,8 +410,7 @@ public class UsersServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerifyUserName(){
|
||||
|
||||
public void testVerifyUserName() {
|
||||
//not exist user
|
||||
Result result = usersService.verifyUserName("admin89899");
|
||||
logger.info(result.toString());
|
||||
@ -424,11 +423,10 @@ public class UsersServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnauthorizedUser(){
|
||||
|
||||
public void testUnauthorizedUser() {
|
||||
User loginUser = new User();
|
||||
when(userMapper.selectList(null )).thenReturn(getUserList());
|
||||
when( userMapper.queryUserListByAlertGroupId(2)).thenReturn(getUserList());
|
||||
when(userMapper.selectList(null)).thenReturn(getUserList());
|
||||
when(userMapper.queryUserListByAlertGroupId(2)).thenReturn(getUserList());
|
||||
//no operate
|
||||
Map<String, Object> result = usersService.unauthorizedUser(loginUser, 2);
|
||||
logger.info(result.toString());
|
||||
@ -442,8 +440,7 @@ public class UsersServiceTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void testAuthorizedUser(){
|
||||
|
||||
public void testAuthorizedUser() {
|
||||
User loginUser = new User();
|
||||
when(userMapper.queryUserListByAlertGroupId(2)).thenReturn(getUserList());
|
||||
//no operate
|
||||
@ -571,10 +568,8 @@ public class UsersServiceTest {
|
||||
|
||||
/**
|
||||
* get disabled user
|
||||
* @return
|
||||
*/
|
||||
private User getDisabledUser() {
|
||||
|
||||
User user = new User();
|
||||
user.setUserType(UserType.GENERAL_USER);
|
||||
user.setUserName("userTest0001");
|
||||
@ -586,10 +581,8 @@ public class UsersServiceTest {
|
||||
|
||||
/**
|
||||
* get user
|
||||
* @return
|
||||
*/
|
||||
private User getGeneralUser(){
|
||||
|
||||
private User getGeneralUser() {
|
||||
User user = new User();
|
||||
user.setUserType(UserType.GENERAL_USER);
|
||||
user.setUserName("userTest0001");
|
||||
@ -597,8 +590,7 @@ public class UsersServiceTest {
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
private List<User> getUserList(){
|
||||
private List<User> getUserList() {
|
||||
List<User> userList = new ArrayList<>();
|
||||
userList.add(getGeneralUser());
|
||||
return userList;
|
||||
@ -607,8 +599,7 @@ public class UsersServiceTest {
|
||||
/**
|
||||
* get user
|
||||
*/
|
||||
private User getUser(){
|
||||
|
||||
private User getUser() {
|
||||
User user = new User();
|
||||
user.setUserType(UserType.ADMIN_USER);
|
||||
user.setUserName("userTest0001");
|
||||
@ -619,9 +610,10 @@ public class UsersServiceTest {
|
||||
|
||||
/**
|
||||
* get tenant
|
||||
*
|
||||
* @return tenant
|
||||
*/
|
||||
private Tenant getTenant(){
|
||||
private Tenant getTenant() {
|
||||
Tenant tenant = new Tenant();
|
||||
tenant.setId(1);
|
||||
return tenant;
|
||||
@ -629,10 +621,10 @@ public class UsersServiceTest {
|
||||
|
||||
/**
|
||||
* get resource
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
private Resource getResource(){
|
||||
|
||||
private Resource getResource() {
|
||||
Resource resource = new Resource();
|
||||
resource.setPid(-1);
|
||||
resource.setUserId(1);
|
||||
|
@ -19,7 +19,7 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="org.apache.dolphinscheduler.dao.mapper.AccessTokenMapper">
|
||||
<select id="selectAccessTokenPage" resultType="org.apache.dolphinscheduler.dao.entity.AccessToken">
|
||||
select t.id, t.user_id, t.token, t.expire_time, t.create_time, t.update_time
|
||||
select t.id, t.user_id, t.token, t.expire_time, t.create_time, t.update_time, u.user_name
|
||||
from t_ds_access_token t
|
||||
left join t_ds_user u on t.user_id = u.id
|
||||
where 1 = 1
|
||||
|
@ -18,82 +18,97 @@
|
||||
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="org.apache.dolphinscheduler.dao.mapper.UdfFuncMapper">
|
||||
|
||||
<sql id="baseSql">
|
||||
${alias}.id, ${alias}.user_id, ${alias}.func_name, ${alias}.class_name, ${alias}.type, ${alias}.arg_types,
|
||||
${alias}.database, ${alias}.description, ${alias}.resource_id, ${alias}.resource_name, ${alias}.create_time, ${alias}.update_time
|
||||
</sql>
|
||||
|
||||
<select id="selectUdfById" resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
|
||||
select
|
||||
id, user_id, func_name, class_name, type, arg_types,
|
||||
database, description, resource_id, resource_name, create_time, update_time
|
||||
from t_ds_udfs
|
||||
<include refid="baseSql">
|
||||
<property name="alias" value="udf"/>
|
||||
</include>
|
||||
from t_ds_udfs udf
|
||||
where id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="queryUdfByIdStr" resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
|
||||
select
|
||||
id, user_id, func_name, class_name, type, arg_types,
|
||||
database, description, resource_id, resource_name, create_time, update_time
|
||||
from t_ds_udfs
|
||||
<include refid="baseSql">
|
||||
<property name="alias" value="udf"/>
|
||||
</include>
|
||||
from t_ds_udfs udf
|
||||
where 1 = 1
|
||||
<if test="ids != null and ids != ''">
|
||||
and id in
|
||||
and udf.id in
|
||||
<foreach collection="ids" item="i" open="(" close=")" separator=",">
|
||||
#{i}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="funcNames != null and funcNames != ''">
|
||||
and func_name = #{funcNames}
|
||||
and udf.func_name = #{funcNames}
|
||||
</if>
|
||||
order by id asc
|
||||
order by udf.id asc
|
||||
</select>
|
||||
<select id="queryUdfFuncPaging" resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
|
||||
select id, user_id, func_name, class_name, type, arg_types, database, description, resource_id, resource_name, create_time, update_time
|
||||
from t_ds_udfs
|
||||
select
|
||||
<include refid="baseSql">
|
||||
<property name="alias" value="udf"/>
|
||||
</include>
|
||||
from t_ds_udfs udf
|
||||
where 1=1
|
||||
<if test="searchVal!= null and searchVal != ''">
|
||||
and func_name like concat('%', #{searchVal}, '%')
|
||||
and udf.func_name like concat('%', #{searchVal}, '%')
|
||||
</if>
|
||||
<if test="userId != 0">
|
||||
and id in (
|
||||
and udf.id in (
|
||||
select udf_id from t_ds_relation_udfs_user where user_id=#{userId}
|
||||
union select id as udf_id from t_ds_udfs where user_id=#{userId})
|
||||
</if>
|
||||
order by create_time desc
|
||||
order by udf.create_time desc
|
||||
</select>
|
||||
<select id="getUdfFuncByType" resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
|
||||
select
|
||||
id, user_id, func_name, class_name, type, arg_types,
|
||||
database, description, resource_id, resource_name, create_time, update_time
|
||||
from t_ds_udfs
|
||||
where type=#{type}
|
||||
<include refid="baseSql">
|
||||
<property name="alias" value="udf"/>
|
||||
</include>
|
||||
from t_ds_udfs udf
|
||||
where udf.type=#{type}
|
||||
<if test="userId != 0">
|
||||
and id in (
|
||||
and udf.id in (
|
||||
select udf_id from t_ds_relation_udfs_user where user_id=#{userId}
|
||||
union select id as udf_id from t_ds_udfs where user_id=#{userId})
|
||||
</if>
|
||||
</select>
|
||||
<select id="queryUdfFuncExceptUserId" resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
|
||||
select
|
||||
id, user_id, func_name, class_name, type, arg_types,
|
||||
database, description, resource_id, resource_name, create_time, update_time
|
||||
from t_ds_udfs
|
||||
where user_id <![CDATA[ <> ]]> #{userId}
|
||||
<include refid="baseSql">
|
||||
<property name="alias" value="udf"/>
|
||||
</include>
|
||||
from t_ds_udfs udf
|
||||
where udf.user_id <![CDATA[ <> ]]> #{userId}
|
||||
</select>
|
||||
<select id="queryAuthedUdfFunc" resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
|
||||
SELECT
|
||||
u.id, u.user_id, u.func_name, u.class_name, u.type, u.arg_types,
|
||||
u.database, u.description, u.resource_id, u.resource_name, u.create_time, u.update_time
|
||||
from t_ds_udfs u,t_ds_relation_udfs_user rel
|
||||
WHERE u.id = rel.udf_id
|
||||
<include refid="baseSql">
|
||||
<property name="alias" value="udf"/>
|
||||
</include>
|
||||
from t_ds_udfs udf,t_ds_relation_udfs_user rel
|
||||
WHERE udf.id = rel.udf_id
|
||||
AND rel.user_id = #{userId}
|
||||
</select>
|
||||
<select id="listAuthorizedUdfFunc" resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
|
||||
select
|
||||
u.id, u.user_id, u.func_name, u.class_name, u.type, u.arg_types,
|
||||
u.database, u.description, u.resource_id, u.resource_name, u.create_time, u.update_time
|
||||
from t_ds_udfs u
|
||||
<include refid="baseSql">
|
||||
<property name="alias" value="udf"/>
|
||||
</include>
|
||||
from t_ds_udfs udf
|
||||
where
|
||||
id in (select udf_id from t_ds_relation_udfs_user where user_id=#{userId}
|
||||
udf.id in (select udf_id from t_ds_relation_udfs_user where user_id=#{userId}
|
||||
union select id as udf_id from t_ds_udfs where user_id=#{userId})
|
||||
<if test="udfIds != null and udfIds != ''">
|
||||
and id in
|
||||
and udf.id in
|
||||
<foreach collection="udfIds" item="i" open="(" close=")" separator=",">
|
||||
#{i}
|
||||
</foreach>
|
||||
@ -101,12 +116,13 @@
|
||||
</select>
|
||||
<select id="listUdfByResourceId" resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
|
||||
select
|
||||
u.id, u.user_id, u.func_name, u.class_name, u.type, u.arg_types,
|
||||
u.database, u.description, u.resource_id, u.resource_name, u.create_time, u.update_time
|
||||
from t_ds_udfs u
|
||||
<include refid="baseSql">
|
||||
<property name="alias" value="udf"/>
|
||||
</include>
|
||||
from t_ds_udfs udf
|
||||
where 1=1
|
||||
<if test="resourceIds != null and resourceIds != ''">
|
||||
and resource_id in
|
||||
and udf.resource_id in
|
||||
<foreach collection="resourceIds" item="i" open="(" close=")" separator=",">
|
||||
#{i}
|
||||
</foreach>
|
||||
@ -114,14 +130,15 @@
|
||||
</select>
|
||||
<select id="listAuthorizedUdfByResourceId" resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
|
||||
select
|
||||
u.id, u.user_id, u.func_name, u.class_name, u.type, u.arg_types,
|
||||
u.database, u.description, u.resource_id, u.resource_name, u.create_time, u.update_time
|
||||
from t_ds_udfs u
|
||||
<include refid="baseSql">
|
||||
<property name="alias" value="udf"/>
|
||||
</include>
|
||||
from t_ds_udfs udf
|
||||
where
|
||||
id in (select udf_id from t_ds_relation_udfs_user where user_id=#{userId}
|
||||
udf.id in (select udf_id from t_ds_relation_udfs_user where user_id=#{userId}
|
||||
union select id as udf_id from t_ds_udfs where user_id=#{userId})
|
||||
<if test="resourceIds != null and resourceIds != ''">
|
||||
and resource_id in
|
||||
and udf.resource_id in
|
||||
<foreach collection="resourceIds" item="i" open="(" close=")" separator=",">
|
||||
#{i}
|
||||
</foreach>
|
||||
|
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.apache.dolphinscheduler.server.utils;
|
||||
|
||||
public class ArgsUtils {
|
||||
|
||||
private ArgsUtils() throws IllegalStateException {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static String escape(String arg) {
|
||||
return arg.replace(" ", "\\ ").replace("\"", "\\\"").replace("'", "\\'");
|
||||
}
|
||||
|
||||
}
|
@ -14,8 +14,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dolphinscheduler.server.utils;
|
||||
|
||||
package org.apache.dolphinscheduler.server.utils;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.dolphinscheduler.common.Constants;
|
||||
@ -26,7 +26,6 @@ import org.apache.dolphinscheduler.common.task.flink.FlinkParameters;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* flink args utils
|
||||
*/
|
||||
@ -62,7 +61,7 @@ public class FlinkArgsUtils {
|
||||
String appName = param.getAppName();
|
||||
if (StringUtils.isNotEmpty(appName)) { //-ynm
|
||||
args.add(Constants.FLINK_APP_NAME);
|
||||
args.add(appName);
|
||||
args.add(ArgsUtils.escape(appName));
|
||||
}
|
||||
|
||||
// judge flink version,from flink1.10,the parameter -yn removed
|
||||
|
@ -25,8 +25,6 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.transaction.NotSupportedException;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.qos.logback.classic.sift.SiftingAppender;
|
||||
@ -35,8 +33,8 @@ import ch.qos.logback.core.spi.AppenderAttachable;
|
||||
|
||||
public class LogUtils {
|
||||
|
||||
private LogUtils() throws NotSupportedException {
|
||||
throw new NotSupportedException();
|
||||
private LogUtils() throws IllegalStateException {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,9 +30,6 @@ import org.apache.dolphinscheduler.remote.utils.Host;
|
||||
import org.apache.dolphinscheduler.server.entity.TaskExecutionContext;
|
||||
import org.apache.dolphinscheduler.service.log.LogClientService;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
@ -40,21 +37,28 @@ import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* mainly used to get the start command line of a process.
|
||||
*/
|
||||
public class ProcessUtils {
|
||||
|
||||
/**
|
||||
* logger.
|
||||
* logger
|
||||
*/
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProcessUtils.class);
|
||||
|
||||
/**
|
||||
* Initialization regularization, solve the problem of pre-compilation performance,
|
||||
* avoid the thread safety problem of multi-thread operation.
|
||||
* avoid the thread safety problem of multi-thread operation
|
||||
*/
|
||||
private static final Pattern MACPATTERN = Pattern.compile("-[+|-]-\\s(\\d+)");
|
||||
|
||||
/**
|
||||
* Expression of PID recognition in Windows scene
|
||||
*/
|
||||
private static final Pattern WINDOWSATTERN = Pattern.compile("(\\d+)");
|
||||
|
||||
private static final String LOCAL_PROCESS_EXEC = "jdk.lang.Process.allowAmbiguousCommands";
|
||||
@ -79,7 +83,7 @@ public class ProcessUtils {
|
||||
}
|
||||
|
||||
cmdstr = createCommandLine(
|
||||
VERIFICATION_LEGACY, executablePath, cmd);
|
||||
VERIFICATION_LEGACY, executablePath, cmd);
|
||||
} else {
|
||||
String executablePath;
|
||||
try {
|
||||
@ -102,7 +106,7 @@ public class ProcessUtils {
|
||||
|
||||
cmdstr = createCommandLine(
|
||||
|
||||
isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
|
||||
isShellFile(executablePath) ? VERIFICATION_CMD_BAT : VERIFICATION_WIN32, quoteString(executablePath), cmd);
|
||||
}
|
||||
return cmdstr;
|
||||
}
|
||||
@ -211,8 +215,8 @@ public class ProcessUtils {
|
||||
* create command line.
|
||||
*
|
||||
* @param verificationType verification type
|
||||
* @param executablePath executable path
|
||||
* @param cmd cmd
|
||||
* @param executablePath executable path
|
||||
* @param cmd cmd
|
||||
* @return command line
|
||||
*/
|
||||
private static String createCommandLine(int verificationType, final String executablePath, final String[] cmd) {
|
||||
@ -241,8 +245,8 @@ public class ProcessUtils {
|
||||
* whether is quoted.
|
||||
*
|
||||
* @param noQuotesInside no quotes inside
|
||||
* @param arg arg
|
||||
* @param errorMessage error message
|
||||
* @param arg arg
|
||||
* @param errorMessage error message
|
||||
* @return boolean
|
||||
*/
|
||||
private static boolean isQuoted(boolean noQuotesInside, String arg, String errorMessage) {
|
||||
@ -266,7 +270,7 @@ public class ProcessUtils {
|
||||
* whether needs escaping.
|
||||
*
|
||||
* @param verificationType verification type
|
||||
* @param arg arg
|
||||
* @param arg arg
|
||||
* @return boolean
|
||||
*/
|
||||
private static boolean needsEscaping(int verificationType, String arg) {
|
||||
@ -287,9 +291,9 @@ public class ProcessUtils {
|
||||
/**
|
||||
* kill yarn application.
|
||||
*
|
||||
* @param appIds app id list
|
||||
* @param logger logger
|
||||
* @param tenantCode tenant code
|
||||
* @param appIds app id list
|
||||
* @param logger logger
|
||||
* @param tenantCode tenant code
|
||||
* @param executePath execute path
|
||||
*/
|
||||
public static void cancelApplication(List<String> appIds, Logger logger, String tenantCode, String executePath) {
|
||||
@ -301,7 +305,7 @@ public class ProcessUtils {
|
||||
|
||||
if (!applicationStatus.typeIsFinished()) {
|
||||
String commandFile = String
|
||||
.format("%s/%s.kill", executePath, appId);
|
||||
.format("%s/%s.kill", executePath, appId);
|
||||
String cmd = "yarn application -kill " + appId;
|
||||
execYarnKillCommand(logger, tenantCode, appId, commandFile, cmd);
|
||||
}
|
||||
@ -315,11 +319,11 @@ public class ProcessUtils {
|
||||
/**
|
||||
* build kill command for yarn application
|
||||
*
|
||||
* @param logger logger
|
||||
* @param tenantCode tenant code
|
||||
* @param appId app id
|
||||
* @param logger logger
|
||||
* @param tenantCode tenant code
|
||||
* @param appId app id
|
||||
* @param commandFile command file
|
||||
* @param cmd cmd
|
||||
* @param cmd cmd
|
||||
*/
|
||||
private static void execYarnKillCommand(Logger logger, String tenantCode, String appId, String commandFile, String cmd) {
|
||||
try {
|
||||
@ -361,7 +365,7 @@ public class ProcessUtils {
|
||||
int processId = taskExecutionContext.getProcessId();
|
||||
if (processId == 0) {
|
||||
logger.error("process kill failed, process id :{}, task id:{}",
|
||||
processId, taskExecutionContext.getTaskInstanceId());
|
||||
processId, taskExecutionContext.getTaskInstanceId());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -422,8 +426,8 @@ public class ProcessUtils {
|
||||
try {
|
||||
logClient = new LogClientService();
|
||||
log = logClient.viewLog(Host.of(taskExecutionContext.getHost()).getIp(),
|
||||
Constants.RPC_PORT,
|
||||
taskExecutionContext.getLogPath());
|
||||
Constants.RPC_PORT,
|
||||
taskExecutionContext.getLogPath());
|
||||
} finally {
|
||||
if (logClient != null) {
|
||||
logClient.close();
|
||||
|
@ -89,7 +89,7 @@
|
||||
type="input"
|
||||
size="small"
|
||||
v-model="appName"
|
||||
:placeholder="$t('Please enter the job name of Flink')"
|
||||
:placeholder="$t('Please enter the job name of Flink(optional)')"
|
||||
style="width: 200px;">
|
||||
</el-input>
|
||||
</span>
|
||||
@ -303,11 +303,6 @@
|
||||
return false
|
||||
}
|
||||
|
||||
if (!this.appName) {
|
||||
this.$message.warning(`${i18n.$t('Please enter the job name of Flink')}`)
|
||||
return false
|
||||
}
|
||||
|
||||
if (!this.jobManagerMemory) {
|
||||
this.$message.warning(`${i18n.$t('Please enter jobManager memory')}`)
|
||||
return false
|
||||
@ -353,9 +348,9 @@
|
||||
flinkVersion: this.flinkVersion,
|
||||
slot: this.slot,
|
||||
taskManager: this.taskManager,
|
||||
appName: this.appName,
|
||||
jobManagerMemory: this.jobManagerMemory,
|
||||
taskManagerMemory: this.taskManagerMemory,
|
||||
appName: this.appName,
|
||||
mainArgs: this.mainArgs,
|
||||
others: this.others,
|
||||
programType: this.programType
|
||||
@ -489,9 +484,9 @@
|
||||
localParams: this.localParams,
|
||||
slot: this.slot,
|
||||
taskManager: this.taskManager,
|
||||
appName: this.appName,
|
||||
jobManagerMemory: this.jobManagerMemory,
|
||||
taskManagerMemory: this.taskManagerMemory,
|
||||
appName: this.appName,
|
||||
mainArgs: this.mainArgs,
|
||||
others: this.others,
|
||||
programType: this.programType
|
||||
@ -522,7 +517,7 @@
|
||||
this.taskManager = o.params.taskManager || '2'
|
||||
this.jobManagerMemory = o.params.jobManagerMemory || '1G'
|
||||
this.taskManagerMemory = o.params.taskManagerMemory || '2G'
|
||||
|
||||
this.appName = o.params.appName || ''
|
||||
this.mainArgs = o.params.mainArgs || ''
|
||||
this.others = o.params.others
|
||||
this.programType = o.params.programType || 'SCALA'
|
||||
|
@ -108,7 +108,7 @@ export default {
|
||||
'Driver memory use': 'Driver memory use',
|
||||
'Please enter driver memory use': 'Please enter driver memory use',
|
||||
'Number of Executors': 'Number of Executors',
|
||||
'Please enter the job name of Flink': 'Please enter the job name of Flink',
|
||||
'Please enter the job name of Flink(optional)': 'Please enter the job name of Flink(optional)',
|
||||
'Please enter the number of Executor': 'Please enter the number of Executor',
|
||||
'Executor memory': 'Executor memory',
|
||||
'Please enter the Executor memory': 'Please enter the Executor memory',
|
||||
|
@ -106,7 +106,7 @@ export default {
|
||||
'Driver memory use': 'Driver内存数',
|
||||
'Please enter driver memory use': '请输入Driver内存数',
|
||||
'Number of Executors': 'Executor数量',
|
||||
'Please enter the job name of Flink': '请输入Flink任务名称',
|
||||
'Please enter the job name of Flink(optional)': '请输入Flink任务名称(选填)',
|
||||
'Please enter the number of Executor': '请输入Executor数量',
|
||||
'Executor memory': 'Executor内存数',
|
||||
'Please enter the Executor memory': '请输入Executor内存数',
|
||||
|
6
pom.xml
6
pom.xml
@ -725,8 +725,10 @@
|
||||
<include>**/api/exceptions/ApiExceptionHandlerTest.java</include>
|
||||
<include>**/api/exceptions/ServiceExceptionTest.java</include>
|
||||
<include>**/api/interceptor/LoginHandlerInterceptorTest.java</include>
|
||||
<include>**/api/security/PasswordAuthenticatorTest.java</include>
|
||||
<include>**/api/security/SecurityConfigTest.java</include>
|
||||
<include>**/api/security/impl/pwd/PasswordAuthenticatorTest.java</include>
|
||||
<include>**/api/security/impl/ldap/LdapAuthenticatorTest.java</include>
|
||||
<include>**/api/security/SecurityConfigLDAPTest.java</include>
|
||||
<include>**/api/security/SecurityConfigPasswordTest.java</include>
|
||||
<include>**/api/service/AccessTokenServiceTest.java</include>
|
||||
<include>**/api/service/AlertGroupServiceTest.java</include>
|
||||
<include>**/api/service/BaseDAGServiceTest.java</include>
|
||||
|
Loading…
Reference in New Issue
Block a user