From a5656009d2e6bd83f00d4e84a46f456548d0e95a Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Tue, 27 Apr 2021 11:47:38 +0300 Subject: [PATCH] implemented audit logs for the firmware and resource --- .../server/controller/DeviceController.java | 10 +++---- .../server/controller/FirmwareController.java | 25 ++++++++++++----- .../controller/TbResourceController.java | 27 ++++++++++--------- .../src/main/resources/thingsboard.yml | 2 ++ .../server/dao/firmware/FirmwareService.java | 3 +++ .../server/dao/resource/ResourceService.java | 3 +++ .../server/common/data/FirmwareInfo.java | 9 ++++++- .../server/common/data/TbResourceInfo.java | 9 ++++++- .../server/dao/entity/BaseEntityService.java | 20 ++++++++++++-- .../dao/firmware/BaseFirmwareService.java | 7 +++++ .../dao/resource/BaseResourceService.java | 8 ++++++ .../app/shared/models/entity-type.models.ts | 2 ++ .../assets/locale/locale.constant-en_US.json | 4 ++- 13 files changed, 100 insertions(+), 29 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index 43bce339dc..378083b873 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -75,7 +75,6 @@ import javax.annotation.Nullable; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.stream.Collectors; import static org.thingsboard.server.controller.EdgeController.EDGE_ID; @@ -120,12 +119,12 @@ public class DeviceController extends BaseController { @ResponseBody public Device saveDevice(@RequestBody Device device, @RequestParam(name = "accessToken", required = false) String accessToken) throws ThingsboardException { + boolean created = device.getId() == null; try { device.setTenantId(getCurrentUser().getTenantId()); checkEntity(device.getId(), device, Resource.DEVICE); - boolean created = device.getId() == null; Device oldDevice; if (!created) { oldDevice = deviceService.findDeviceById(getTenantId(), device.getId()); @@ -146,7 +145,7 @@ public class DeviceController extends BaseController { logEntityAction(savedDevice.getId(), savedDevice, savedDevice.getCustomerId(), - device.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); + created ? ActionType.ADDED : ActionType.UPDATED, null); if (device.getId() == null) { deviceStateService.onDeviceAdded(savedDevice); @@ -157,10 +156,9 @@ public class DeviceController extends BaseController { firmwareStateService.update(savedDevice, oldDevice); return savedDevice; - } catch ( - Exception e) { + } catch (Exception e) { logEntityAction(emptyId(EntityType.DEVICE), device, - null, device.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e); + null, created ? ActionType.ADDED : ActionType.UPDATED, e); throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java index c8f10b3d78..a3c067a046 100644 --- a/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java +++ b/application/src/main/java/org/thingsboard/server/controller/FirmwareController.java @@ -30,8 +30,10 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.FirmwareInfo; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.FirmwareId; import org.thingsboard.server.common.data.page.PageData; @@ -101,11 +103,17 @@ public class FirmwareController extends BaseController { @RequestMapping(value = "/firmware", method = RequestMethod.POST) @ResponseBody public FirmwareInfo saveFirmwareInfo(@RequestBody FirmwareInfo firmwareInfo) throws ThingsboardException { - firmwareInfo.setTenantId(getTenantId()); - checkEntity(firmwareInfo.getId(), firmwareInfo, Resource.FIRMWARE); + boolean created = firmwareInfo.getId() == null; try { - return firmwareService.saveFirmwareInfo(firmwareInfo); + firmwareInfo.setTenantId(getTenantId()); + checkEntity(firmwareInfo.getId(), firmwareInfo, Resource.FIRMWARE); + FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo); + logEntityAction(savedFirmwareInfo.getId(), savedFirmwareInfo, + null, created ? ActionType.ADDED : ActionType.UPDATED, null); + return savedFirmwareInfo; } catch (Exception e) { + logEntityAction(emptyId(EntityType.FIRMWARE), firmwareInfo, + null, created ? ActionType.ADDED : ActionType.UPDATED, e); throw handleException(e); } } @@ -141,8 +149,11 @@ public class FirmwareController extends BaseController { firmware.setContentType(file.getContentType()); firmware.setData(ByteBuffer.wrap(data)); firmware.setDataSize((long) data.length); - return firmwareService.saveFirmware(firmware); + Firmware savedFirmware = firmwareService.saveFirmware(firmware); + logEntityAction(savedFirmware.getId(), savedFirmware, null, ActionType.UPDATED, null); + return savedFirmware; } catch (Exception e) { + logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.UPDATED, e, strFirmwareId); throw handleException(e); } } @@ -183,13 +194,15 @@ public class FirmwareController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.DELETE) @ResponseBody - public void deleteResource(@PathVariable("firmwareId") String strFirmwareId) throws ThingsboardException { + public void deleteFirmware(@PathVariable("firmwareId") String strFirmwareId) throws ThingsboardException { checkParameter(FIRMWARE_ID, strFirmwareId); try { FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId)); - checkFirmwareInfoId(firmwareId, Operation.DELETE); + FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.DELETE); firmwareService.deleteFirmware(getTenantId(), firmwareId); + logEntityAction(firmwareId, info, null, ActionType.DELETED, null, strFirmwareId); } catch (Exception e) { + logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.DELETED, e, strFirmwareId); throw handleException(e); } } diff --git a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java index b24cf0e76e..97020ca85d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/TbResourceController.java @@ -28,8 +28,10 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.lwm2m.LwM2mObject; @@ -37,7 +39,6 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.queue.util.TbCoreComponent; -import org.thingsboard.server.service.resource.TbResourceService; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; @@ -103,12 +104,18 @@ public class TbResourceController extends BaseController { @RequestMapping(value = "/resource", method = RequestMethod.POST) @ResponseBody public TbResource saveResource(@RequestBody TbResource resource) throws ThingsboardException { + boolean created = resource.getId() == null; try { - resource.setTenantId(getTenantId()); - checkEntity(resource.getId(), resource, Resource.TB_RESOURCE); - return addResource(resource); - } - catch (Exception e) { + resource.setTenantId(getTenantId()); + checkEntity(resource.getId(), resource, Resource.TB_RESOURCE); + TbResource savedResource = checkNotNull(resourceService.saveResource(resource)); + tbClusterService.onResourceChange(savedResource, null); + logEntityAction(savedResource.getId(), savedResource, + null, created ? ActionType.ADDED : ActionType.UPDATED, null); + return savedResource; + } catch (Exception e) { + logEntityAction(emptyId(EntityType.TB_RESOURCE), resource, + null, created ? ActionType.ADDED : ActionType.UPDATED, e); throw handleException(e); } } @@ -172,15 +179,11 @@ public class TbResourceController extends BaseController { TbResource tbResource = checkResourceId(resourceId, Operation.DELETE); resourceService.deleteResource(getTenantId(), resourceId); tbClusterService.onResourceDeleted(tbResource, null); + logEntityAction(resourceId, tbResource, null, ActionType.DELETED, null, strResourceId); } catch (Exception e) { + logEntityAction(emptyId(EntityType.TB_RESOURCE), null, null, ActionType.DELETED, e, strResourceId); throw handleException(e); } } - private TbResource addResource(TbResource resource) throws Exception { - checkEntity(resource.getId(), resource, Resource.TB_RESOURCE); - TbResource savedResource = checkNotNull(resourceService.saveResource(resource)); - tbClusterService.onResourceChange(savedResource, null); - return savedResource; - } } \ No newline at end of file diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 270a18e065..e8e1fb15f4 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -496,6 +496,8 @@ audit-log: "entity_view": "${AUDIT_LOG_MASK_ENTITY_VIEW:W}" "device_profile": "${AUDIT_LOG_MASK_DEVICE_PROFILE:W}" "edge": "${AUDIT_LOG_MASK_EDGE:W}" + "tb_resource": "${AUDIT_LOG_MASK_RESOURCE:W}" + "firmware": "${AUDIT_LOG_MASK_FIRMWARE:W}" sink: # Type of external sink. possible options: none, elasticsearch type: "${AUDIT_LOG_SINK_TYPE:none}" diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java index 0fd26fee6e..907638eabb 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/firmware/FirmwareService.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.firmware; +import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.Firmware; import org.thingsboard.server.common.data.FirmwareInfo; import org.thingsboard.server.common.data.id.FirmwareId; @@ -32,6 +33,8 @@ public interface FirmwareService { FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId); + ListenableFuture findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId); + PageData findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink); PageData findTenantFirmwaresByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink); diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java index 68c2c1f5f0..802628ff2c 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/resource/ResourceService.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.resource; +import com.google.common.util.concurrent.ListenableFuture; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TbResourceInfo; @@ -34,6 +35,8 @@ public interface ResourceService { TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId); + ListenableFuture findResourceInfoByIdAsync(TenantId tenantId, TbResourceId resourceId); + PageData findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); PageData findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java index 3a26763c4f..c9941e29bd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/FirmwareInfo.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.common.data; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -24,7 +25,7 @@ import org.thingsboard.server.common.data.id.TenantId; @Slf4j @Data @EqualsAndHashCode(callSuper = true) -public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo implements HasTenantId { +public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo implements HasName, HasTenantId { private static final long serialVersionUID = 3168391583570815419L; @@ -64,4 +65,10 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo public String getSearchText() { return title; } + + @Override + @JsonIgnore + public String getName() { + return title; + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java index 95fbcd46ff..9d72d01534 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/TbResourceInfo.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.common.data; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; @@ -25,7 +26,7 @@ import org.thingsboard.server.common.data.validation.NoXss; @Slf4j @Data @EqualsAndHashCode(callSuper = true) -public class TbResourceInfo extends SearchTextBased implements HasTenantId { +public class TbResourceInfo extends SearchTextBased implements HasName, HasTenantId { private static final long serialVersionUID = 7282664529021651736L; @@ -53,6 +54,12 @@ public class TbResourceInfo extends SearchTextBased implements Has this.searchText = resourceInfo.getSearchText(); } + @Override + @JsonIgnore + public String getName() { + return title; + } + @Override public String getSearchText() { return searchText != null ? searchText : title; diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java index 5dc9cf4eed..7e0218740a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/BaseEntityService.java @@ -31,7 +31,9 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityViewId; +import org.thingsboard.server.common.data.id.FirmwareId; import org.thingsboard.server.common.data.id.RuleChainId; +import org.thingsboard.server.common.data.id.TbResourceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; @@ -46,6 +48,8 @@ import org.thingsboard.server.dao.dashboard.DashboardService; import org.thingsboard.server.dao.device.DeviceService; import org.thingsboard.server.dao.entityview.EntityViewService; import org.thingsboard.server.dao.exception.IncorrectParameterException; +import org.thingsboard.server.dao.firmware.FirmwareService; +import org.thingsboard.server.dao.resource.ResourceService; import org.thingsboard.server.dao.rule.RuleChainService; import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.user.UserService; @@ -92,6 +96,12 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe @Autowired private EntityQueryDao entityQueryDao; + @Autowired + private ResourceService resourceService; + + @Autowired + private FirmwareService firmwareService; + @Override public void deleteEntityRelations(TenantId tenantId, EntityId entityId) { super.deleteEntityRelations(tenantId, entityId); @@ -152,6 +162,12 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe case EDGE: hasName = edgeService.findEdgeByIdAsync(tenantId, new EdgeId(entityId.getId())); break; + case TB_RESOURCE: + hasName = resourceService.findResourceInfoByIdAsync(tenantId, new TbResourceId(entityId.getId())); + break; + case FIRMWARE: + hasName = firmwareService.findFirmwareInfoByIdAsync(tenantId, new FirmwareId(entityId.getId())); + break; default: throw new IllegalStateException("Not Implemented!"); } @@ -178,9 +194,9 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe if (pageLink == null) { throw new IncorrectParameterException("Entity Data Page link must be specified."); } else if (pageLink.getPageSize() < 1) { - throw new IncorrectParameterException("Incorrect entity data page link page size '"+pageLink.getPageSize()+"'. Page size must be greater than zero."); + throw new IncorrectParameterException("Incorrect entity data page link page size '" + pageLink.getPageSize() + "'. Page size must be greater than zero."); } else if (pageLink.getPage() < 0) { - throw new IncorrectParameterException("Incorrect entity data page link page '"+pageLink.getPage()+"'. Page must be positive integer."); + throw new IncorrectParameterException("Incorrect entity data page link page '" + pageLink.getPage() + "'. Page must be positive integer."); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java b/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java index 5a80fc75f6..d504845488 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/firmware/BaseFirmwareService.java @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.firmware; import com.google.common.hash.HashFunction; import com.google.common.hash.Hashing; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.hibernate.exception.ConstraintViolationException; @@ -115,6 +116,12 @@ public class BaseFirmwareService implements FirmwareService { return firmwareInfoDao.findById(tenantId, firmwareId.getId()); } + @Override + public ListenableFuture findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId) { + log.trace("Executing findFirmwareInfoByIdAsync [{}]", firmwareId); + validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId); + return firmwareInfoDao.findByIdAsync(tenantId, firmwareId.getId()); } + @Override public PageData findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink) { log.trace("Executing findTenantFirmwaresByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink); diff --git a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java index 97675d4b3e..6dacd1357f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/resource/BaseResourceService.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.resource; +import com.google.common.util.concurrent.ListenableFuture; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.hibernate.exception.ConstraintViolationException; @@ -93,6 +94,13 @@ public class BaseResourceService implements ResourceService { return resourceInfoDao.findById(tenantId, resourceId.getId()); } + @Override + public ListenableFuture findResourceInfoByIdAsync(TenantId tenantId, TbResourceId resourceId) { + log.trace("Executing findResourceInfoById [{}] [{}]", tenantId, resourceId); + Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId); + return resourceInfoDao.findByIdAsync(tenantId, resourceId.getId()); + } + @Override public void deleteResource(TenantId tenantId, TbResourceId resourceId) { log.trace("Executing deleteResource [{}] [{}]", tenantId, resourceId); diff --git a/ui-ngx/src/app/shared/models/entity-type.models.ts b/ui-ngx/src/app/shared/models/entity-type.models.ts index 892d2a1244..ae2382e0ea 100644 --- a/ui-ngx/src/app/shared/models/entity-type.models.ts +++ b/ui-ngx/src/app/shared/models/entity-type.models.ts @@ -287,6 +287,7 @@ export const entityTypeTranslations = new Map