This is an automated email from the ASF dual-hosted git repository.
journey pushed a commit to branch dev-1.2.1
in repository https://gitbox.apache.org/repos/asf/incubator-dolphinscheduler.git
The following commit(s) were added to refs/heads/dev-1.2.1 by this push:
new d75485a [Fix #1828]check whether has permission to download udf file
or delete udf function (#1858)
d75485a is described below
commit d75485a1672af2e3b0f00c3466f094295a52354e
Author: lgcareer <[email protected]>
AuthorDate: Sun Jan 19 12:00:58 2020 +0800
[Fix #1828]check whether has permission to download udf file or delete udf
function (#1858)
* fix issue 1828:get the udf resource path error when create udf function
* update grantResources
* first verify whether udf resource is bound by udf function
* update grantResources
* update testListAuthorizedUdfFunc
* update getUserInfo in order to run success
* check whether has permission to download udf file or delete udf file
* update listAuthorizedResourceById in ResourceMapper.xml
---
.../api/controller/ResourcesController.java | 2 +-
.../api/service/UdfFuncService.java | 17 +++++++--
.../dolphinscheduler/api/service/UsersService.java | 29 ++++++++++------
.../api/service/UsersServiceTest.java | 8 +++--
.../common/enums/AuthorizationType.java | 6 ++--
.../apache/dolphinscheduler/dao/ProcessDao.java | 4 +++
.../dao/mapper/ResourceMapper.java | 8 +++++
.../dolphinscheduler/dao/mapper/UdfFuncMapper.java | 7 ++++
.../dolphinscheduler/dao/mapper/ResourceMapper.xml | 12 +++++++
.../dolphinscheduler/dao/mapper/UdfFuncMapper.xml | 13 +++++++
.../dao/mapper/UdfFuncMapperTest.java | 3 ++
.../server/worker/task/sql/SqlTask.java | 40 +++++++++++++++-------
12 files changed, 117 insertions(+), 32 deletions(-)
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java
index 7bac661..43a44bb 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/ResourcesController.java
@@ -620,7 +620,7 @@ public class ResourcesController extends BaseController{
try{
logger.info("login user {}, delete udf function id: {}",
loginUser.getUserName(),udfFuncId);
- return udfFuncService.delete(udfFuncId);
+ return udfFuncService.delete(loginUser,udfFuncId);
}catch (Exception e){
logger.error(DELETE_UDF_FUNCTION_ERROR.getMsg(),e);
return error(Status.DELETE_UDF_FUNCTION_ERROR.getCode(),
Status.DELETE_UDF_FUNCTION_ERROR.getMsg());
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UdfFuncService.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UdfFuncService.java
index adff29d..37717bb 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UdfFuncService.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UdfFuncService.java
@@ -301,13 +301,24 @@ public class UdfFuncService extends BaseService{
/**
* delete udf function
*
- * @param id udf function id
+ * @param id udf function id
+ * @param loginUser login user
* @return delete result code
*/
@Transactional(rollbackFor = Exception.class)
- public Result delete(int id) {
+ public Result delete(User loginUser,int id) {
Result result = new Result();
-
+
+ UdfFunc udfFunc = udfFuncMapper.selectUdfById(id);
+ if(udfFunc == null){
+ putMsg(result,Status.UDF_FUNCTION_NOT_EXIST);
+ return result;
+ }
+
+ if (!hasPerm(loginUser,udfFunc.getUserId())){
+ putMsg(result,Status.USER_NO_OPERATION_PERM);
+ return result;
+ }
udfFuncMapper.deleteById(id);
udfUserMapper.deleteByUdfFuncId(id);
putMsg(result, Status.SUCCESS);
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
index dd04700..e9f6e0a 100644
---
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/UsersService.java
@@ -438,21 +438,30 @@ public class UsersService extends BaseService {
return result;
}
String[] resourcesIdArr = resourceIds.split(",");
- //if resource type is UDF,need check whether it is bound by UDF functon
Set<Integer> needAuthorizedIds = new HashSet<>();
if (StringUtils.isNotEmpty(resourceIds)) {
needAuthorizedIds =
Arrays.stream(resourcesIdArr).map(t->Integer.parseInt(t)).collect(Collectors.toSet());
}
- List<Resource> udfResourceList = resourceMapper.queryResourceList("",
0, ResourceType.UDF.ordinal());
- Set<Integer> allUdfResIds = udfResourceList.stream().map(t ->
t.getId()).collect(Collectors.toSet());
- allUdfResIds.removeAll(needAuthorizedIds);
- List<UdfFunc> udfFuncs =
udfFuncMapper.listUdfByResourceId(ArrayUtils.toPrimitive(allUdfResIds.toArray(new
Integer[allUdfResIds.size()])));
- if (CollectionUtils.isNotEmpty(udfFuncs)) {
- logger.error("can't be deleted,because it is bound by UDF
functions:{}",udfFuncs.toString());
- putMsg(result, Status.UDF_RESOURCE_IS_BOUND,
udfFuncs.get(0).getFuncName());
- return result;
- }
+ //if resource type is UDF,need check whether it is bound by UDF functon
+
+ //get the authorized resource id list by user id and resource type
+ List<Resource> oldAuthorizedUdfRes =
resourceMapper.queryResourceListAuthored(userId, ResourceType.UDF.ordinal());
+ Set<Integer> oldAuthorizedUdfResIds =
oldAuthorizedUdfRes.stream().map(t -> t.getId()).collect(Collectors.toSet());
+
+ //get the unauthorized resource id list
+ oldAuthorizedUdfResIds.removeAll(needAuthorizedIds);
+
+ if (CollectionUtils.isNotEmpty(oldAuthorizedUdfResIds)) {
+ int[] unauthorizedResIds =
ArrayUtils.toPrimitive(oldAuthorizedUdfResIds.toArray(new
Integer[oldAuthorizedUdfResIds.size()]));
+ List<UdfFunc> authorizedUdfFuncs =
udfFuncMapper.listAuthorizedUdfByResourceId(userId, unauthorizedResIds);
+
+ if (CollectionUtils.isNotEmpty(authorizedUdfFuncs)) {
+ logger.error("can't be deleted,because it is bound by UDF
functions:{}",authorizedUdfFuncs.toString());
+ putMsg(result, Status.UDF_RESOURCE_IS_BOUND,
authorizedUdfFuncs.get(0).getFuncName());
+ return result;
+ }
+ }
resourcesUserMapper.deleteResourceUser(userId, 0);
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
index fd51f91..991daef 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/UsersServiceTest.java
@@ -297,18 +297,19 @@ public class UsersServiceTest {
logger.info(result.toString());
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
- List<Resource> udfResourceList = new ArrayList<Resource>() {{
+ //the udf resources needAuthorizedUser has the permission to use
+ List<Resource> oldAuthorizedUdfRes = new ArrayList<Resource>() {{
add(createResource(getAdminUser(), ResourceType.UDF, 100000));
add(createResource(getAdminUser(), ResourceType.UDF, 120000));
}};
- when(resourceMapper.queryResourceList("", 0,
ResourceType.UDF.ordinal())).thenReturn(udfResourceList);
+
when(resourceMapper.queryResourceListAuthored(needAuthorizedUser.getId(),
ResourceType.UDF.ordinal())).thenReturn(oldAuthorizedUdfRes);
//mock udf function list
UdfFunc udfFunc = createUdfFunc(getAdminUser(), 100000);
List<UdfFunc> udfFuncs = new ArrayList<>();
udfFuncs.add(udfFunc);
- when(udfFuncMapper.listUdfByResourceId(new
int[]{100000})).thenReturn(udfFuncs);
+
when(udfFuncMapper.listAuthorizedUdfByResourceId(needAuthorizedUser.getId(),new
int[]{100000})).thenReturn(udfFuncs);
//fail if udf resource is already bound by the udf function
result = usersService.grantResources(adminUser,
needAuthorizedUser.getId(), "120000");
@@ -316,6 +317,7 @@ public class UsersServiceTest {
result = usersService.grantResources(adminUser,
needAuthorizedUser.getId(), "100000");
Assert.assertEquals(Status.SUCCESS, result.get(Constants.STATUS));
+ logger.info(result.toString());
}
diff --git
a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/AuthorizationType.java
b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/AuthorizationType.java
index 1c371e7..4c13134 100644
---
a/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/AuthorizationType.java
+++
b/dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/enums/AuthorizationType.java
@@ -24,12 +24,14 @@ import com.baomidou.mybatisplus.annotation.EnumValue;
public enum AuthorizationType {
/**
* 0 RESOURCE_FILE;
+ * 1 UDF_FILE;
* 1 DATASOURCE;
* 2 UDF;
*/
RESOURCE_FILE(0, "resource file"),
- DATASOURCE(1, "data source"),
- UDF(2, "udf function");
+ UDF_FILE(1, "udf file"),
+ DATASOURCE(2, "data source"),
+ UDF(3, "udf function");
AuthorizationType(int code, String descp){
this.code = code;
diff --git
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/ProcessDao.java
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/ProcessDao.java
index aabd6b4..19e87f8 100644
---
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/ProcessDao.java
+++
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/ProcessDao.java
@@ -1789,6 +1789,10 @@ public class ProcessDao {
Set<String> authorizedResources =
resourceMapper.listAuthorizedResource(userId, needChecks).stream().map(t ->
t.getAlias()).collect(toSet());
originResSet.removeAll(authorizedResources);
break;
+ case UDF_FILE:
+ Set<Integer> authorizedUdfFiles =
resourceMapper.listAuthorizedResourceById(userId, needChecks).stream().map(t ->
t.getId()).collect(toSet());
+ originResSet.removeAll(authorizedUdfFiles);
+ break;
case DATASOURCE:
Set<Integer> authorizedDatasources =
dataSourceMapper.listAuthorizedDataSource(userId,needChecks).stream().map(t ->
t.getId()).collect(toSet());
originResSet.removeAll(authorizedDatasources);
diff --git
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ResourceMapper.java
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ResourceMapper.java
index c407811..3d0b183 100644
---
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ResourceMapper.java
+++
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/ResourceMapper.java
@@ -99,4 +99,12 @@ public interface ResourceMapper extends BaseMapper<Resource>
{
* @return resource list
*/
<T> List<Resource> listAuthorizedResource(@Param("userId") int
userId,@Param("resNames")T[] resNames);
+
+ /**
+ * list authorized resource
+ * @param userId userId
+ * @param resIds resource ids
+ * @return resource list
+ */
+ <T> List<Resource> listAuthorizedResourceById(@Param("userId") int
userId,@Param("resIds")T[] resIds);
}
diff --git
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapper.java
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapper.java
index 7e7850c..2411c9b 100644
---
a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapper.java
+++
b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapper.java
@@ -93,5 +93,12 @@ public interface UdfFuncMapper extends BaseMapper<UdfFunc> {
*/
List<UdfFunc> listUdfByResourceId(@Param("resourceIds") int[] resourceIds);
+ /**
+ * list authorized UDF by resource id
+ * @param resourceIds resource id array
+ * @return UDF function list
+ */
+ List<UdfFunc> listAuthorizedUdfByResourceId(@Param("userId") int
userId,@Param("resourceIds") int[] resourceIds);
+
}
diff --git
a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ResourceMapper.xml
b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ResourceMapper.xml
index b451d62..c9dc2b3 100644
---
a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ResourceMapper.xml
+++
b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/ResourceMapper.xml
@@ -86,5 +86,17 @@
</foreach>
</if>
</select>
+ <select id="listAuthorizedResourceById"
resultType="org.apache.dolphinscheduler.dao.entity.Resource">
+ select *
+ from t_ds_resources
+ where id in (select resources_id from t_ds_relation_resources_user
where user_id=#{userId}
+ union select id as resources_id from t_ds_resources where
user_id=#{userId})
+ <if test="resIds != null and resIds != ''">
+ and id in
+ <foreach collection="resIds" item="i" open="(" close=")"
separator=",">
+ #{i}
+ </foreach>
+ </if>
+ </select>
</mapper>
diff --git
a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapper.xml
b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapper.xml
index 512312a..e38d163 100644
---
a/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapper.xml
+++
b/dolphinscheduler-dao/src/main/resources/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapper.xml
@@ -98,4 +98,17 @@
</foreach>
</if>
</select>
+ <select id="listAuthorizedUdfByResourceId"
resultType="org.apache.dolphinscheduler.dao.entity.UdfFunc">
+ select *
+ from t_ds_udfs
+ where
+ 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
+ <foreach collection="resourceIds" item="i" open="(" close=")"
separator=",">
+ #{i}
+ </foreach>
+ </if>
+ </select>
</mapper>
\ No newline at end of file
diff --git
a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapperTest.java
b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapperTest.java
index c4d2927..b0704b7 100644
---
a/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapperTest.java
+++
b/dolphinscheduler-dao/src/test/java/org/apache/dolphinscheduler/dao/mapper/UdfFuncMapperTest.java
@@ -23,6 +23,7 @@ import org.apache.commons.lang3.ArrayUtils;
import org.apache.dolphinscheduler.common.enums.ResourceType;
import org.apache.dolphinscheduler.common.enums.UdfType;
import org.apache.dolphinscheduler.common.enums.UserType;
+import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.dao.entity.Resource;
import org.apache.dolphinscheduler.dao.entity.UDFUser;
import org.apache.dolphinscheduler.dao.entity.UdfFunc;
@@ -39,6 +40,8 @@ import
org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
diff --git
a/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java
b/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java
index 9702e66..5cb7239 100644
---
a/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java
+++
b/dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/sql/SqlTask.java
@@ -53,6 +53,7 @@ import java.sql.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collector;
import java.util.stream.Collectors;
import static org.apache.dolphinscheduler.common.Constants.*;
@@ -123,8 +124,11 @@ public class SqlTask extends AbstractTask {
return;
}
int dataSourceId = sqlParameters.getDatasource();
+ // process instance
+ ProcessInstance processInstance =
processDao.findProcessInstanceByTaskId(taskProps.getTaskInstId());
+ int userId = processInstance.getExecutorId();
// check data source permission
- checkDataSourcePermission(dataSourceId);
+ checkDataSourcePermission(userId,dataSourceId);
dataSource= processDao.findDataSourceById(dataSourceId);
logger.info("datasource name : {} , type : {} , desc : {} , user_id :
{} , parameter : {}",
dataSource.getName(),
@@ -171,8 +175,11 @@ public class SqlTask extends AbstractTask {
idsArray[i]=Integer.parseInt(ids[i]);
}
// check udf permission
- checkUdfPermission(ArrayUtils.toObject(idsArray));
+ checkUdfPermission(userId,ArrayUtils.toObject(idsArray));
List<UdfFunc> udfFuncList =
processDao.queryUdfFunListByids(idsArray);
+ // check whether has permission to download udf file
+ checkUdfFilePermission(userId,udfFuncList);
+
Map<String,UdfFunc> udfFuncMap = new HashMap<String,UdfFunc>();
for(UdfFunc udfFunc : udfFuncList) {
String tenantCode =
processDao.queryTenantCodeByResName(udfFunc.getResourceName(),
ResourceType.UDF);
@@ -466,29 +473,36 @@ public class SqlTask extends AbstractTask {
}
/**
- * check udf function permission
- * @param udfFunIds udf functions
+ * check udf file permission
+ * @param userId login user id
+ * @param udfFuncList udf function list
* @return if has download permission return true else false
*/
- private void checkUdfPermission(Integer[] udfFunIds) throws Exception{
- // process instance
- ProcessInstance processInstance =
processDao.findProcessInstanceByTaskId(taskProps.getTaskInstId());
- int userId = processInstance.getExecutorId();
+ private void checkUdfFilePermission(int userId,List<UdfFunc> udfFuncList)
throws Exception{
+ Integer[] resourceIds = udfFuncList.stream().map(t ->
t.getResourceId()).collect(Collectors.toList()).toArray(new
Integer[udfFuncList.size()]);
+ PermissionCheck<Integer> permissionCheckUdfFile = new
PermissionCheck<Integer>(AuthorizationType.UDF_FILE,processDao,resourceIds,userId,logger);
+ permissionCheckUdfFile.checkPermission();
+ }
+
+ /**
+ * check udf function permission
+ * @param userId login user id
+ * @param udfFunIds udf functions
+ * @return if has permission return true else false
+ */
+ private void checkUdfPermission(int userId,Integer[] udfFunIds) throws
Exception{
PermissionCheck<Integer> permissionCheckUdf = new
PermissionCheck<Integer>(AuthorizationType.UDF,processDao,udfFunIds,userId,logger);
permissionCheckUdf.checkPermission();
}
/**
* check data source permission
+ * @param userId login user id
* @param dataSourceId data source id
* @return if has download permission return true else false
*/
- private void checkDataSourcePermission(int dataSourceId) throws Exception{
- // process instance
- ProcessInstance processInstance =
processDao.findProcessInstanceByTaskId(taskProps.getTaskInstId());
- int userId = processInstance.getExecutorId();
-
+ private void checkDataSourcePermission(int userId,int dataSourceId) throws
Exception{
PermissionCheck<Integer> permissionCheckDataSource = new
PermissionCheck<Integer>(AuthorizationType.DATASOURCE,processDao,new
Integer[]{dataSourceId},userId,logger);
permissionCheckDataSource.checkPermission();
}