Commit a5656009d2e6bd83f00d4e84a46f456548d0e95a

Authored by YevhenBondarenko
Committed by Andrew Shvayka
1 parent ce24a87b

implemented audit logs for the firmware and resource

... ... @@ -75,7 +75,6 @@ import javax.annotation.Nullable;
75 75 import java.io.IOException;
76 76 import java.util.ArrayList;
77 77 import java.util.List;
78   -import java.util.Objects;
79 78 import java.util.stream.Collectors;
80 79
81 80 import static org.thingsboard.server.controller.EdgeController.EDGE_ID;
... ... @@ -120,12 +119,12 @@ public class DeviceController extends BaseController {
120 119 @ResponseBody
121 120 public Device saveDevice(@RequestBody Device device,
122 121 @RequestParam(name = "accessToken", required = false) String accessToken) throws ThingsboardException {
  122 + boolean created = device.getId() == null;
123 123 try {
124 124 device.setTenantId(getCurrentUser().getTenantId());
125 125
126 126 checkEntity(device.getId(), device, Resource.DEVICE);
127 127
128   - boolean created = device.getId() == null;
129 128 Device oldDevice;
130 129 if (!created) {
131 130 oldDevice = deviceService.findDeviceById(getTenantId(), device.getId());
... ... @@ -146,7 +145,7 @@ public class DeviceController extends BaseController {
146 145
147 146 logEntityAction(savedDevice.getId(), savedDevice,
148 147 savedDevice.getCustomerId(),
149   - device.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
  148 + created ? ActionType.ADDED : ActionType.UPDATED, null);
150 149
151 150 if (device.getId() == null) {
152 151 deviceStateService.onDeviceAdded(savedDevice);
... ... @@ -157,10 +156,9 @@ public class DeviceController extends BaseController {
157 156 firmwareStateService.update(savedDevice, oldDevice);
158 157
159 158 return savedDevice;
160   - } catch (
161   - Exception e) {
  159 + } catch (Exception e) {
162 160 logEntityAction(emptyId(EntityType.DEVICE), device,
163   - null, device.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e);
  161 + null, created ? ActionType.ADDED : ActionType.UPDATED, e);
164 162 throw handleException(e);
165 163 }
166 164
... ...
... ... @@ -30,8 +30,10 @@ import org.springframework.web.bind.annotation.RequestParam;
30 30 import org.springframework.web.bind.annotation.ResponseBody;
31 31 import org.springframework.web.bind.annotation.RestController;
32 32 import org.springframework.web.multipart.MultipartFile;
  33 +import org.thingsboard.server.common.data.EntityType;
33 34 import org.thingsboard.server.common.data.Firmware;
34 35 import org.thingsboard.server.common.data.FirmwareInfo;
  36 +import org.thingsboard.server.common.data.audit.ActionType;
35 37 import org.thingsboard.server.common.data.exception.ThingsboardException;
36 38 import org.thingsboard.server.common.data.id.FirmwareId;
37 39 import org.thingsboard.server.common.data.page.PageData;
... ... @@ -101,11 +103,17 @@ public class FirmwareController extends BaseController {
101 103 @RequestMapping(value = "/firmware", method = RequestMethod.POST)
102 104 @ResponseBody
103 105 public FirmwareInfo saveFirmwareInfo(@RequestBody FirmwareInfo firmwareInfo) throws ThingsboardException {
104   - firmwareInfo.setTenantId(getTenantId());
105   - checkEntity(firmwareInfo.getId(), firmwareInfo, Resource.FIRMWARE);
  106 + boolean created = firmwareInfo.getId() == null;
106 107 try {
107   - return firmwareService.saveFirmwareInfo(firmwareInfo);
  108 + firmwareInfo.setTenantId(getTenantId());
  109 + checkEntity(firmwareInfo.getId(), firmwareInfo, Resource.FIRMWARE);
  110 + FirmwareInfo savedFirmwareInfo = firmwareService.saveFirmwareInfo(firmwareInfo);
  111 + logEntityAction(savedFirmwareInfo.getId(), savedFirmwareInfo,
  112 + null, created ? ActionType.ADDED : ActionType.UPDATED, null);
  113 + return savedFirmwareInfo;
108 114 } catch (Exception e) {
  115 + logEntityAction(emptyId(EntityType.FIRMWARE), firmwareInfo,
  116 + null, created ? ActionType.ADDED : ActionType.UPDATED, e);
109 117 throw handleException(e);
110 118 }
111 119 }
... ... @@ -141,8 +149,11 @@ public class FirmwareController extends BaseController {
141 149 firmware.setContentType(file.getContentType());
142 150 firmware.setData(ByteBuffer.wrap(data));
143 151 firmware.setDataSize((long) data.length);
144   - return firmwareService.saveFirmware(firmware);
  152 + Firmware savedFirmware = firmwareService.saveFirmware(firmware);
  153 + logEntityAction(savedFirmware.getId(), savedFirmware, null, ActionType.UPDATED, null);
  154 + return savedFirmware;
145 155 } catch (Exception e) {
  156 + logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.UPDATED, e, strFirmwareId);
146 157 throw handleException(e);
147 158 }
148 159 }
... ... @@ -183,13 +194,15 @@ public class FirmwareController extends BaseController {
183 194 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')")
184 195 @RequestMapping(value = "/firmware/{firmwareId}", method = RequestMethod.DELETE)
185 196 @ResponseBody
186   - public void deleteResource(@PathVariable("firmwareId") String strFirmwareId) throws ThingsboardException {
  197 + public void deleteFirmware(@PathVariable("firmwareId") String strFirmwareId) throws ThingsboardException {
187 198 checkParameter(FIRMWARE_ID, strFirmwareId);
188 199 try {
189 200 FirmwareId firmwareId = new FirmwareId(toUUID(strFirmwareId));
190   - checkFirmwareInfoId(firmwareId, Operation.DELETE);
  201 + FirmwareInfo info = checkFirmwareInfoId(firmwareId, Operation.DELETE);
191 202 firmwareService.deleteFirmware(getTenantId(), firmwareId);
  203 + logEntityAction(firmwareId, info, null, ActionType.DELETED, null, strFirmwareId);
192 204 } catch (Exception e) {
  205 + logEntityAction(emptyId(EntityType.FIRMWARE), null, null, ActionType.DELETED, e, strFirmwareId);
193 206 throw handleException(e);
194 207 }
195 208 }
... ...
... ... @@ -28,8 +28,10 @@ import org.springframework.web.bind.annotation.RequestMethod;
28 28 import org.springframework.web.bind.annotation.RequestParam;
29 29 import org.springframework.web.bind.annotation.ResponseBody;
30 30 import org.springframework.web.bind.annotation.RestController;
  31 +import org.thingsboard.server.common.data.EntityType;
31 32 import org.thingsboard.server.common.data.TbResource;
32 33 import org.thingsboard.server.common.data.TbResourceInfo;
  34 +import org.thingsboard.server.common.data.audit.ActionType;
33 35 import org.thingsboard.server.common.data.exception.ThingsboardException;
34 36 import org.thingsboard.server.common.data.id.TbResourceId;
35 37 import org.thingsboard.server.common.data.lwm2m.LwM2mObject;
... ... @@ -37,7 +39,6 @@ import org.thingsboard.server.common.data.page.PageData;
37 39 import org.thingsboard.server.common.data.page.PageLink;
38 40 import org.thingsboard.server.common.data.security.Authority;
39 41 import org.thingsboard.server.queue.util.TbCoreComponent;
40   -import org.thingsboard.server.service.resource.TbResourceService;
41 42 import org.thingsboard.server.service.security.permission.Operation;
42 43 import org.thingsboard.server.service.security.permission.Resource;
43 44
... ... @@ -103,12 +104,18 @@ public class TbResourceController extends BaseController {
103 104 @RequestMapping(value = "/resource", method = RequestMethod.POST)
104 105 @ResponseBody
105 106 public TbResource saveResource(@RequestBody TbResource resource) throws ThingsboardException {
  107 + boolean created = resource.getId() == null;
106 108 try {
107   - resource.setTenantId(getTenantId());
108   - checkEntity(resource.getId(), resource, Resource.TB_RESOURCE);
109   - return addResource(resource);
110   - }
111   - catch (Exception e) {
  109 + resource.setTenantId(getTenantId());
  110 + checkEntity(resource.getId(), resource, Resource.TB_RESOURCE);
  111 + TbResource savedResource = checkNotNull(resourceService.saveResource(resource));
  112 + tbClusterService.onResourceChange(savedResource, null);
  113 + logEntityAction(savedResource.getId(), savedResource,
  114 + null, created ? ActionType.ADDED : ActionType.UPDATED, null);
  115 + return savedResource;
  116 + } catch (Exception e) {
  117 + logEntityAction(emptyId(EntityType.TB_RESOURCE), resource,
  118 + null, created ? ActionType.ADDED : ActionType.UPDATED, e);
112 119 throw handleException(e);
113 120 }
114 121 }
... ... @@ -172,15 +179,11 @@ public class TbResourceController extends BaseController {
172 179 TbResource tbResource = checkResourceId(resourceId, Operation.DELETE);
173 180 resourceService.deleteResource(getTenantId(), resourceId);
174 181 tbClusterService.onResourceDeleted(tbResource, null);
  182 + logEntityAction(resourceId, tbResource, null, ActionType.DELETED, null, strResourceId);
175 183 } catch (Exception e) {
  184 + logEntityAction(emptyId(EntityType.TB_RESOURCE), null, null, ActionType.DELETED, e, strResourceId);
176 185 throw handleException(e);
177 186 }
178 187 }
179 188
180   - private TbResource addResource(TbResource resource) throws Exception {
181   - checkEntity(resource.getId(), resource, Resource.TB_RESOURCE);
182   - TbResource savedResource = checkNotNull(resourceService.saveResource(resource));
183   - tbClusterService.onResourceChange(savedResource, null);
184   - return savedResource;
185   - }
186 189 }
\ No newline at end of file
... ...
... ... @@ -496,6 +496,8 @@ audit-log:
496 496 "entity_view": "${AUDIT_LOG_MASK_ENTITY_VIEW:W}"
497 497 "device_profile": "${AUDIT_LOG_MASK_DEVICE_PROFILE:W}"
498 498 "edge": "${AUDIT_LOG_MASK_EDGE:W}"
  499 + "tb_resource": "${AUDIT_LOG_MASK_RESOURCE:W}"
  500 + "firmware": "${AUDIT_LOG_MASK_FIRMWARE:W}"
499 501 sink:
500 502 # Type of external sink. possible options: none, elasticsearch
501 503 type: "${AUDIT_LOG_SINK_TYPE:none}"
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.dao.firmware;
17 17
  18 +import com.google.common.util.concurrent.ListenableFuture;
18 19 import org.thingsboard.server.common.data.Firmware;
19 20 import org.thingsboard.server.common.data.FirmwareInfo;
20 21 import org.thingsboard.server.common.data.id.FirmwareId;
... ... @@ -32,6 +33,8 @@ public interface FirmwareService {
32 33
33 34 FirmwareInfo findFirmwareInfoById(TenantId tenantId, FirmwareId firmwareId);
34 35
  36 + ListenableFuture<FirmwareInfo> findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId);
  37 +
35 38 PageData<FirmwareInfo> findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink);
36 39
37 40 PageData<FirmwareInfo> findTenantFirmwaresByTenantIdAndHasData(TenantId tenantId, boolean hasData, PageLink pageLink);
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.dao.resource;
17 17
  18 +import com.google.common.util.concurrent.ListenableFuture;
18 19 import org.thingsboard.server.common.data.ResourceType;
19 20 import org.thingsboard.server.common.data.TbResource;
20 21 import org.thingsboard.server.common.data.TbResourceInfo;
... ... @@ -34,6 +35,8 @@ public interface ResourceService {
34 35
35 36 TbResourceInfo findResourceInfoById(TenantId tenantId, TbResourceId resourceId);
36 37
  38 + ListenableFuture<TbResourceInfo> findResourceInfoByIdAsync(TenantId tenantId, TbResourceId resourceId);
  39 +
37 40 PageData<TbResourceInfo> findAllTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink);
38 41
39 42 PageData<TbResourceInfo> findTenantResourcesByTenantId(TenantId tenantId, PageLink pageLink);
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import com.fasterxml.jackson.annotation.JsonIgnore;
18 19 import lombok.Data;
19 20 import lombok.EqualsAndHashCode;
20 21 import lombok.extern.slf4j.Slf4j;
... ... @@ -24,7 +25,7 @@ import org.thingsboard.server.common.data.id.TenantId;
24 25 @Slf4j
25 26 @Data
26 27 @EqualsAndHashCode(callSuper = true)
27   -public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId> implements HasTenantId {
  28 +public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId> implements HasName, HasTenantId {
28 29
29 30 private static final long serialVersionUID = 3168391583570815419L;
30 31
... ... @@ -64,4 +65,10 @@ public class FirmwareInfo extends SearchTextBasedWithAdditionalInfo<FirmwareId>
64 65 public String getSearchText() {
65 66 return title;
66 67 }
  68 +
  69 + @Override
  70 + @JsonIgnore
  71 + public String getName() {
  72 + return title;
  73 + }
67 74 }
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.common.data;
17 17
  18 +import com.fasterxml.jackson.annotation.JsonIgnore;
18 19 import lombok.Data;
19 20 import lombok.EqualsAndHashCode;
20 21 import lombok.extern.slf4j.Slf4j;
... ... @@ -25,7 +26,7 @@ import org.thingsboard.server.common.data.validation.NoXss;
25 26 @Slf4j
26 27 @Data
27 28 @EqualsAndHashCode(callSuper = true)
28   -public class TbResourceInfo extends SearchTextBased<TbResourceId> implements HasTenantId {
  29 +public class TbResourceInfo extends SearchTextBased<TbResourceId> implements HasName, HasTenantId {
29 30
30 31 private static final long serialVersionUID = 7282664529021651736L;
31 32
... ... @@ -54,6 +55,12 @@ public class TbResourceInfo extends SearchTextBased<TbResourceId> implements Has
54 55 }
55 56
56 57 @Override
  58 + @JsonIgnore
  59 + public String getName() {
  60 + return title;
  61 + }
  62 +
  63 + @Override
57 64 public String getSearchText() {
58 65 return searchText != null ? searchText : title;
59 66 }
... ...
... ... @@ -31,7 +31,9 @@ import org.thingsboard.server.common.data.id.DeviceId;
31 31 import org.thingsboard.server.common.data.id.EdgeId;
32 32 import org.thingsboard.server.common.data.id.EntityId;
33 33 import org.thingsboard.server.common.data.id.EntityViewId;
  34 +import org.thingsboard.server.common.data.id.FirmwareId;
34 35 import org.thingsboard.server.common.data.id.RuleChainId;
  36 +import org.thingsboard.server.common.data.id.TbResourceId;
35 37 import org.thingsboard.server.common.data.id.TenantId;
36 38 import org.thingsboard.server.common.data.id.UserId;
37 39 import org.thingsboard.server.common.data.page.PageData;
... ... @@ -46,6 +48,8 @@ import org.thingsboard.server.dao.dashboard.DashboardService;
46 48 import org.thingsboard.server.dao.device.DeviceService;
47 49 import org.thingsboard.server.dao.entityview.EntityViewService;
48 50 import org.thingsboard.server.dao.exception.IncorrectParameterException;
  51 +import org.thingsboard.server.dao.firmware.FirmwareService;
  52 +import org.thingsboard.server.dao.resource.ResourceService;
49 53 import org.thingsboard.server.dao.rule.RuleChainService;
50 54 import org.thingsboard.server.dao.tenant.TenantService;
51 55 import org.thingsboard.server.dao.user.UserService;
... ... @@ -92,6 +96,12 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
92 96 @Autowired
93 97 private EntityQueryDao entityQueryDao;
94 98
  99 + @Autowired
  100 + private ResourceService resourceService;
  101 +
  102 + @Autowired
  103 + private FirmwareService firmwareService;
  104 +
95 105 @Override
96 106 public void deleteEntityRelations(TenantId tenantId, EntityId entityId) {
97 107 super.deleteEntityRelations(tenantId, entityId);
... ... @@ -152,6 +162,12 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
152 162 case EDGE:
153 163 hasName = edgeService.findEdgeByIdAsync(tenantId, new EdgeId(entityId.getId()));
154 164 break;
  165 + case TB_RESOURCE:
  166 + hasName = resourceService.findResourceInfoByIdAsync(tenantId, new TbResourceId(entityId.getId()));
  167 + break;
  168 + case FIRMWARE:
  169 + hasName = firmwareService.findFirmwareInfoByIdAsync(tenantId, new FirmwareId(entityId.getId()));
  170 + break;
155 171 default:
156 172 throw new IllegalStateException("Not Implemented!");
157 173 }
... ... @@ -178,9 +194,9 @@ public class BaseEntityService extends AbstractEntityService implements EntitySe
178 194 if (pageLink == null) {
179 195 throw new IncorrectParameterException("Entity Data Page link must be specified.");
180 196 } else if (pageLink.getPageSize() < 1) {
181   - throw new IncorrectParameterException("Incorrect entity data page link page size '"+pageLink.getPageSize()+"'. Page size must be greater than zero.");
  197 + throw new IncorrectParameterException("Incorrect entity data page link page size '" + pageLink.getPageSize() + "'. Page size must be greater than zero.");
182 198 } else if (pageLink.getPage() < 0) {
183   - throw new IncorrectParameterException("Incorrect entity data page link page '"+pageLink.getPage()+"'. Page must be positive integer.");
  199 + throw new IncorrectParameterException("Incorrect entity data page link page '" + pageLink.getPage() + "'. Page must be positive integer.");
184 200 }
185 201 }
186 202
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.firmware;
17 17
18 18 import com.google.common.hash.HashFunction;
19 19 import com.google.common.hash.Hashing;
  20 +import com.google.common.util.concurrent.ListenableFuture;
20 21 import lombok.extern.slf4j.Slf4j;
21 22 import org.apache.commons.lang3.StringUtils;
22 23 import org.hibernate.exception.ConstraintViolationException;
... ... @@ -116,6 +117,12 @@ public class BaseFirmwareService implements FirmwareService {
116 117 }
117 118
118 119 @Override
  120 + public ListenableFuture<FirmwareInfo> findFirmwareInfoByIdAsync(TenantId tenantId, FirmwareId firmwareId) {
  121 + log.trace("Executing findFirmwareInfoByIdAsync [{}]", firmwareId);
  122 + validateId(firmwareId, INCORRECT_FIRMWARE_ID + firmwareId);
  123 + return firmwareInfoDao.findByIdAsync(tenantId, firmwareId.getId()); }
  124 +
  125 + @Override
119 126 public PageData<FirmwareInfo> findTenantFirmwaresByTenantId(TenantId tenantId, PageLink pageLink) {
120 127 log.trace("Executing findTenantFirmwaresByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink);
121 128 validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
... ...
... ... @@ -15,6 +15,7 @@
15 15 */
16 16 package org.thingsboard.server.dao.resource;
17 17
  18 +import com.google.common.util.concurrent.ListenableFuture;
18 19 import lombok.extern.slf4j.Slf4j;
19 20 import org.apache.commons.lang3.StringUtils;
20 21 import org.hibernate.exception.ConstraintViolationException;
... ... @@ -94,6 +95,13 @@ public class BaseResourceService implements ResourceService {
94 95 }
95 96
96 97 @Override
  98 + public ListenableFuture<TbResourceInfo> findResourceInfoByIdAsync(TenantId tenantId, TbResourceId resourceId) {
  99 + log.trace("Executing findResourceInfoById [{}] [{}]", tenantId, resourceId);
  100 + Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId);
  101 + return resourceInfoDao.findByIdAsync(tenantId, resourceId.getId());
  102 + }
  103 +
  104 + @Override
97 105 public void deleteResource(TenantId tenantId, TbResourceId resourceId) {
98 106 log.trace("Executing deleteResource [{}] [{}]", tenantId, resourceId);
99 107 Validator.validateId(resourceId, INCORRECT_RESOURCE_ID + resourceId);
... ...
... ... @@ -287,6 +287,7 @@ export const entityTypeTranslations = new Map<EntityType | AliasEntityType, Enti
287 287 [
288 288 EntityType.TB_RESOURCE,
289 289 {
  290 + type: 'entity.type-tb-resource',
290 291 details: 'resource.resource-library-details',
291 292 add: 'resource.add',
292 293 noEntities: 'resource.no-resource-text',
... ... @@ -297,6 +298,7 @@ export const entityTypeTranslations = new Map<EntityType | AliasEntityType, Enti
297 298 [
298 299 EntityType.FIRMWARE,
299 300 {
  301 + type: 'entity.type-firmware',
300 302 details: 'firmware.firmware-details',
301 303 add: 'firmware.add',
302 304 noEntities: 'firmware.no-firmware-text',
... ...
... ... @@ -1493,7 +1493,9 @@
1493 1493 "type-edge": "Edge",
1494 1494 "type-edges": "Edges",
1495 1495 "list-of-edges": "{ count, plural, 1 {One edge} other {List of # edges} }",
1496   - "edge-name-starts-with": "Edges whose names start with '{{prefix}}'"
  1496 + "edge-name-starts-with": "Edges whose names start with '{{prefix}}'",
  1497 + "type-tb-resource": "Resource",
  1498 + "type-firmware": "Firmware"
1497 1499 },
1498 1500 "entity-field": {
1499 1501 "created-time": "Created time",
... ...