github-advanced-security[bot] commented on code in PR #15554: URL: https://github.com/apache/dolphinscheduler/pull/15554#discussion_r1475724325
########## dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/OperatorLogAspect.java: ########## @@ -0,0 +1,355 @@ +/* + * 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.audit; + +import org.apache.dolphinscheduler.api.enums.ExecuteType; +import org.apache.dolphinscheduler.api.service.AuditService; +import org.apache.dolphinscheduler.api.utils.Result; +import org.apache.dolphinscheduler.common.enums.AuditObjectType; +import org.apache.dolphinscheduler.common.enums.AuditOperationType; +import org.apache.dolphinscheduler.common.enums.ReleaseState; +import org.apache.dolphinscheduler.dao.entity.AuditLog; +import org.apache.dolphinscheduler.dao.entity.Schedule; +import org.apache.dolphinscheduler.dao.entity.User; +import org.apache.dolphinscheduler.dao.mapper.ScheduleMapper; +import org.apache.dolphinscheduler.dao.mapper.UserMapper; +import org.apache.dolphinscheduler.spi.enums.ResourceType; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import io.swagger.v3.oas.annotations.Operation; + +@Aspect +@Component +@Slf4j +public class OperatorLogAspect { + + @Autowired + private AuditService auditService; + + @Autowired + private ScheduleMapper scheduleMapper; + + @Autowired + private UserMapper userMapper; + + @Pointcut("@annotation(OperatorLog)") + public void logPointCut() { + + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + + OperatorLog operatorLog = method.getAnnotation(OperatorLog.class); + // Api don't need record log + if (operatorLog == null) { + return point.proceed(); + } + + AuditObjectType auditObjectType = operatorLog.objectType(); + AuditOperationType auditOperationType = operatorLog.operationType(); + + Operation operation = method.getAnnotation(Operation.class); + if (operation == null) { + log.error("api operation is null"); + return point.proceed(); + } + + Object[] args = point.getArgs(); + String[] strings = signature.getParameterNames(); + + User user = null; + + Map<String, Object> paramsMap = new HashMap<>(); + for (int i = 0; i < strings.length; i++) { + paramsMap.put(strings[i], args[i]); + + if (args[i] instanceof User) { + user = (User) args[i]; + } + } + + if (user == null) { + log.error("api param user is null"); + return point.proceed(); + } + + // Change object and operation for resource part + ResourceType resourceType = (ResourceType) paramsMap.get("type"); + + switch (auditObjectType) { + case FOLDER: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FOLDER; + break; + case FILE: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FILE; + break; + case WORKER_GROUP: + if (auditOperationType == AuditOperationType.CREATE && + !paramsMap.get("id").toString().equals("0")) { + auditOperationType = AuditOperationType.UPDATE; + } + break; + default: + break; + } + + if (auditOperationType.isIntermediateState()) { + switch (auditOperationType) { + case RELEASE: + ReleaseState releaseState = (ReleaseState) paramsMap.get("releaseState"); + switch (releaseState) { + case ONLINE: + auditOperationType = AuditOperationType.ONLINE; + break; + case OFFLINE: + auditOperationType = AuditOperationType.OFFLINE; + break; + default: + break; + } + break; + case EXECUTE: + ExecuteType executeType = (ExecuteType) paramsMap.get("executeType"); + switch (executeType) { + case REPEAT_RUNNING: + auditOperationType = AuditOperationType.RERUN; + break; + case RECOVER_SUSPENDED_PROCESS: + auditOperationType = AuditOperationType.RESUME_PAUSE; + break; + case START_FAILURE_TASK_PROCESS: + auditOperationType = AuditOperationType.RESUME_FAILURE; + break; + case STOP: + auditOperationType = AuditOperationType.STOP; + break; + case PAUSE: + auditOperationType = AuditOperationType.PAUSE; + break; + case EXECUTE_TASK: + auditOperationType = AuditOperationType.EXECUTE; + break; + default: + break; + } + break; + default: + break; + } + } + + List<AuditLog> auditLogList = new ArrayList<>(); + AuditLog auditLog = new AuditLog(); + auditLog.setUserId(user.getId()); + auditLog.setObjectType(auditObjectType.getCode()); + auditLog.setOperationType(auditOperationType.getCode()); + auditLog.setDescription(operation.description()); + auditLog.setTime(new Date()); + auditLogList.add(auditLog); + + setInformation(operatorLog, auditLogList, paramsMap); + + Result result = (Result) point.proceed(); + + if (resultFail(result)) { + log.error("request fail, code {}", result.getCode()); + return result; + } + + // need get field by created obj like create operation + if (operatorLog.returnObjectFieldName().length != 0) { + auditLog.setObjectId(getObjectIfFromReturnObject(result.getData(), operatorLog.returnObjectFieldName())); + auditLog.setObjectName(auditService.getObjectNameByObjectId(auditLog.getObjectId(), auditObjectType)); + } + + long latency = System.currentTimeMillis() - beginTime; + + auditService.addAudit(auditLogList, latency); + + return result; + } + + private void setInformation(OperatorLog operatorLog, List<AuditLog> auditLogList, Map<String, Object> paramsMap) { + + String[] paramNameArr = operatorLog.requestParamName(); + + if (paramNameArr.length == 0) { + return; + } + + modifyParma(paramNameArr, paramsMap, operatorLog.objectType()); + + setObjectByParma(paramNameArr, paramsMap, operatorLog.objectType(), auditLogList); + + switch (operatorLog.operationType()) { + case SWITCH_VERSION: + case DELETE_VERSION: + auditLogList.get(0).setObjectName(paramsMap.get("version").toString()); + break; + default: + break; + } + + if (auditLogList.get(0).getObjectId() == null) { + auditLogList.get(0).setObjectId(getObjectIdentityByParma(paramNameArr, paramsMap)); + } + } + + private long getObjectIdentityByParma(String[] paramNameArr, Map<String, Object> paramsMap) { + for (String name : paramNameArr) { + if (paramsMap.get(name) instanceof String) { + String param = (String) paramsMap.get(name); + if (param.matches("\\d+")) { + return Long.parseLong(param); Review Comment: ## Missing catch of NumberFormatException Potential uncaught 'java.lang.NumberFormatException'. [Show more details](https://github.com/apache/dolphinscheduler/security/code-scanning/3879) ########## dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/OperatorLogAspect.java: ########## @@ -0,0 +1,355 @@ +/* + * 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.audit; + +import org.apache.dolphinscheduler.api.enums.ExecuteType; +import org.apache.dolphinscheduler.api.service.AuditService; +import org.apache.dolphinscheduler.api.utils.Result; +import org.apache.dolphinscheduler.common.enums.AuditObjectType; +import org.apache.dolphinscheduler.common.enums.AuditOperationType; +import org.apache.dolphinscheduler.common.enums.ReleaseState; +import org.apache.dolphinscheduler.dao.entity.AuditLog; +import org.apache.dolphinscheduler.dao.entity.Schedule; +import org.apache.dolphinscheduler.dao.entity.User; +import org.apache.dolphinscheduler.dao.mapper.ScheduleMapper; +import org.apache.dolphinscheduler.dao.mapper.UserMapper; +import org.apache.dolphinscheduler.spi.enums.ResourceType; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import io.swagger.v3.oas.annotations.Operation; + +@Aspect +@Component +@Slf4j +public class OperatorLogAspect { + + @Autowired + private AuditService auditService; + + @Autowired + private ScheduleMapper scheduleMapper; + + @Autowired + private UserMapper userMapper; + + @Pointcut("@annotation(OperatorLog)") + public void logPointCut() { + + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + + OperatorLog operatorLog = method.getAnnotation(OperatorLog.class); + // Api don't need record log + if (operatorLog == null) { + return point.proceed(); + } + + AuditObjectType auditObjectType = operatorLog.objectType(); + AuditOperationType auditOperationType = operatorLog.operationType(); + + Operation operation = method.getAnnotation(Operation.class); + if (operation == null) { + log.error("api operation is null"); + return point.proceed(); + } + + Object[] args = point.getArgs(); + String[] strings = signature.getParameterNames(); + + User user = null; + + Map<String, Object> paramsMap = new HashMap<>(); + for (int i = 0; i < strings.length; i++) { + paramsMap.put(strings[i], args[i]); + + if (args[i] instanceof User) { + user = (User) args[i]; + } + } + + if (user == null) { + log.error("api param user is null"); + return point.proceed(); + } + + // Change object and operation for resource part + ResourceType resourceType = (ResourceType) paramsMap.get("type"); + + switch (auditObjectType) { + case FOLDER: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FOLDER; + break; + case FILE: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FILE; + break; + case WORKER_GROUP: + if (auditOperationType == AuditOperationType.CREATE && + !paramsMap.get("id").toString().equals("0")) { + auditOperationType = AuditOperationType.UPDATE; + } + break; + default: + break; + } + + if (auditOperationType.isIntermediateState()) { + switch (auditOperationType) { + case RELEASE: + ReleaseState releaseState = (ReleaseState) paramsMap.get("releaseState"); + switch (releaseState) { + case ONLINE: + auditOperationType = AuditOperationType.ONLINE; + break; + case OFFLINE: + auditOperationType = AuditOperationType.OFFLINE; + break; + default: + break; + } + break; + case EXECUTE: + ExecuteType executeType = (ExecuteType) paramsMap.get("executeType"); + switch (executeType) { + case REPEAT_RUNNING: + auditOperationType = AuditOperationType.RERUN; + break; + case RECOVER_SUSPENDED_PROCESS: + auditOperationType = AuditOperationType.RESUME_PAUSE; + break; + case START_FAILURE_TASK_PROCESS: + auditOperationType = AuditOperationType.RESUME_FAILURE; + break; + case STOP: + auditOperationType = AuditOperationType.STOP; + break; + case PAUSE: + auditOperationType = AuditOperationType.PAUSE; + break; + case EXECUTE_TASK: + auditOperationType = AuditOperationType.EXECUTE; + break; + default: + break; + } + break; + default: + break; + } + } + + List<AuditLog> auditLogList = new ArrayList<>(); + AuditLog auditLog = new AuditLog(); + auditLog.setUserId(user.getId()); + auditLog.setObjectType(auditObjectType.getCode()); + auditLog.setOperationType(auditOperationType.getCode()); + auditLog.setDescription(operation.description()); + auditLog.setTime(new Date()); + auditLogList.add(auditLog); + + setInformation(operatorLog, auditLogList, paramsMap); + + Result result = (Result) point.proceed(); + + if (resultFail(result)) { + log.error("request fail, code {}", result.getCode()); + return result; + } + + // need get field by created obj like create operation + if (operatorLog.returnObjectFieldName().length != 0) { + auditLog.setObjectId(getObjectIfFromReturnObject(result.getData(), operatorLog.returnObjectFieldName())); + auditLog.setObjectName(auditService.getObjectNameByObjectId(auditLog.getObjectId(), auditObjectType)); + } + + long latency = System.currentTimeMillis() - beginTime; + + auditService.addAudit(auditLogList, latency); + + return result; + } + + private void setInformation(OperatorLog operatorLog, List<AuditLog> auditLogList, Map<String, Object> paramsMap) { + + String[] paramNameArr = operatorLog.requestParamName(); + + if (paramNameArr.length == 0) { + return; + } + + modifyParma(paramNameArr, paramsMap, operatorLog.objectType()); + + setObjectByParma(paramNameArr, paramsMap, operatorLog.objectType(), auditLogList); + + switch (operatorLog.operationType()) { + case SWITCH_VERSION: + case DELETE_VERSION: + auditLogList.get(0).setObjectName(paramsMap.get("version").toString()); + break; + default: + break; + } + + if (auditLogList.get(0).getObjectId() == null) { + auditLogList.get(0).setObjectId(getObjectIdentityByParma(paramNameArr, paramsMap)); + } + } + + private long getObjectIdentityByParma(String[] paramNameArr, Map<String, Object> paramsMap) { + for (String name : paramNameArr) { + if (paramsMap.get(name) instanceof String) { + String param = (String) paramsMap.get(name); + if (param.matches("\\d+")) { + return Long.parseLong(param); + } + } + } + + return -1; + } + + private void modifyParma(String[] paramNameArr, Map<String, Object> paramsMap, AuditObjectType objectType) { + switch (objectType) { + case SCHEDULE: + for (int i = 0; i < paramNameArr.length; i++) { + if (paramNameArr[i].equals("id")) { + int id = (int) paramsMap.get(paramNameArr[i]); + Schedule schedule = scheduleMapper.selectById(id); + paramsMap.put("code", schedule.getProcessDefinitionCode()); + paramNameArr[i] = "code"; + } + } + break; + default: + break; + } + } + + private void setObjectByParma(String[] paramNameArr, Map<String, Object> paramsMap, AuditObjectType objectType, + List<AuditLog> auditLogList) { + for (String name : paramNameArr) { + if (name.toLowerCase().contains("codes")) { + String[] codes = ((String) paramsMap.get(name)).split(","); + AuditLog auditLog = auditLogList.get(0); + + for (String code : codes) { + String detail = auditService.getObjectNameByObjectId( + Long.parseLong(code), objectType); + + auditLog.setObjectId(Long.parseLong(code)); Review Comment: ## Missing catch of NumberFormatException Potential uncaught 'java.lang.NumberFormatException'. [Show more details](https://github.com/apache/dolphinscheduler/security/code-scanning/3881) ########## dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/OperatorLogAspect.java: ########## @@ -0,0 +1,355 @@ +/* + * 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.audit; + +import org.apache.dolphinscheduler.api.enums.ExecuteType; +import org.apache.dolphinscheduler.api.service.AuditService; +import org.apache.dolphinscheduler.api.utils.Result; +import org.apache.dolphinscheduler.common.enums.AuditObjectType; +import org.apache.dolphinscheduler.common.enums.AuditOperationType; +import org.apache.dolphinscheduler.common.enums.ReleaseState; +import org.apache.dolphinscheduler.dao.entity.AuditLog; +import org.apache.dolphinscheduler.dao.entity.Schedule; +import org.apache.dolphinscheduler.dao.entity.User; +import org.apache.dolphinscheduler.dao.mapper.ScheduleMapper; +import org.apache.dolphinscheduler.dao.mapper.UserMapper; +import org.apache.dolphinscheduler.spi.enums.ResourceType; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import io.swagger.v3.oas.annotations.Operation; + +@Aspect +@Component +@Slf4j +public class OperatorLogAspect { + + @Autowired + private AuditService auditService; + + @Autowired + private ScheduleMapper scheduleMapper; + + @Autowired + private UserMapper userMapper; + + @Pointcut("@annotation(OperatorLog)") + public void logPointCut() { + + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + + OperatorLog operatorLog = method.getAnnotation(OperatorLog.class); + // Api don't need record log + if (operatorLog == null) { + return point.proceed(); + } + + AuditObjectType auditObjectType = operatorLog.objectType(); + AuditOperationType auditOperationType = operatorLog.operationType(); + + Operation operation = method.getAnnotation(Operation.class); + if (operation == null) { + log.error("api operation is null"); + return point.proceed(); + } + + Object[] args = point.getArgs(); + String[] strings = signature.getParameterNames(); + + User user = null; + + Map<String, Object> paramsMap = new HashMap<>(); + for (int i = 0; i < strings.length; i++) { + paramsMap.put(strings[i], args[i]); + + if (args[i] instanceof User) { + user = (User) args[i]; + } + } + + if (user == null) { + log.error("api param user is null"); + return point.proceed(); + } + + // Change object and operation for resource part + ResourceType resourceType = (ResourceType) paramsMap.get("type"); + + switch (auditObjectType) { + case FOLDER: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FOLDER; + break; + case FILE: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FILE; + break; + case WORKER_GROUP: + if (auditOperationType == AuditOperationType.CREATE && + !paramsMap.get("id").toString().equals("0")) { + auditOperationType = AuditOperationType.UPDATE; + } + break; + default: + break; + } + + if (auditOperationType.isIntermediateState()) { + switch (auditOperationType) { + case RELEASE: + ReleaseState releaseState = (ReleaseState) paramsMap.get("releaseState"); + switch (releaseState) { + case ONLINE: + auditOperationType = AuditOperationType.ONLINE; + break; + case OFFLINE: + auditOperationType = AuditOperationType.OFFLINE; + break; + default: + break; + } + break; + case EXECUTE: + ExecuteType executeType = (ExecuteType) paramsMap.get("executeType"); + switch (executeType) { + case REPEAT_RUNNING: + auditOperationType = AuditOperationType.RERUN; + break; + case RECOVER_SUSPENDED_PROCESS: + auditOperationType = AuditOperationType.RESUME_PAUSE; + break; + case START_FAILURE_TASK_PROCESS: + auditOperationType = AuditOperationType.RESUME_FAILURE; + break; + case STOP: + auditOperationType = AuditOperationType.STOP; + break; + case PAUSE: + auditOperationType = AuditOperationType.PAUSE; + break; + case EXECUTE_TASK: + auditOperationType = AuditOperationType.EXECUTE; + break; + default: + break; + } + break; + default: + break; + } + } + + List<AuditLog> auditLogList = new ArrayList<>(); + AuditLog auditLog = new AuditLog(); + auditLog.setUserId(user.getId()); + auditLog.setObjectType(auditObjectType.getCode()); + auditLog.setOperationType(auditOperationType.getCode()); + auditLog.setDescription(operation.description()); + auditLog.setTime(new Date()); + auditLogList.add(auditLog); + + setInformation(operatorLog, auditLogList, paramsMap); + + Result result = (Result) point.proceed(); + + if (resultFail(result)) { + log.error("request fail, code {}", result.getCode()); + return result; + } + + // need get field by created obj like create operation + if (operatorLog.returnObjectFieldName().length != 0) { + auditLog.setObjectId(getObjectIfFromReturnObject(result.getData(), operatorLog.returnObjectFieldName())); + auditLog.setObjectName(auditService.getObjectNameByObjectId(auditLog.getObjectId(), auditObjectType)); + } + + long latency = System.currentTimeMillis() - beginTime; + + auditService.addAudit(auditLogList, latency); + + return result; + } + + private void setInformation(OperatorLog operatorLog, List<AuditLog> auditLogList, Map<String, Object> paramsMap) { + + String[] paramNameArr = operatorLog.requestParamName(); + + if (paramNameArr.length == 0) { + return; + } + + modifyParma(paramNameArr, paramsMap, operatorLog.objectType()); + + setObjectByParma(paramNameArr, paramsMap, operatorLog.objectType(), auditLogList); + + switch (operatorLog.operationType()) { + case SWITCH_VERSION: + case DELETE_VERSION: + auditLogList.get(0).setObjectName(paramsMap.get("version").toString()); + break; + default: + break; + } + + if (auditLogList.get(0).getObjectId() == null) { + auditLogList.get(0).setObjectId(getObjectIdentityByParma(paramNameArr, paramsMap)); + } + } + + private long getObjectIdentityByParma(String[] paramNameArr, Map<String, Object> paramsMap) { + for (String name : paramNameArr) { + if (paramsMap.get(name) instanceof String) { + String param = (String) paramsMap.get(name); + if (param.matches("\\d+")) { + return Long.parseLong(param); + } + } + } + + return -1; + } + + private void modifyParma(String[] paramNameArr, Map<String, Object> paramsMap, AuditObjectType objectType) { + switch (objectType) { + case SCHEDULE: + for (int i = 0; i < paramNameArr.length; i++) { + if (paramNameArr[i].equals("id")) { + int id = (int) paramsMap.get(paramNameArr[i]); + Schedule schedule = scheduleMapper.selectById(id); + paramsMap.put("code", schedule.getProcessDefinitionCode()); + paramNameArr[i] = "code"; + } + } + break; + default: + break; + } + } + + private void setObjectByParma(String[] paramNameArr, Map<String, Object> paramsMap, AuditObjectType objectType, + List<AuditLog> auditLogList) { + for (String name : paramNameArr) { + if (name.toLowerCase().contains("codes")) { + String[] codes = ((String) paramsMap.get(name)).split(","); + AuditLog auditLog = auditLogList.get(0); + + for (String code : codes) { + String detail = auditService.getObjectNameByObjectId( + Long.parseLong(code), objectType); Review Comment: ## Missing catch of NumberFormatException Potential uncaught 'java.lang.NumberFormatException'. [Show more details](https://github.com/apache/dolphinscheduler/security/code-scanning/3880) ########## dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/OperatorLogAspect.java: ########## @@ -0,0 +1,355 @@ +/* + * 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.audit; + +import org.apache.dolphinscheduler.api.enums.ExecuteType; +import org.apache.dolphinscheduler.api.service.AuditService; +import org.apache.dolphinscheduler.api.utils.Result; +import org.apache.dolphinscheduler.common.enums.AuditObjectType; +import org.apache.dolphinscheduler.common.enums.AuditOperationType; +import org.apache.dolphinscheduler.common.enums.ReleaseState; +import org.apache.dolphinscheduler.dao.entity.AuditLog; +import org.apache.dolphinscheduler.dao.entity.Schedule; +import org.apache.dolphinscheduler.dao.entity.User; +import org.apache.dolphinscheduler.dao.mapper.ScheduleMapper; +import org.apache.dolphinscheduler.dao.mapper.UserMapper; +import org.apache.dolphinscheduler.spi.enums.ResourceType; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import io.swagger.v3.oas.annotations.Operation; + +@Aspect +@Component +@Slf4j +public class OperatorLogAspect { + + @Autowired + private AuditService auditService; + + @Autowired + private ScheduleMapper scheduleMapper; + + @Autowired + private UserMapper userMapper; + + @Pointcut("@annotation(OperatorLog)") + public void logPointCut() { + + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + + OperatorLog operatorLog = method.getAnnotation(OperatorLog.class); + // Api don't need record log + if (operatorLog == null) { + return point.proceed(); + } + + AuditObjectType auditObjectType = operatorLog.objectType(); + AuditOperationType auditOperationType = operatorLog.operationType(); + + Operation operation = method.getAnnotation(Operation.class); + if (operation == null) { + log.error("api operation is null"); + return point.proceed(); + } + + Object[] args = point.getArgs(); + String[] strings = signature.getParameterNames(); + + User user = null; + + Map<String, Object> paramsMap = new HashMap<>(); + for (int i = 0; i < strings.length; i++) { + paramsMap.put(strings[i], args[i]); + + if (args[i] instanceof User) { + user = (User) args[i]; + } + } + + if (user == null) { + log.error("api param user is null"); + return point.proceed(); + } + + // Change object and operation for resource part + ResourceType resourceType = (ResourceType) paramsMap.get("type"); + + switch (auditObjectType) { + case FOLDER: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FOLDER; + break; + case FILE: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FILE; + break; + case WORKER_GROUP: + if (auditOperationType == AuditOperationType.CREATE && + !paramsMap.get("id").toString().equals("0")) { + auditOperationType = AuditOperationType.UPDATE; + } + break; + default: + break; + } + + if (auditOperationType.isIntermediateState()) { + switch (auditOperationType) { + case RELEASE: + ReleaseState releaseState = (ReleaseState) paramsMap.get("releaseState"); + switch (releaseState) { + case ONLINE: + auditOperationType = AuditOperationType.ONLINE; + break; + case OFFLINE: + auditOperationType = AuditOperationType.OFFLINE; + break; + default: + break; + } + break; + case EXECUTE: + ExecuteType executeType = (ExecuteType) paramsMap.get("executeType"); + switch (executeType) { + case REPEAT_RUNNING: + auditOperationType = AuditOperationType.RERUN; + break; + case RECOVER_SUSPENDED_PROCESS: + auditOperationType = AuditOperationType.RESUME_PAUSE; + break; + case START_FAILURE_TASK_PROCESS: + auditOperationType = AuditOperationType.RESUME_FAILURE; + break; + case STOP: + auditOperationType = AuditOperationType.STOP; + break; + case PAUSE: + auditOperationType = AuditOperationType.PAUSE; + break; + case EXECUTE_TASK: + auditOperationType = AuditOperationType.EXECUTE; + break; + default: + break; + } + break; + default: + break; + } + } + + List<AuditLog> auditLogList = new ArrayList<>(); + AuditLog auditLog = new AuditLog(); + auditLog.setUserId(user.getId()); + auditLog.setObjectType(auditObjectType.getCode()); + auditLog.setOperationType(auditOperationType.getCode()); + auditLog.setDescription(operation.description()); + auditLog.setTime(new Date()); + auditLogList.add(auditLog); + + setInformation(operatorLog, auditLogList, paramsMap); + + Result result = (Result) point.proceed(); + + if (resultFail(result)) { + log.error("request fail, code {}", result.getCode()); + return result; + } + + // need get field by created obj like create operation + if (operatorLog.returnObjectFieldName().length != 0) { + auditLog.setObjectId(getObjectIfFromReturnObject(result.getData(), operatorLog.returnObjectFieldName())); + auditLog.setObjectName(auditService.getObjectNameByObjectId(auditLog.getObjectId(), auditObjectType)); + } + + long latency = System.currentTimeMillis() - beginTime; + + auditService.addAudit(auditLogList, latency); + + return result; + } + + private void setInformation(OperatorLog operatorLog, List<AuditLog> auditLogList, Map<String, Object> paramsMap) { + + String[] paramNameArr = operatorLog.requestParamName(); + + if (paramNameArr.length == 0) { + return; + } + + modifyParma(paramNameArr, paramsMap, operatorLog.objectType()); + + setObjectByParma(paramNameArr, paramsMap, operatorLog.objectType(), auditLogList); + + switch (operatorLog.operationType()) { + case SWITCH_VERSION: + case DELETE_VERSION: + auditLogList.get(0).setObjectName(paramsMap.get("version").toString()); + break; + default: + break; + } + + if (auditLogList.get(0).getObjectId() == null) { + auditLogList.get(0).setObjectId(getObjectIdentityByParma(paramNameArr, paramsMap)); + } + } + + private long getObjectIdentityByParma(String[] paramNameArr, Map<String, Object> paramsMap) { + for (String name : paramNameArr) { + if (paramsMap.get(name) instanceof String) { + String param = (String) paramsMap.get(name); + if (param.matches("\\d+")) { + return Long.parseLong(param); + } + } + } + + return -1; + } + + private void modifyParma(String[] paramNameArr, Map<String, Object> paramsMap, AuditObjectType objectType) { + switch (objectType) { + case SCHEDULE: + for (int i = 0; i < paramNameArr.length; i++) { + if (paramNameArr[i].equals("id")) { + int id = (int) paramsMap.get(paramNameArr[i]); + Schedule schedule = scheduleMapper.selectById(id); + paramsMap.put("code", schedule.getProcessDefinitionCode()); + paramNameArr[i] = "code"; + } + } + break; + default: + break; + } + } + + private void setObjectByParma(String[] paramNameArr, Map<String, Object> paramsMap, AuditObjectType objectType, + List<AuditLog> auditLogList) { + for (String name : paramNameArr) { + if (name.toLowerCase().contains("codes")) { + String[] codes = ((String) paramsMap.get(name)).split(","); + AuditLog auditLog = auditLogList.get(0); + + for (String code : codes) { + String detail = auditService.getObjectNameByObjectId( + Long.parseLong(code), objectType); + + auditLog.setObjectId(Long.parseLong(code)); + auditLog.setObjectName(detail); + auditLogList.add(auditLog); + auditLog = AuditLog.copyNewOne(auditLog); + } + + auditLogList.remove(0); + } else if (name.toLowerCase().contains("code")) { + long code = (long) paramsMap.get(name); + String detail = auditService.getObjectNameByObjectId(code, objectType); + auditLogList.get(0).setObjectName(detail); + auditLogList.get(0).setObjectId(code); + } else if (name.toLowerCase().contains("ids")) { + String[] ids = ((String) paramsMap.get(name)).split(","); + AuditLog auditLog = auditLogList.get(0); + + for (String id : ids) { + String detail = auditService.getObjectNameByObjectId(Long.parseLong(id), objectType); Review Comment: ## Missing catch of NumberFormatException Potential uncaught 'java.lang.NumberFormatException'. [Show more details](https://github.com/apache/dolphinscheduler/security/code-scanning/3882) ########## dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/audit/OperatorLogAspect.java: ########## @@ -0,0 +1,355 @@ +/* + * 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.audit; + +import org.apache.dolphinscheduler.api.enums.ExecuteType; +import org.apache.dolphinscheduler.api.service.AuditService; +import org.apache.dolphinscheduler.api.utils.Result; +import org.apache.dolphinscheduler.common.enums.AuditObjectType; +import org.apache.dolphinscheduler.common.enums.AuditOperationType; +import org.apache.dolphinscheduler.common.enums.ReleaseState; +import org.apache.dolphinscheduler.dao.entity.AuditLog; +import org.apache.dolphinscheduler.dao.entity.Schedule; +import org.apache.dolphinscheduler.dao.entity.User; +import org.apache.dolphinscheduler.dao.mapper.ScheduleMapper; +import org.apache.dolphinscheduler.dao.mapper.UserMapper; +import org.apache.dolphinscheduler.spi.enums.ResourceType; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.extern.slf4j.Slf4j; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import io.swagger.v3.oas.annotations.Operation; + +@Aspect +@Component +@Slf4j +public class OperatorLogAspect { + + @Autowired + private AuditService auditService; + + @Autowired + private ScheduleMapper scheduleMapper; + + @Autowired + private UserMapper userMapper; + + @Pointcut("@annotation(OperatorLog)") + public void logPointCut() { + + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + + OperatorLog operatorLog = method.getAnnotation(OperatorLog.class); + // Api don't need record log + if (operatorLog == null) { + return point.proceed(); + } + + AuditObjectType auditObjectType = operatorLog.objectType(); + AuditOperationType auditOperationType = operatorLog.operationType(); + + Operation operation = method.getAnnotation(Operation.class); + if (operation == null) { + log.error("api operation is null"); + return point.proceed(); + } + + Object[] args = point.getArgs(); + String[] strings = signature.getParameterNames(); + + User user = null; + + Map<String, Object> paramsMap = new HashMap<>(); + for (int i = 0; i < strings.length; i++) { + paramsMap.put(strings[i], args[i]); + + if (args[i] instanceof User) { + user = (User) args[i]; + } + } + + if (user == null) { + log.error("api param user is null"); + return point.proceed(); + } + + // Change object and operation for resource part + ResourceType resourceType = (ResourceType) paramsMap.get("type"); + + switch (auditObjectType) { + case FOLDER: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FOLDER; + break; + case FILE: + if (resourceType != null && resourceType.equals(ResourceType.UDF)) + auditObjectType = AuditObjectType.UDF_FILE; + break; + case WORKER_GROUP: + if (auditOperationType == AuditOperationType.CREATE && + !paramsMap.get("id").toString().equals("0")) { + auditOperationType = AuditOperationType.UPDATE; + } + break; + default: + break; + } + + if (auditOperationType.isIntermediateState()) { + switch (auditOperationType) { + case RELEASE: + ReleaseState releaseState = (ReleaseState) paramsMap.get("releaseState"); + switch (releaseState) { + case ONLINE: + auditOperationType = AuditOperationType.ONLINE; + break; + case OFFLINE: + auditOperationType = AuditOperationType.OFFLINE; + break; + default: + break; + } + break; + case EXECUTE: + ExecuteType executeType = (ExecuteType) paramsMap.get("executeType"); + switch (executeType) { + case REPEAT_RUNNING: + auditOperationType = AuditOperationType.RERUN; + break; + case RECOVER_SUSPENDED_PROCESS: + auditOperationType = AuditOperationType.RESUME_PAUSE; + break; + case START_FAILURE_TASK_PROCESS: + auditOperationType = AuditOperationType.RESUME_FAILURE; + break; + case STOP: + auditOperationType = AuditOperationType.STOP; + break; + case PAUSE: + auditOperationType = AuditOperationType.PAUSE; + break; + case EXECUTE_TASK: + auditOperationType = AuditOperationType.EXECUTE; + break; + default: + break; + } + break; + default: + break; + } + } + + List<AuditLog> auditLogList = new ArrayList<>(); + AuditLog auditLog = new AuditLog(); + auditLog.setUserId(user.getId()); + auditLog.setObjectType(auditObjectType.getCode()); + auditLog.setOperationType(auditOperationType.getCode()); + auditLog.setDescription(operation.description()); + auditLog.setTime(new Date()); + auditLogList.add(auditLog); + + setInformation(operatorLog, auditLogList, paramsMap); + + Result result = (Result) point.proceed(); + + if (resultFail(result)) { + log.error("request fail, code {}", result.getCode()); + return result; + } + + // need get field by created obj like create operation + if (operatorLog.returnObjectFieldName().length != 0) { + auditLog.setObjectId(getObjectIfFromReturnObject(result.getData(), operatorLog.returnObjectFieldName())); + auditLog.setObjectName(auditService.getObjectNameByObjectId(auditLog.getObjectId(), auditObjectType)); + } + + long latency = System.currentTimeMillis() - beginTime; + + auditService.addAudit(auditLogList, latency); + + return result; + } + + private void setInformation(OperatorLog operatorLog, List<AuditLog> auditLogList, Map<String, Object> paramsMap) { + + String[] paramNameArr = operatorLog.requestParamName(); + + if (paramNameArr.length == 0) { + return; + } + + modifyParma(paramNameArr, paramsMap, operatorLog.objectType()); + + setObjectByParma(paramNameArr, paramsMap, operatorLog.objectType(), auditLogList); + + switch (operatorLog.operationType()) { + case SWITCH_VERSION: + case DELETE_VERSION: + auditLogList.get(0).setObjectName(paramsMap.get("version").toString()); + break; + default: + break; + } + + if (auditLogList.get(0).getObjectId() == null) { + auditLogList.get(0).setObjectId(getObjectIdentityByParma(paramNameArr, paramsMap)); + } + } + + private long getObjectIdentityByParma(String[] paramNameArr, Map<String, Object> paramsMap) { + for (String name : paramNameArr) { + if (paramsMap.get(name) instanceof String) { + String param = (String) paramsMap.get(name); + if (param.matches("\\d+")) { + return Long.parseLong(param); + } + } + } + + return -1; + } + + private void modifyParma(String[] paramNameArr, Map<String, Object> paramsMap, AuditObjectType objectType) { + switch (objectType) { + case SCHEDULE: + for (int i = 0; i < paramNameArr.length; i++) { + if (paramNameArr[i].equals("id")) { + int id = (int) paramsMap.get(paramNameArr[i]); + Schedule schedule = scheduleMapper.selectById(id); + paramsMap.put("code", schedule.getProcessDefinitionCode()); + paramNameArr[i] = "code"; + } + } + break; + default: + break; + } + } + + private void setObjectByParma(String[] paramNameArr, Map<String, Object> paramsMap, AuditObjectType objectType, + List<AuditLog> auditLogList) { + for (String name : paramNameArr) { + if (name.toLowerCase().contains("codes")) { + String[] codes = ((String) paramsMap.get(name)).split(","); + AuditLog auditLog = auditLogList.get(0); + + for (String code : codes) { + String detail = auditService.getObjectNameByObjectId( + Long.parseLong(code), objectType); + + auditLog.setObjectId(Long.parseLong(code)); + auditLog.setObjectName(detail); + auditLogList.add(auditLog); + auditLog = AuditLog.copyNewOne(auditLog); + } + + auditLogList.remove(0); + } else if (name.toLowerCase().contains("code")) { + long code = (long) paramsMap.get(name); + String detail = auditService.getObjectNameByObjectId(code, objectType); + auditLogList.get(0).setObjectName(detail); + auditLogList.get(0).setObjectId(code); + } else if (name.toLowerCase().contains("ids")) { + String[] ids = ((String) paramsMap.get(name)).split(","); + AuditLog auditLog = auditLogList.get(0); + + for (String id : ids) { + String detail = auditService.getObjectNameByObjectId(Long.parseLong(id), objectType); + auditLog.setObjectId(Long.parseLong(id)); Review Comment: ## Missing catch of NumberFormatException Potential uncaught 'java.lang.NumberFormatException'. [Show more details](https://github.com/apache/dolphinscheduler/security/code-scanning/3883) ########## dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/AuditService.java: ########## @@ -19,40 +19,56 @@ import org.apache.dolphinscheduler.api.dto.AuditDto; import org.apache.dolphinscheduler.api.utils.PageInfo; -import org.apache.dolphinscheduler.common.enums.AuditOperationType; -import org.apache.dolphinscheduler.common.enums.AuditResourceType; +import org.apache.dolphinscheduler.common.enums.AuditObjectType; +import org.apache.dolphinscheduler.dao.entity.AuditLog; import org.apache.dolphinscheduler.dao.entity.User; +import java.util.List; + /** * audit information service */ public interface AuditService { /** - * add new audit record + * add audit object + * + * @param auditLog auditLog + */ + void addAudit(AuditLog auditLog); + + /** + * add audit by list * - * @param user login user - * @param resourceType resource type - * @param resourceId resource id - * @param operation operation type + * @param auditLogList auditLog list + * @param latency api latency milliseconds */ - void addAudit(User user, AuditResourceType resourceType, Integer resourceId, AuditOperationType operation); + void addAudit(List<AuditLog> auditLogList, long latency); /** * query audit log list * - * @param loginUser login user - * @param resourceType resource type - * @param operationType operation type - * @param startTime start time - * @param endTime end time - * @param userName query user name - * @param pageNo page number - * @param pageSize page size - * @return audit log string + * @param loginUser login user + * @param objectTypeCodes object type codes + * @param operationTypeCodes operation type codes + * @param startTime start time + * @param endTime end time + * @param userName query user name + * @param pageNo page number + * @param pageSize page size + * @return audit log string */ - PageInfo<AuditDto> queryLogListPaging(User loginUser, AuditResourceType resourceType, - AuditOperationType operationType, String startTime, - String endTime, String userName, + PageInfo<AuditDto> queryLogListPaging(User loginUser, String objectTypeCodes, Review Comment: ## Useless parameter The parameter 'loginUser' is never used. [Show more details](https://github.com/apache/dolphinscheduler/security/code-scanning/3885) ########## dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/AuditServiceImpl.java: ########## @@ -45,68 +79,122 @@ private AuditLogMapper auditLogMapper; @Autowired - private AuditPublishService publishService; + private ProjectMapper projectMapper; + + @Autowired + private ProcessDefinitionMapper processDefinitionMapper; + + @Autowired + private ProcessInstanceMapper processInstanceMapper; + + @Autowired + private TaskDefinitionMapper taskDefinitionMapper; + + @Autowired + private ScheduleMapper scheduleMapper; + + @Autowired + private UdfFuncMapper udfFuncMapper; + + @Autowired + private UserMapper userMapper; + + @Autowired + private DataSourceMapper dataSourceMapper; + + @Autowired + private TenantMapper tenantMapper; + + @Autowired + private AlertGroupMapper alertGroupMapper; + + @Autowired + private AlertPluginInstanceMapper alertPluginInstanceMapper; + + @Autowired + private WorkerGroupMapper workerGroupMapper; + + @Autowired + private QueueMapper queueMapper; + + @Autowired + private EnvironmentMapper environmentMapper; + + @Autowired + private ClusterMapper clusterMapper; + + @Autowired + private K8sNamespaceMapper k8sNamespaceMapper; + + @Autowired + private AccessTokenMapper accessTokenMapper; - /** - * add new audit log - * - * @param user login user - * @param resourceType resource type - * @param resourceId resource id - * @param operation operation type - */ @Override - public void addAudit(User user, AuditResourceType resourceType, Integer resourceId, AuditOperationType operation) { - publishService.publish(new AuditMessage(user, new Date(), resourceType, operation, resourceId)); + public void addAudit(AuditLog auditLog) { + auditLogMapper.insert(auditLog); + } + + @Override + public void addAudit(List<AuditLog> auditLogList, long latency) { + auditLogList.forEach(auditLog -> { + auditLog.setLatency(latency); + addAudit(auditLog); + }); } /** * query audit log paging * - * @param loginUser login user - * @param resourceType resource type - * @param operationType operation type - * @param startDate start time - * @param endDate end time - * @param userName query user name - * @param pageNo page number - * @param pageSize page size + * @param loginUser login user + * @param objectTypeCodes object type codes + * @param operationTypeCodes operation type codes + * @param startDate start time + * @param endDate end time + * @param userName query user name + * @param objectName query object name + * @param pageNo page number + * @param pageSize page size * @return audit log string data */ @Override public PageInfo<AuditDto> queryLogListPaging(User loginUser, - AuditResourceType resourceType, - AuditOperationType operationType, + String objectTypeCodes, + String operationTypeCodes, String startDate, String endDate, String userName, + String objectName, Integer pageNo, Integer pageSize) { - int[] resourceArray = null; - if (resourceType != null) { - resourceArray = new int[]{resourceType.getCode()}; - } - - int[] opsArray = null; - if (operationType != null) { - opsArray = new int[]{operationType.getCode()}; - } + List<Integer> objectTypeCodeList = convertStringToIntList(objectTypeCodes); + List<Integer> operationTypeCodeList = convertStringToIntList(operationTypeCodes); Date start = checkAndParseDateParameters(startDate); Date end = checkAndParseDateParameters(endDate); - IPage<AuditLog> logIPage = auditLogMapper.queryAuditLog(new Page<>(pageNo, pageSize), resourceArray, opsArray, - userName, start, end); + IPage<AuditLog> logIPage = + auditLogMapper.queryAuditLog(new Page<>(pageNo, pageSize), objectTypeCodeList, operationTypeCodeList, + userName, objectName, start, end); List<AuditDto> auditDtos = logIPage.getRecords().stream().map(this::transformAuditLog).collect(Collectors.toList()); PageInfo<AuditDto> pageInfo = new PageInfo<>(pageNo, pageSize); - pageInfo.setTotal((int) auditDtos.size()); + pageInfo.setTotal((int) logIPage.getTotal()); pageInfo.setTotalList(auditDtos); return pageInfo; } + private List<Integer> convertStringToIntList(String codes) { + if (Strings.isNullOrEmpty(codes)) { + return new ArrayList<>(); + } + + return Arrays.stream(codes.split(",")) + .map(Integer::parseInt) Review Comment: ## Missing catch of NumberFormatException Potential uncaught 'java.lang.NumberFormatException'. [Show more details](https://github.com/apache/dolphinscheduler/security/code-scanning/3884) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
