[Feature-5822][api] Add audit log (#6322)
* rebase * update audit log type name * fix the quoted property error * fix bug * update audit global switch default value * fix wrong ddl comment * fix wrong code style * update audit log search sql * add licenses * add unit test * fix wrong code style * fix bugs * fix wrong code style * add test case * add test case * add license * Add unit test in pom.xml * resolve code smell problem * mysql and postgresql ddl update * update audit log path and audit page query * update audit configuration * update audit log schema, add resource type and resource id * update audit query and list page * resolve audit log front page bugs and log query error * update audit configuration * resolve wrong configuration * update AuditLogControllerTest * update application.yaml * resolve code smell * update standalone configuration * resolve bugs Co-authored-by: yc322 <1393242780@qq.com>
This commit is contained in:
parent
30b8b4a93e
commit
fb9f4a1339
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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.common.enums.AuditOperationType;
|
||||
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class AuditMessage {
|
||||
private User user;
|
||||
|
||||
private Date auditDate;
|
||||
|
||||
private AuditResourceType resourceType;
|
||||
|
||||
private AuditOperationType operation;
|
||||
|
||||
private Integer resourceId;
|
||||
|
||||
public AuditMessage(User user, Date auditDate, AuditResourceType resourceType, AuditOperationType operation, Integer resourceId) {
|
||||
this.user = user;
|
||||
this.auditDate = auditDate;
|
||||
this.resourceType = resourceType;
|
||||
this.operation = operation;
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public Date getAuditDate() {
|
||||
return auditDate;
|
||||
}
|
||||
|
||||
public void setAuditDate(Date auditDate) {
|
||||
this.auditDate = auditDate;
|
||||
}
|
||||
|
||||
public AuditResourceType getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
public void setResourceType(AuditResourceType resourceType) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public AuditOperationType getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(AuditOperationType operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public Integer getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(Integer resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AuditMessage{"
|
||||
+ "user=" + user
|
||||
+ ", Date=" + auditDate
|
||||
+ ", resourceType" + resourceType
|
||||
+ ", operation=" + operation
|
||||
+ ", resourceId='" + resourceId + '\'';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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.configuration.AuditConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AuditPublishService {
|
||||
|
||||
private BlockingQueue<AuditMessage> auditMessageQueue = new LinkedBlockingQueue<>();
|
||||
|
||||
@Autowired
|
||||
private List<AuditSubscriber> subscribers;
|
||||
|
||||
@Autowired
|
||||
private AuditConfiguration auditConfiguration;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuditPublishService.class);
|
||||
|
||||
/**
|
||||
* create a daemon thread to process the message queue
|
||||
*/
|
||||
@PostConstruct
|
||||
private void init() {
|
||||
if (auditConfiguration.getEnabled()) {
|
||||
Thread thread = new Thread(this::doPublish);
|
||||
thread.setDaemon(true);
|
||||
thread.setName("Audit-Log-Consume-Thread");
|
||||
thread.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* publish a new audit message
|
||||
*
|
||||
* @param message audit message
|
||||
*/
|
||||
public void publish(AuditMessage message) {
|
||||
if (auditConfiguration.getEnabled() && !auditMessageQueue.offer(message)) {
|
||||
logger.error("add audit message failed {}", message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* subscribers execute the message processor method
|
||||
*/
|
||||
private void doPublish() {
|
||||
AuditMessage message = null;
|
||||
while (true) {
|
||||
try {
|
||||
message = auditMessageQueue.take();
|
||||
for (AuditSubscriber subscriber : subscribers) {
|
||||
try {
|
||||
subscriber.execute(message);
|
||||
} catch (Exception e) {
|
||||
logger.error("consume audit message {} failed, error detail {}", message, e);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
logger.error("consume audit message failed {}.", message, e);
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
public interface AuditSubscriber {
|
||||
|
||||
/**
|
||||
* process the audit message
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
void execute(AuditMessage message);
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.dao.entity.AuditLog;
|
||||
import org.apache.dolphinscheduler.dao.mapper.AuditLogMapper;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AuditSubscriberImpl implements AuditSubscriber {
|
||||
|
||||
@Autowired
|
||||
private AuditLogMapper logMapper;
|
||||
|
||||
@Override
|
||||
public void execute(AuditMessage message) {
|
||||
AuditLog auditLog = new AuditLog();
|
||||
auditLog.setUserId(message.getUser().getId());
|
||||
auditLog.setResourceType(message.getResourceType().getCode());
|
||||
auditLog.setOperation(message.getOperation().getCode());
|
||||
auditLog.setTime(message.getAuditDate());
|
||||
auditLog.setResourceId(message.getResourceId());
|
||||
logMapper.insert(auditLog);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.configuration;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@EnableConfigurationProperties
|
||||
@ConfigurationProperties(value = "audit", ignoreUnknownFields = false)
|
||||
public class AuditConfiguration {
|
||||
private boolean enabled;
|
||||
|
||||
public boolean getEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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.controller;
|
||||
|
||||
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_AUDIT_LOG_LIST_PAGING;
|
||||
|
||||
import org.apache.dolphinscheduler.api.aspect.AccessLogAnnotation;
|
||||
import org.apache.dolphinscheduler.api.exceptions.ApiException;
|
||||
import org.apache.dolphinscheduler.api.service.AuditService;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.Constants;
|
||||
import org.apache.dolphinscheduler.common.enums.AuditOperationType;
|
||||
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
@Api(tags = "AUDIT_LOG_TAG")
|
||||
@RestController
|
||||
@RequestMapping("projects/audit")
|
||||
public class AuditLogController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
AuditService auditService;
|
||||
|
||||
/**
|
||||
* query audit log list paging
|
||||
*
|
||||
* @param loginUser login user
|
||||
* @param pageNo page number
|
||||
* @param moduleType module type
|
||||
* @param operationType operation type
|
||||
* @param startDate start time
|
||||
* @param endDate end time
|
||||
* @param userName user name
|
||||
* @param pageSize page size
|
||||
* @return audit log content
|
||||
*/
|
||||
@ApiOperation(value = "queryAuditLogListPaging", notes = "QUERY_AUDIT_LOG")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "startDate", value = "START_DATE", type = "String"),
|
||||
@ApiImplicitParam(name = "endDate", value = "END_DATE", type = "String"),
|
||||
@ApiImplicitParam(name = "moduleType", value = "MODULE_TYPE", type = "String"),
|
||||
@ApiImplicitParam(name = "operationType", value = "OPERATION_TYPE", type = "String"),
|
||||
@ApiImplicitParam(name = "userName", value = "USER_NAME", type = "String"),
|
||||
@ApiImplicitParam(name = "projectName", value = "PROJECT_NAME", type = "String"),
|
||||
@ApiImplicitParam(name = "processName", value = "PROCESS_NAME", type = "String"),
|
||||
@ApiImplicitParam(name = "pageNo", value = "PAGE_NO", required = true, dataType = "Int", example = "1"),
|
||||
@ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", required = true, dataType = "Int", example = "20")
|
||||
})
|
||||
@GetMapping(value = "/audit-log-list")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
@ApiException(QUERY_AUDIT_LOG_LIST_PAGING)
|
||||
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
|
||||
public Result queryAuditLogListPaging(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
|
||||
@RequestParam("pageNo") Integer pageNo,
|
||||
@RequestParam("pageSize") Integer pageSize,
|
||||
@RequestParam(value = "resourceType", required = false) AuditResourceType resourceType,
|
||||
@RequestParam(value = "operationType", required = false) AuditOperationType operationType,
|
||||
@RequestParam(value = "startDate", required = false) String startDate,
|
||||
@RequestParam(value = "endDate", required = false) String endDate,
|
||||
@RequestParam(value = "userName", required = false) String userName) {
|
||||
Result result = checkPageParams(pageNo, pageSize);
|
||||
if (!result.checkResult()) {
|
||||
return result;
|
||||
}
|
||||
result = auditService.queryLogListPaging(loginUser, resourceType, operationType, startDate, endDate, userName, pageNo, pageSize);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
public class AuditDto {
|
||||
|
||||
private String userName;
|
||||
|
||||
private String resource;
|
||||
|
||||
private String operation;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||
private Date time;
|
||||
|
||||
private String resourceName;
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public String getResource() {
|
||||
return resource;
|
||||
}
|
||||
|
||||
public void setResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(String operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public Date getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Date time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getResourceName() {
|
||||
return resourceName;
|
||||
}
|
||||
|
||||
public void setResourceName(String resourceName) {
|
||||
this.resourceName = resourceName;
|
||||
}
|
||||
}
|
||||
|
|
@ -319,6 +319,9 @@ public enum Status {
|
|||
|
||||
KERBEROS_STARTUP_STATE(100001, "get kerberos startup state error", "获取kerberos启动状态错误"),
|
||||
|
||||
// audit log
|
||||
QUERY_AUDIT_LOG_LIST_PAGING(10057, "query resources list paging", "分页查询资源列表错误"),
|
||||
|
||||
//plugin
|
||||
PLUGIN_NOT_A_UI_COMPONENT(110001, "query plugin error, this plugin has no UI component", "查询插件错误,此插件无UI组件"),
|
||||
QUERY_PLUGINS_RESULT_IS_NULL(110002, "query plugins result is null", "查询插件为空"),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.service;
|
||||
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.enums.AuditOperationType;
|
||||
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
|
||||
/**
|
||||
* audit information service
|
||||
*/
|
||||
public interface AuditService {
|
||||
|
||||
/**
|
||||
* add new audit record
|
||||
*
|
||||
* @param user login user
|
||||
* @param resourceType resource type
|
||||
* @param resourceId resource id
|
||||
* @param operation operation type
|
||||
*/
|
||||
void addAudit(User user, AuditResourceType resourceType, Integer resourceId, AuditOperationType operation);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
Result queryLogListPaging(User loginUser, AuditResourceType resourceType,
|
||||
AuditOperationType operationType, String startTime,
|
||||
String endTime, String userName,
|
||||
Integer pageNo, Integer pageSize);
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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.service.impl;
|
||||
|
||||
import org.apache.dolphinscheduler.api.audit.AuditMessage;
|
||||
import org.apache.dolphinscheduler.api.audit.AuditPublishService;
|
||||
import org.apache.dolphinscheduler.api.dto.AuditDto;
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.service.AuditService;
|
||||
import org.apache.dolphinscheduler.api.utils.PageInfo;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.Constants;
|
||||
import org.apache.dolphinscheduler.common.enums.AuditOperationType;
|
||||
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
|
||||
import org.apache.dolphinscheduler.dao.entity.AuditLog;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.mapper.AuditLogMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
@Service
|
||||
public class AuditServiceImpl extends BaseServiceImpl implements AuditService {
|
||||
|
||||
@Autowired
|
||||
private AuditLogMapper auditLogMapper;
|
||||
|
||||
@Autowired
|
||||
private AuditPublishService publishService;
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return audit log string data
|
||||
*/
|
||||
@Override
|
||||
public Result queryLogListPaging(User loginUser, AuditResourceType resourceType,
|
||||
AuditOperationType operationType, String startDate,
|
||||
String endDate, String userName,
|
||||
Integer pageNo, Integer pageSize) {
|
||||
Result result = new Result();
|
||||
|
||||
Map<String, Object> checkAndParseDateResult = checkAndParseDateParameters(startDate, endDate);
|
||||
Status resultEnum = (Status) checkAndParseDateResult.get(Constants.STATUS);
|
||||
if (resultEnum != Status.SUCCESS) {
|
||||
putMsg(result,resultEnum);
|
||||
return result;
|
||||
}
|
||||
|
||||
int[] resourceArray = null;
|
||||
if (resourceType != null) {
|
||||
resourceArray = new int[]{resourceType.getCode()};
|
||||
}
|
||||
|
||||
int[] opsArray = null;
|
||||
if (operationType != null) {
|
||||
opsArray = new int[]{operationType.getCode()};
|
||||
}
|
||||
|
||||
Date start = (Date) checkAndParseDateResult.get(Constants.START_TIME);
|
||||
Date end = (Date) checkAndParseDateResult.get(Constants.END_TIME);
|
||||
|
||||
Page<AuditLog> page = new Page<>(pageNo, pageSize);
|
||||
IPage<AuditLog> logIPage = auditLogMapper.queryAuditLog(page, resourceArray, opsArray, userName, start, end);
|
||||
List<AuditLog> logList = logIPage != null ? logIPage.getRecords() : new ArrayList<>();
|
||||
PageInfo<AuditDto> pageInfo = new PageInfo<>(pageNo, pageSize);
|
||||
|
||||
List<AuditDto> auditDtos = logList.stream().map(this::transformAuditLog).collect(Collectors.toList());
|
||||
pageInfo.setTotal((int) (auditDtos != null ? auditDtos.size() : 0L));
|
||||
pageInfo.setTotalList(auditDtos);
|
||||
result.setData(pageInfo);
|
||||
putMsg(result, Status.SUCCESS);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* transform AuditLog to AuditDto
|
||||
*
|
||||
* @param auditLog audit log
|
||||
* @return audit dto
|
||||
*/
|
||||
private AuditDto transformAuditLog(AuditLog auditLog) {
|
||||
AuditDto auditDto = new AuditDto();
|
||||
String resourceType = AuditResourceType.of(auditLog.getResourceType()).getMsg();
|
||||
auditDto.setResource(resourceType);
|
||||
auditDto.setOperation(AuditOperationType.of(auditLog.getOperation()).getMsg());
|
||||
auditDto.setUserName(auditLog.getUserName());
|
||||
auditDto.setResourceName(auditLogMapper.queryResourceNameByType(resourceType, auditLog.getResourceId()));
|
||||
auditDto.setTime(auditLog.getTime());
|
||||
return auditDto;
|
||||
}
|
||||
}
|
||||
|
|
@ -101,6 +101,9 @@ registry:
|
|||
block-until-connected: 600ms
|
||||
digest: ~
|
||||
|
||||
audit:
|
||||
enabled: false
|
||||
|
||||
# Override by profile
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -282,3 +282,6 @@ DELETE_PROCESS_DEFINITION_VERSION_NOTES=delete process definition version
|
|||
QUERY_PROCESS_DEFINITION_VERSIONS_NOTES=query process definition versions
|
||||
SWITCH_PROCESS_DEFINITION_VERSION_NOTES=switch process definition version
|
||||
VERSION=version
|
||||
AUDIT_LOG_TAG=audit log related operation
|
||||
MODULE_TYPE=module type
|
||||
OPERATION_TYPE=operation type
|
||||
|
|
|
|||
|
|
@ -340,3 +340,7 @@ SWITCH_PROCESS_DEFINITION_VERSION_NOTES=switch process definition version
|
|||
VERSION=version
|
||||
TASK_GROUP_QUEUEID=task group queue id
|
||||
TASK_GROUP_QUEUE_PRIORITY=task group queue priority
|
||||
QUERY_AUDIT_LOG=query audit log
|
||||
AUDIT_LOG_TAG=audit log related operation
|
||||
MODULE_TYPE=module type
|
||||
OPERATION_TYPE=operation type
|
||||
|
|
@ -336,3 +336,7 @@ SWITCH_PROCESS_DEFINITION_VERSION_NOTES=切换流程版本
|
|||
VERSION=版本号
|
||||
TASK_GROUP_QUEUEID=任务组队列id
|
||||
TASK_GROUP_QUEUE_PRIORITY=任务队列优先级
|
||||
QUERY_AUDIT_LOG=查询审计日志
|
||||
AUDIT_LOG_TAG=审计日志执行相关操作
|
||||
MODULE_TYPE=模块类型
|
||||
OPERATION_TYPE=操作类型
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.common.enums.AuditOperationType;
|
||||
import org.apache.dolphinscheduler.common.enums.AuditResourceType;
|
||||
import org.apache.dolphinscheduler.dao.entity.AuditLog;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.mapper.AuditLogMapper;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AuditSubscriberTest {
|
||||
|
||||
@Mock
|
||||
private AuditLogMapper logMapper;
|
||||
|
||||
@InjectMocks
|
||||
private AuditSubscriberImpl auditSubscriber;
|
||||
|
||||
@Test
|
||||
public void testExecute() {
|
||||
Mockito.when(logMapper.insert(Mockito.any(AuditLog.class))).thenReturn(1);
|
||||
auditSubscriber.execute(new AuditMessage(new User(), new Date(), AuditResourceType.USER_MODULE, AuditOperationType.CREATE, 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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.configuration;
|
||||
|
||||
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.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@ActiveProfiles("audit")
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = AuditConfiguration.class)
|
||||
public class AuditConfigurationTest {
|
||||
|
||||
@Autowired
|
||||
private AuditConfiguration auditConfiguration;
|
||||
|
||||
@Test
|
||||
public void isAuditGlobalControlSwitch() {
|
||||
Assert.assertTrue(auditConfiguration.getEnabled());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.controller;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.utils.JSONUtils;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
/**
|
||||
* audit log controller test
|
||||
*/
|
||||
public class AuditLogControllerTest extends AbstractControllerTest {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(AuditLogControllerTest.class);
|
||||
|
||||
@Test
|
||||
public void testQueryAuditLogListPaging() throws Exception {
|
||||
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
|
||||
paramsMap.add("pageNo", "1");
|
||||
paramsMap.add("pageSize", "10");
|
||||
|
||||
MvcResult mvcResult = mockMvc.perform(get("/projects/audit/audit-log-list")
|
||||
.header(SESSION_ID, sessionId)
|
||||
.params(paramsMap))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||
.andReturn();
|
||||
|
||||
Result result = JSONUtils.parseObject(mvcResult.getResponse().getContentAsString(), Result.class);
|
||||
Assert.assertEquals(Status.SUCCESS.getCode(),result.getCode().intValue());
|
||||
logger.info(mvcResult.getResponse().getContentAsString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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.service;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.apache.dolphinscheduler.api.enums.Status;
|
||||
import org.apache.dolphinscheduler.api.service.impl.AuditServiceImpl;
|
||||
import org.apache.dolphinscheduler.api.utils.Result;
|
||||
import org.apache.dolphinscheduler.common.utils.DateUtils;
|
||||
import org.apache.dolphinscheduler.dao.entity.AuditLog;
|
||||
import org.apache.dolphinscheduler.dao.entity.User;
|
||||
import org.apache.dolphinscheduler.dao.mapper.AuditLogMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
/**
|
||||
* audit service test
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AuditServiceTest {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuditServiceTest.class);
|
||||
|
||||
@InjectMocks
|
||||
private AuditServiceImpl auditService;
|
||||
|
||||
@Mock
|
||||
private AuditLogMapper auditLogMapper;
|
||||
|
||||
@Test
|
||||
public void testQueryLogListPaging() {
|
||||
Date start = DateUtils.getScheduleDate("2020-11-01 00:00:00");
|
||||
Date end = DateUtils.getScheduleDate("2020-11-02 00:00:00");
|
||||
|
||||
IPage<AuditLog> page = new Page<>(1, 10);
|
||||
page.setRecords(getLists());
|
||||
page.setTotal(1L);
|
||||
when(auditLogMapper.queryAuditLog(Mockito.any(Page.class), Mockito.any(), Mockito.any(),
|
||||
Mockito.eq(""), eq(start), eq(end)))
|
||||
.thenReturn(page);
|
||||
Result result = auditService.queryLogListPaging(new User(), null, null, "2020-11-01 00:00:00", "2020-11-02 00:00:00", "", 1, 10);
|
||||
logger.info(result.toString());
|
||||
Assert.assertEquals(Status.SUCCESS.getCode(), (int) result.getCode());
|
||||
}
|
||||
|
||||
private List<AuditLog> getLists() {
|
||||
List<AuditLog> list = new ArrayList<>();
|
||||
list.add(getAuditLog());
|
||||
return list;
|
||||
}
|
||||
|
||||
private AuditLog getAuditLog() {
|
||||
AuditLog auditLog = new AuditLog();
|
||||
auditLog.setUserName("testName");
|
||||
auditLog.setOperation(0);
|
||||
auditLog.setResourceType(0);
|
||||
return auditLog;
|
||||
}
|
||||
}
|
||||
|
|
@ -26,3 +26,6 @@ spring:
|
|||
|
||||
registry:
|
||||
type: zookeeper
|
||||
|
||||
audit:
|
||||
enabled: true
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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.common.enums;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Audit Operation type
|
||||
*/
|
||||
public enum AuditOperationType {
|
||||
|
||||
CREATE(0, "CREATE"),
|
||||
READ(1, "READ"),
|
||||
UPDATE(2, "UPDATE"),
|
||||
DELETE(3, "DELETE");
|
||||
|
||||
private final int code;
|
||||
private final String enMsg;
|
||||
|
||||
private static HashMap<Integer, AuditOperationType> AUDIT_OPERATION_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (AuditOperationType operationType : AuditOperationType.values()) {
|
||||
AUDIT_OPERATION_MAP.put(operationType.code, operationType);
|
||||
}
|
||||
}
|
||||
|
||||
AuditOperationType(int code, String enMsg) {
|
||||
this.code = code;
|
||||
this.enMsg = enMsg;
|
||||
}
|
||||
|
||||
public static AuditOperationType of(int status) {
|
||||
if (AUDIT_OPERATION_MAP.containsKey(status)) {
|
||||
return AUDIT_OPERATION_MAP.get(status);
|
||||
}
|
||||
throw new IllegalArgumentException("invalid audit operation type code " + status);
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return enMsg;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.common.enums;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Audit Module type
|
||||
*/
|
||||
public enum AuditResourceType {
|
||||
// TODO: add other audit resource enums
|
||||
USER_MODULE(0, "USER"),
|
||||
PROJECT_MODULE(1, "PROJECT");
|
||||
|
||||
private final int code;
|
||||
private final String enMsg;
|
||||
|
||||
private static HashMap<Integer, AuditResourceType> AUDIT_RESOURCE_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (AuditResourceType auditResourceType : AuditResourceType.values()) {
|
||||
AUDIT_RESOURCE_MAP.put(auditResourceType.code, auditResourceType);
|
||||
}
|
||||
}
|
||||
|
||||
AuditResourceType(int code, String enMsg) {
|
||||
this.code = code;
|
||||
this.enMsg = enMsg;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return this.enMsg;
|
||||
}
|
||||
|
||||
public static AuditResourceType of(int status) {
|
||||
if (AUDIT_RESOURCE_MAP.containsKey(status)) {
|
||||
return AUDIT_RESOURCE_MAP.get(status);
|
||||
}
|
||||
throw new IllegalArgumentException("invalid audit resource type code " + status);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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.dao.entity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
@TableName("t_ds_audit_log")
|
||||
public class AuditLog {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private int id;
|
||||
|
||||
/**
|
||||
* user id
|
||||
*/
|
||||
private Integer userId;
|
||||
|
||||
/**
|
||||
* resource type
|
||||
*/
|
||||
private Integer resourceType;
|
||||
|
||||
/**
|
||||
* operation type
|
||||
*/
|
||||
private Integer operation;
|
||||
|
||||
/**
|
||||
* resource id
|
||||
*/
|
||||
private Integer resourceId;
|
||||
|
||||
/**
|
||||
* user name
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* operation time
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
|
||||
private Date time;
|
||||
|
||||
public Integer getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(Integer userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Integer getResourceType() {
|
||||
return resourceType;
|
||||
}
|
||||
|
||||
public void setResourceType(Integer resourceType) {
|
||||
this.resourceType = resourceType;
|
||||
}
|
||||
|
||||
public Integer getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(Integer operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public Integer getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(Integer resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public void setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
}
|
||||
|
||||
public Date getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Date time) {
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.dao.mapper;
|
||||
|
||||
import org.apache.dolphinscheduler.dao.entity.AuditLog;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
|
||||
/**
|
||||
* auditlog mapper interface
|
||||
*/
|
||||
public interface AuditLogMapper extends BaseMapper<AuditLog> {
|
||||
IPage<AuditLog> queryAuditLog(IPage<AuditLog> page,
|
||||
@Param("resourceType") int[] resourceArray,
|
||||
@Param("operationType") int[] operationType,
|
||||
@Param("userName") String userName,
|
||||
@Param("startDate") Date startDate,
|
||||
@Param("endDate") Date endDate);
|
||||
|
||||
String queryResourceNameByType(@Param("resourceType") String resourceType,
|
||||
@Param("resourceId") Integer resourceId);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<!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.AuditLogMapper">
|
||||
<sql id="baseSql">
|
||||
id, user_id, resource_type, operation, resource_id, time
|
||||
</sql>
|
||||
<sql id="baseSqlV2">
|
||||
${alias}.id, ${alias}.user_id, ${alias}.resource_type, ${alias}.operation, ${alias}.resource_id, ${alias}.time
|
||||
</sql>
|
||||
|
||||
<select id="queryAuditLog" resultType="org.apache.dolphinscheduler.dao.entity.AuditLog">
|
||||
select
|
||||
<include refid="baseSqlV2">
|
||||
<property name="alias" value="log"/>
|
||||
</include>
|
||||
,
|
||||
u.user_name as user_name
|
||||
from t_ds_audit_log log
|
||||
join t_ds_user u on log.user_id = u.id
|
||||
where 1 = 1
|
||||
<if test="startDate != null">
|
||||
and log.time > #{startDate} and log.time <![CDATA[ <=]]> #{endDate}
|
||||
</if>
|
||||
<if test="resourceType != null and resourceType.length > 0">
|
||||
and log.resource_type in
|
||||
<foreach collection="resourceType" index="index" item="i" open="(" separator="," close=")">
|
||||
#{i}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="operationType != null and operationType.length > 0">
|
||||
and log.operation in
|
||||
<foreach collection="operationType" index="index" item="j" open="(" separator="," close=")">
|
||||
#{j}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="userName != null and userName != ''">
|
||||
and u.user_name = #{userName}
|
||||
</if>
|
||||
order by log.time desc
|
||||
</select>
|
||||
|
||||
<select id="queryResourceNameByType" resultType="String">
|
||||
<if test="resourceType != null and resourceType == 'USER'">
|
||||
select user_name from t_ds_user where id = #{resourceId}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -1078,3 +1078,18 @@ CREATE TABLE t_ds_task_group
|
|||
update_time datetime DEFAULT NULL ,
|
||||
PRIMARY KEY(id)
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_alert_plugin_instance
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS t_ds_audit_log;
|
||||
CREATE TABLE t_ds_audit_log
|
||||
(
|
||||
id int(11) NOT NULL AUTO_INCREMENT,
|
||||
user_id int(11) NOT NULL,
|
||||
resource_type int(11) NOT NULL,
|
||||
operation int(11) NOT NULL,
|
||||
time timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
resource_id int(11) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
|
@ -1063,3 +1063,17 @@ CREATE TABLE `t_ds_task_group` (
|
|||
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY(`id`)
|
||||
) ENGINE= INNODB AUTO_INCREMENT= 1 DEFAULT CHARSET= utf8;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_audit_log
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `t_ds_audit_log`;
|
||||
CREATE TABLE `t_ds_audit_log` (
|
||||
`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT'key',
|
||||
`user_id` int(11) NOT NULL COMMENT 'user id',
|
||||
`resource_type` int(11) NOT NULL COMMENT 'resource type',
|
||||
`operation` int(11) NOT NULL COMMENT 'operation',
|
||||
`time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT 'create time',
|
||||
`resource_id` int(11) NULL DEFAULT NULL COMMENT 'resource id',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT= 1 DEFAULT CHARSET=utf8;
|
||||
|
|
@ -1062,3 +1062,17 @@ CREATE TABLE t_ds_task_group (
|
|||
update_time timestamp DEFAULT NULL ,
|
||||
PRIMARY KEY(id)
|
||||
);
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_audit_log
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS t_ds_audit_log;
|
||||
CREATE TABLE t_ds_audit_log (
|
||||
id serial NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
resource_type int NOT NULL,
|
||||
operation int NOT NULL,
|
||||
time timestamp DEFAULT NULL ,
|
||||
resource_id int NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
|
@ -368,6 +368,20 @@ CREATE TABLE `t_ds_worker_group` (
|
|||
UNIQUE KEY `name_unique` (`name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for t_ds_audit_log
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `t_ds_audit_log`;
|
||||
CREATE TABLE `t_ds_audit_log` (
|
||||
`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT'key',
|
||||
`user_id` int(11) NOT NULL COMMENT 'user id',
|
||||
`resource_type` int(11) NOT NULL COMMENT 'resource type',
|
||||
`operation` int(11) NOT NULL COMMENT 'operation',
|
||||
`time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT 'create time',
|
||||
`resource_id` int(11) NULL DEFAULT NULL COMMENT 'resource id',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT= 1 DEFAULT CHARSET=utf8;
|
||||
|
||||
-- t_ds_command
|
||||
alter table t_ds_command change process_definition_id process_definition_code bigint(20) NOT NULL COMMENT 'process definition code';
|
||||
alter table t_ds_command add environment_code bigint(20) DEFAULT '-1' COMMENT 'environment code' AFTER worker_group;
|
||||
|
|
|
|||
|
|
@ -318,6 +318,16 @@ BEGIN
|
|||
CONSTRAINT name_unique UNIQUE (name)
|
||||
)';
|
||||
|
||||
EXECUTE 'CREATE TABLE IF NOT EXISTS '|| quote_ident(v_schema) ||'."t_ds_audit_log" (
|
||||
id serial NOT NULL,
|
||||
user_id int NOT NULL,
|
||||
resource_type int NOT NULL,
|
||||
operation int NOT NULL,
|
||||
time timestamp DEFAULT NULL ,
|
||||
resource_id int NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
)';
|
||||
|
||||
return 'Success!';
|
||||
exception when others then
|
||||
---Raise EXCEPTION '(%)',SQLERRM;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.dao.mapper;
|
||||
|
||||
import org.apache.dolphinscheduler.dao.BaseDaoTest;
|
||||
import org.apache.dolphinscheduler.dao.entity.AuditLog;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
public class AuditLogMapperTest extends BaseDaoTest {
|
||||
|
||||
@Autowired
|
||||
AuditLogMapper logMapper;
|
||||
|
||||
/**
|
||||
* insert
|
||||
* @return
|
||||
*/
|
||||
private void insertOne() {
|
||||
AuditLog auditLog = new AuditLog();
|
||||
auditLog.setUserId(1);
|
||||
auditLog.setTime(new Date());
|
||||
auditLog.setResourceType(0);
|
||||
auditLog.setOperation(0);
|
||||
auditLog.setResourceId(0);
|
||||
logMapper.insert(auditLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* test page query
|
||||
*/
|
||||
@Test
|
||||
public void testQueryAuditLog() {
|
||||
insertOne();
|
||||
Page<AuditLog> page = new Page<>(1, 3);
|
||||
int[] resourceType = new int[0];
|
||||
int[] operationType = new int[0];
|
||||
|
||||
IPage<AuditLog> logIPage = logMapper.queryAuditLog(page, resourceType, operationType, "", null, null);
|
||||
Assert.assertNotEquals(logIPage.getTotal(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryResourceNameByType() {
|
||||
String resourceName = logMapper.queryResourceNameByType("USER", 1);
|
||||
Assert.assertEquals("admin", resourceName);
|
||||
}
|
||||
}
|
||||
|
|
@ -159,6 +159,9 @@ management:
|
|||
tags:
|
||||
application: ${spring.application.name}
|
||||
|
||||
audit:
|
||||
enabled: true
|
||||
|
||||
# Override by profile
|
||||
---
|
||||
spring:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
<template>
|
||||
<m-conditions>
|
||||
<template slot="search-group">
|
||||
<div class="list">
|
||||
<el-button size="mini" @click="_ckQuery" icon="el-icon-search"></el-button>
|
||||
</div>
|
||||
<div class="list">
|
||||
<el-date-picker
|
||||
style="width: 310px"
|
||||
v-model="dataTime"
|
||||
size="mini"
|
||||
@change="_onChangeStartStop"
|
||||
type="datetimerange"
|
||||
range-separator="-"
|
||||
:start-placeholder="$t('startDate')"
|
||||
:end-placeholder="$t('endDate')"
|
||||
value-format="yyyy-MM-dd HH:mm:ss">
|
||||
</el-date-picker>
|
||||
</div>
|
||||
<div class="list">
|
||||
<el-select style="width: 140px;" @change="_onChangeResource" :value="searchParams.resourceType" :placeholder="$t('Resource Type')" size="mini">
|
||||
<el-option
|
||||
v-for="module in resourceTypeList"
|
||||
:key="module.label"
|
||||
:value="module.code"
|
||||
:label="module.label">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="list">
|
||||
<el-select style="width: 140px;" @change="_onChangeOperation" :value="searchParams.operationType" :placeholder="$t('Operation')" size="mini">
|
||||
<el-option
|
||||
v-for="operation in operationTypeList"
|
||||
:key="operation.label"
|
||||
:value="operation.code"
|
||||
:label="operation.label">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="list">
|
||||
<el-input v-model="searchParams.userName" @keyup.enter.native="_ckQuery" style="width: 140px;" size="mini" :placeholder="$t('User Name')"></el-input>
|
||||
</div>
|
||||
</template>
|
||||
</m-conditions>
|
||||
</template>
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import { resourceType, operationType } from './common'
|
||||
import mConditions from '@/module/components/conditions/conditions'
|
||||
export default {
|
||||
name: 'monitor-log-conditions',
|
||||
data () {
|
||||
return {
|
||||
// state(list)
|
||||
resourceTypeList: resourceType,
|
||||
operationTypeList: operationType,
|
||||
searchParams: {
|
||||
// resource type
|
||||
resourceType: '',
|
||||
// operation
|
||||
operationType: '',
|
||||
// start date
|
||||
startDate: '',
|
||||
// end date
|
||||
endDate: ''
|
||||
},
|
||||
dataTime: []
|
||||
}
|
||||
},
|
||||
props: {},
|
||||
methods: {
|
||||
_ckQuery () {
|
||||
this.$emit('on-query', this.searchParams)
|
||||
},
|
||||
/**
|
||||
* change times
|
||||
*/
|
||||
_onChangeStartStop (val) {
|
||||
this.searchParams.startDate = val[0]
|
||||
this.searchParams.endDate = val[1]
|
||||
this.dataTime[0] = val[0]
|
||||
this.dataTime[1] = val[1]
|
||||
},
|
||||
/**
|
||||
* change resource
|
||||
*/
|
||||
_onChangeResource (val) {
|
||||
this.searchParams.resourceType = val
|
||||
},
|
||||
/**
|
||||
* change operation
|
||||
*/
|
||||
_onChangeOperation (val) {
|
||||
this.searchParams.operationType = val
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
},
|
||||
created () {
|
||||
// Routing parameter merging
|
||||
if (!_.isEmpty(this.$route.query)) {
|
||||
this.searchParams = _.assign(this.searchParams, this.$route.query)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
components: { mConditions }
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import i18n from '@/module/i18n'
|
||||
|
||||
/**
|
||||
* Module code table
|
||||
*/
|
||||
const resourceType = [
|
||||
{
|
||||
code: '',
|
||||
label: `${i18n.$t('Resource Type')}`
|
||||
}, {
|
||||
code: 'USER_MODULE',
|
||||
label: `${i18n.$t('User Audit')}`
|
||||
}, {
|
||||
code: 'PROJECT_MODULE',
|
||||
label: `${i18n.$t('Project Audit')}`
|
||||
}
|
||||
]
|
||||
|
||||
/**
|
||||
* Operation code table
|
||||
*/
|
||||
const operationType = [
|
||||
{
|
||||
code: '',
|
||||
label: `${i18n.$t('All Operations')}`
|
||||
}, {
|
||||
code: 'CREATE',
|
||||
label: `${i18n.$t('Create Operation')}`
|
||||
}, {
|
||||
code: 'UPDATE',
|
||||
label: `${i18n.$t('Update Operation')}`
|
||||
}, {
|
||||
code: 'DELETE',
|
||||
label: `${i18n.$t('Delete Operation')}`
|
||||
}, {
|
||||
code: 'READ',
|
||||
label: `${i18n.$t('Read Operation')}`
|
||||
}
|
||||
]
|
||||
|
||||
export {
|
||||
resourceType, operationType
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
<template>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'monitor-conditions-index'
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
<template>
|
||||
<div class="list-model">
|
||||
<div class="table-box">
|
||||
<el-table :data="list" size="mini" style="width: 100%">
|
||||
<el-table-column type="index" :label="$t('#')" width="50"></el-table-column>
|
||||
<el-table-column prop="userName" :label="$t('User Name')"></el-table-column>
|
||||
<el-table-column prop="resource" :label="$t('Resource Type')"></el-table-column>
|
||||
<el-table-column prop="resourceName" :label="$t('Project Name')"></el-table-column>
|
||||
<el-table-column prop="operation" :label="$t('Operation')">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.operation | filterNull}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('Create Time')" min-width="120">
|
||||
<template slot-scope="scope">
|
||||
<span>{{scope.row.time | formatDate}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'audit-list',
|
||||
data () {
|
||||
return {
|
||||
list: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
logList: Array,
|
||||
pageNo: Number,
|
||||
pageSize: Number
|
||||
},
|
||||
methods: {
|
||||
_edit (item) {
|
||||
this.$emit('on-edit', item)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
logList (a) {
|
||||
this.list = []
|
||||
setTimeout(() => {
|
||||
this.list = a
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.list = this.logList
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
components: { }
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
<template>
|
||||
<m-list-construction :title="$t('Audit Log')">
|
||||
<template slot="conditions">
|
||||
<m-log-conditions @on-query="_onQuery"></m-log-conditions>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<template v-if="logList.length || total>0">
|
||||
<m-list @on-edit="_onEdit"
|
||||
:log-list="logList"
|
||||
:page-no="searchParams.pageNo"
|
||||
:page-size="searchParams.pageSize">
|
||||
</m-list>
|
||||
<div class="page-box">
|
||||
<el-pagination
|
||||
background
|
||||
@current-change="_page"
|
||||
@size-change="_pageSize"
|
||||
:page-size="searchParams.pageSize"
|
||||
:current-page.sync="searchParams.pageNo"
|
||||
:page-sizes="[10, 30, 50]"
|
||||
layout="sizes, prev, pager, next, jumper"
|
||||
:total="total">
|
||||
</el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="!logList.length && total<=0">
|
||||
<m-no-data></m-no-data>
|
||||
</template>
|
||||
<m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
|
||||
</template>
|
||||
</m-list-construction>
|
||||
</template>
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import { mapActions } from 'vuex'
|
||||
import mList from './_source/list'
|
||||
import store from '@/conf/home/store'
|
||||
import mSpin from '@/module/components/spin/spin'
|
||||
import mNoData from '@/module/components/noData/noData'
|
||||
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
|
||||
import mListConstruction from '@/module/components/listConstruction/listConstruction'
|
||||
import mLogConditions from '@/conf/home/pages/monitor/pages/_source/conditions/audit/auditLog'
|
||||
|
||||
export default {
|
||||
name: 'audit-log-index',
|
||||
data () {
|
||||
return {
|
||||
total: null,
|
||||
isLoading: true,
|
||||
logList: [],
|
||||
searchParams: {
|
||||
pageSize: 10,
|
||||
pageNo: 1,
|
||||
// resource type
|
||||
resourceType: '',
|
||||
// operation
|
||||
operationType: '',
|
||||
// start date
|
||||
startDate: '',
|
||||
// end date
|
||||
endDate: '',
|
||||
// operator
|
||||
userName: ''
|
||||
},
|
||||
isLeft: true,
|
||||
// isEffective: 1,
|
||||
isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER',
|
||||
item: {}
|
||||
}
|
||||
},
|
||||
mixins: [listUrlParamHandle],
|
||||
props: {},
|
||||
methods: {
|
||||
...mapActions('projects', ['getAuditLogList']),
|
||||
/**
|
||||
* click query
|
||||
*/
|
||||
_onQuery (o) {
|
||||
this.searchParams = _.assign(this.searchParams, o)
|
||||
this.searchParams.pageNo = 1
|
||||
},
|
||||
_page (val) {
|
||||
this.searchParams.pageNo = val
|
||||
},
|
||||
_pageSize (val) {
|
||||
this.searchParams.pageSize = val
|
||||
},
|
||||
_onUpdate () {
|
||||
this._debounceGET()
|
||||
},
|
||||
close () {
|
||||
},
|
||||
_getList (flag) {
|
||||
this.isLoading = !flag
|
||||
this.getAuditLogList(this.searchParams).then(res => {
|
||||
if (this.searchParams.pageNo > 1 && res.totalList.length === 0) {
|
||||
this.searchParams.pageNo = this.searchParams.pageNo - 1
|
||||
} else {
|
||||
this.logList = []
|
||||
this.logList = res.totalList
|
||||
this.total = res.total
|
||||
this.isLoading = false
|
||||
}
|
||||
}).catch(e => {
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
_debounceGET: _.debounce(function (flag) {
|
||||
if (Number(sessionStorage.getItem('isLeft')) === 0) {
|
||||
this.isLeft = false
|
||||
} else {
|
||||
this.isLeft = true
|
||||
}
|
||||
this._getList(flag)
|
||||
}, 100, {
|
||||
leading: false,
|
||||
trailing: true
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
// router
|
||||
'$route' (a) {
|
||||
// url no params get instance list
|
||||
this.searchParams.pageNo = _.isEmpty(a.query) ? 1 : a.query.pageNo
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
mounted () {
|
||||
// Cycle acquisition status
|
||||
this.setIntervalP = setInterval(() => {
|
||||
this._debounceGET('false')
|
||||
}, 90000)
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval(this.setIntervalP)
|
||||
sessionStorage.setItem('isLeft', 1)
|
||||
},
|
||||
components: { mList, mListConstruction, mSpin, mNoData, mLogConditions }
|
||||
}
|
||||
</script>
|
||||
|
|
@ -92,6 +92,15 @@ const monitor = [
|
|||
title: 'statistics',
|
||||
refreshInSwitchedTab: config.refreshInSwitchedTab
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/monitor/audit/log',
|
||||
name: 'audit-log',
|
||||
component: resolve => require(['../../pages/monitor/pages/log/index'], resolve),
|
||||
meta: {
|
||||
title: 'audit-log',
|
||||
refreshInSwitchedTab: config.refreshInSwitchedTab
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,5 +137,17 @@ export default {
|
|||
reject(e)
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* Get audit log list
|
||||
*/
|
||||
getAuditLogList ({ state }, payload) {
|
||||
return new Promise((resolve, reject) => {
|
||||
io.get('projects/audit/audit-log-list', payload, res => {
|
||||
resolve(res.data)
|
||||
}).catch(e => {
|
||||
reject(e)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -298,6 +298,12 @@ const menu = {
|
|||
path: 'statistics',
|
||||
id: 0,
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
name: 'Audit Log',
|
||||
path: 'audit-log',
|
||||
id: 1,
|
||||
enabled: true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -802,6 +802,17 @@ export default {
|
|||
'Priority not empty': 'The value of priority can not be empty',
|
||||
'Priority must be number': 'The value of priority should be number',
|
||||
'Please select task name': 'Please select a task name',
|
||||
'Audit Log': 'Audit Log',
|
||||
'Resource Type': 'resource type',
|
||||
'All Types': 'all types',
|
||||
'All Modules': 'all modules',
|
||||
'All Operations': 'all operations',
|
||||
'User Audit': 'user management audit',
|
||||
'Project Audit': 'project management audit',
|
||||
'Create Operation': 'create',
|
||||
'Update Operation': 'update',
|
||||
'Delete Operation': 'delete',
|
||||
'Read Operation': 'read',
|
||||
'Process State': 'Process State',
|
||||
'Upstream Tasks': 'Upstream Tasks',
|
||||
'and {n} more': '… and {n} more',
|
||||
|
|
|
|||
|
|
@ -804,6 +804,16 @@ export default {
|
|||
'Priority not empty': '优先级不能为空',
|
||||
'Priority must be number': '优先级必须是数值',
|
||||
'Please select task name': '请选择节点名称',
|
||||
'Audit Log': '审计日志',
|
||||
'Resource Type': '资源类型',
|
||||
'All Types': '所有类型',
|
||||
'All Operations': '所有操作',
|
||||
'User Audit': '用户管理审计',
|
||||
'Project Audit': '项目管理审计',
|
||||
'Create Operation': '创建',
|
||||
'Update Operation': '更新',
|
||||
'Delete Operation': '删除',
|
||||
'Read Operation': '读取',
|
||||
'Process State': '工作流状态',
|
||||
'Upstream Tasks': '上游任务',
|
||||
'and {n} more': '…等{n}个',
|
||||
|
|
|
|||
Loading…
Reference in New Issue