Commit 8db68202569b3d91643a2ad90123b5f6e538bf86

Authored by Andrew Shvayka
1 parent 1cad3497

Audit Log improvements

... ... @@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestParam;
26 26 import org.springframework.web.bind.annotation.ResponseBody;
27 27 import org.springframework.web.bind.annotation.ResponseStatus;
28 28 import org.springframework.web.bind.annotation.RestController;
  29 +import org.thingsboard.server.common.data.EntityType;
29 30 import org.thingsboard.server.common.data.alarm.Alarm;
30 31 import org.thingsboard.server.common.data.alarm.AlarmId;
31 32 import org.thingsboard.server.common.data.alarm.AlarmInfo;
... ... @@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.alarm.AlarmQuery;
33 34 import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
34 35 import org.thingsboard.server.common.data.alarm.AlarmSeverity;
35 36 import org.thingsboard.server.common.data.alarm.AlarmStatus;
  37 +import org.thingsboard.server.common.data.audit.ActionType;
36 38 import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
37 39 import org.thingsboard.server.common.data.exception.ThingsboardException;
38 40 import org.thingsboard.server.common.data.id.EntityId;
... ... @@ -53,7 +55,6 @@ public class AlarmController extends BaseController {
53 55 checkParameter(ALARM_ID, strAlarmId);
54 56 try {
55 57 AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
56   -
57 58 return checkAlarmId(alarmId);
58 59 } catch (Exception e) {
59 60 throw handleException(e);
... ... @@ -79,8 +80,14 @@ public class AlarmController extends BaseController {
79 80 public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException {
80 81 try {
81 82 alarm.setTenantId(getCurrentUser().getTenantId());
82   - return checkNotNull(alarmService.createOrUpdateAlarm(alarm));
  83 + Alarm savedAlarm = checkNotNull(alarmService.createOrUpdateAlarm(alarm));
  84 + logEntityAction(savedAlarm.getId(), savedAlarm,
  85 + getCurrentUser().getCustomerId(),
  86 + savedAlarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
  87 + return savedAlarm;
83 88 } catch (Exception e) {
  89 + logEntityAction(emptyId(EntityType.ASSET), alarm,
  90 + null, alarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e);
84 91 throw handleException(e);
85 92 }
86 93 }
... ... @@ -92,8 +99,9 @@ public class AlarmController extends BaseController {
92 99 checkParameter(ALARM_ID, strAlarmId);
93 100 try {
94 101 AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
95   - checkAlarmId(alarmId);
  102 + Alarm alarm = checkAlarmId(alarmId);
96 103 alarmService.ackAlarm(alarmId, System.currentTimeMillis()).get();
  104 + logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null);
97 105 } catch (Exception e) {
98 106 throw handleException(e);
99 107 }
... ... @@ -106,8 +114,9 @@ public class AlarmController extends BaseController {
106 114 checkParameter(ALARM_ID, strAlarmId);
107 115 try {
108 116 AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
109   - checkAlarmId(alarmId);
  117 + Alarm alarm = checkAlarmId(alarmId);
110 118 alarmService.clearAlarm(alarmId, null, System.currentTimeMillis()).get();
  119 + logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null);
111 120 } catch (Exception e) {
112 121 throw handleException(e);
113 122 }
... ...
... ... @@ -529,18 +529,16 @@ public abstract class BaseController {
529 529 return baseUrl;
530 530 }
531 531
532   - protected <I extends UUIDBased & EntityId> I emptyId(EntityType entityType) {
  532 + protected <I extends EntityId> I emptyId(EntityType entityType) {
533 533 return (I)EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
534 534 }
535 535
536   - protected <E extends BaseData<I> & HasName,
537   - I extends UUIDBased & EntityId> void logEntityAction(I entityId, E entity, CustomerId customerId,
  536 + protected <E extends HasName, I extends EntityId> void logEntityAction(I entityId, E entity, CustomerId customerId,
538 537 ActionType actionType, Exception e, Object... additionalInfo) throws ThingsboardException {
539 538 logEntityAction(getCurrentUser(), entityId, entity, customerId, actionType, e, additionalInfo);
540 539 }
541 540
542   - protected <E extends BaseData<I> & HasName,
543   - I extends UUIDBased & EntityId> void logEntityAction(User user, I entityId, E entity, CustomerId customerId,
  541 + protected <E extends HasName, I extends EntityId> void logEntityAction(User user, I entityId, E entity, CustomerId customerId,
544 542 ActionType actionType, Exception e, Object... additionalInfo) throws ThingsboardException {
545 543 if (customerId == null || customerId.isNullUid()) {
546 544 customerId = user.getCustomerId();
... ... @@ -556,8 +554,7 @@ public abstract class BaseController {
556 554 return error != null ? (Exception.class.isInstance(error) ? (Exception) error : new Exception(error)) : null;
557 555 }
558 556
559   - private <E extends BaseData<I> & HasName,
560   - I extends UUIDBased & EntityId> void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId,
  557 + private <E extends HasName, I extends EntityId> void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId,
561 558 ActionType actionType, Object... additionalInfo) {
562 559 String msgType = null;
563 560 switch (actionType) {
... ...
... ... @@ -24,10 +24,13 @@ import org.springframework.web.bind.annotation.RequestParam;
24 24 import org.springframework.web.bind.annotation.ResponseBody;
25 25 import org.springframework.web.bind.annotation.ResponseStatus;
26 26 import org.springframework.web.bind.annotation.RestController;
  27 +import org.thingsboard.server.common.data.alarm.Alarm;
  28 +import org.thingsboard.server.common.data.audit.ActionType;
27 29 import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
28 30 import org.thingsboard.server.common.data.exception.ThingsboardException;
29 31 import org.thingsboard.server.common.data.id.EntityId;
30 32 import org.thingsboard.server.common.data.id.EntityIdFactory;
  33 +import org.thingsboard.server.common.data.id.UUIDBased;
31 34 import org.thingsboard.server.common.data.relation.EntityRelation;
32 35 import org.thingsboard.server.common.data.relation.EntityRelationInfo;
33 36 import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
... ... @@ -58,7 +61,15 @@ public class EntityRelationController extends BaseController {
58 61 relation.setTypeGroup(RelationTypeGroup.COMMON);
59 62 }
60 63 relationService.saveRelation(relation);
  64 + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
  65 + ActionType.RELATION_ADD_OR_UPDATE, null, relation);
  66 + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
  67 + ActionType.RELATION_ADD_OR_UPDATE, null, relation);
61 68 } catch (Exception e) {
  69 + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
  70 + ActionType.RELATION_ADD_OR_UPDATE, e, relation);
  71 + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
  72 + ActionType.RELATION_ADD_OR_UPDATE, e, relation);
62 73 throw handleException(e);
63 74 }
64 75 }
... ... @@ -81,12 +92,21 @@ public class EntityRelationController extends BaseController {
81 92 checkEntityId(fromId);
82 93 checkEntityId(toId);
83 94 RelationTypeGroup relationTypeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
  95 + EntityRelation relation = new EntityRelation(fromId, toId, strRelationType, relationTypeGroup);
84 96 try {
85 97 Boolean found = relationService.deleteRelation(fromId, toId, strRelationType, relationTypeGroup);
86 98 if (!found) {
87 99 throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND);
88 100 }
  101 + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
  102 + ActionType.RELATION_DELETED, null, relation);
  103 + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
  104 + ActionType.RELATION_DELETED, null, relation);
89 105 } catch (Exception e) {
  106 + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
  107 + ActionType.RELATION_DELETED, e, relation);
  108 + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
  109 + ActionType.RELATION_DELETED, e, relation);
90 110 throw handleException(e);
91 111 }
92 112 }
... ... @@ -102,7 +122,9 @@ public class EntityRelationController extends BaseController {
102 122 checkEntityId(entityId);
103 123 try {
104 124 relationService.deleteEntityRelations(entityId);
  125 + logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, null);
105 126 } catch (Exception e) {
  127 + logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, e);
106 128 throw handleException(e);
107 129 }
108 130 }
... ... @@ -210,8 +232,8 @@ public class EntityRelationController extends BaseController {
210 232 @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE})
211 233 @ResponseBody
212 234 public List<EntityRelationInfo> findInfoByTo(@RequestParam(TO_ID) String strToId,
213   - @RequestParam(TO_TYPE) String strToType,
214   - @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
  235 + @RequestParam(TO_TYPE) String strToType,
  236 + @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
215 237 checkParameter(TO_ID, strToId);
216 238 checkParameter(TO_TYPE, strToType);
217 239 EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId);
... ... @@ -276,10 +298,11 @@ public class EntityRelationController extends BaseController {
276 298
277 299 private RelationTypeGroup parseRelationTypeGroup(String strRelationTypeGroup, RelationTypeGroup defaultValue) {
278 300 RelationTypeGroup result = defaultValue;
279   - if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length()>0) {
  301 + if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length() > 0) {
280 302 try {
281 303 result = RelationTypeGroup.valueOf(strRelationTypeGroup);
282   - } catch (IllegalArgumentException e) { }
  304 + } catch (IllegalArgumentException e) {
  305 + }
283 306 }
284 307 return result;
285 308 }
... ...
... ... @@ -385,6 +385,7 @@ audit_log:
385 385 "customer": "${AUDIT_LOG_MASK_CUSTOMER:W}"
386 386 "user": "${AUDIT_LOG_MASK_USER:W}"
387 387 "rule_chain": "${AUDIT_LOG_MASK_RULE_CHAIN:W}"
  388 + "alarm": "${AUDIT_LOG_MASK_ALARM:W}"
388 389 sink:
389 390 # Type of external sink. possible options: none, elasticsearch
390 391 type: "${AUDIT_LOG_SINK_TYPE:none}"
... ...
... ... @@ -31,7 +31,12 @@ public enum ActionType {
31 31 ACTIVATED(false), // log string id
32 32 SUSPENDED(false), // log string id
33 33 CREDENTIALS_READ(true), // log device id
34   - ATTRIBUTES_READ(true); // log attributes
  34 + ATTRIBUTES_READ(true), // log attributes
  35 + RELATION_ADD_OR_UPDATE (false),
  36 + RELATION_DELETED (false),
  37 + RELATIONS_DELETED (false),
  38 + ALARM_ACK (false),
  39 + ALARM_CLEAR (false);
35 40
36 41 private final boolean isRead;
37 42
... ...
... ... @@ -60,4 +60,5 @@ public class EntityIdFactory {
60 60 }
61 61 throw new IllegalArgumentException("EntityType " + type + " is not supported!");
62 62 }
  63 +
63 64 }
... ...
... ... @@ -40,15 +40,14 @@ public interface AuditLogService {
40 40
41 41 TimePageData<AuditLog> findAuditLogsByTenantId(TenantId tenantId, TimePageLink pageLink);
42 42
43   - <E extends BaseData<I> & HasName,
44   - I extends UUIDBased & EntityId> ListenableFuture<List<Void>> logEntityAction(
45   - TenantId tenantId,
46   - CustomerId customerId,
47   - UserId userId,
48   - String userName,
49   - I entityId,
50   - E entity,
51   - ActionType actionType,
52   - Exception e, Object... additionalInfo);
  43 + <E extends HasName, I extends EntityId> ListenableFuture<List<Void>> logEntityAction(
  44 + TenantId tenantId,
  45 + CustomerId customerId,
  46 + UserId userId,
  47 + String userName,
  48 + I entityId,
  49 + E entity,
  50 + ActionType actionType,
  51 + Exception e, Object... additionalInfo);
53 52
54 53 }
... ...
... ... @@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.id.UserId;
43 43 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
44 44 import org.thingsboard.server.common.data.page.TimePageData;
45 45 import org.thingsboard.server.common.data.page.TimePageLink;
  46 +import org.thingsboard.server.common.data.relation.EntityRelation;
46 47 import org.thingsboard.server.common.data.rule.RuleChainMetaData;
47 48 import org.thingsboard.server.common.data.security.DeviceCredentials;
48 49 import org.thingsboard.server.dao.audit.sink.AuditLogSink;
... ... @@ -115,7 +116,7 @@ public class AuditLogServiceImpl implements AuditLogService {
115 116 }
116 117
117 118 @Override
118   - public <E extends BaseData<I> & HasName, I extends UUIDBased & EntityId> ListenableFuture<List<Void>>
  119 + public <E extends HasName, I extends EntityId> ListenableFuture<List<Void>>
119 120 logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity,
120 121 ActionType actionType, Exception e, Object... additionalInfo) {
121 122 if (canLog(entityId.getEntityType(), actionType)) {
... ... @@ -156,14 +157,16 @@ public class AuditLogServiceImpl implements AuditLogService {
156 157 }
157 158 }
158 159
159   - private <E extends BaseData<I> & HasName, I extends UUIDBased & EntityId> JsonNode constructActionData(I entityId,
160   - E entity,
  160 + private <E extends HasName, I extends EntityId> JsonNode constructActionData(I entityId, E entity,
161 161 ActionType actionType,
162 162 Object... additionalInfo) {
163 163 ObjectNode actionData = objectMapper.createObjectNode();
164 164 switch(actionType) {
165 165 case ADDED:
166 166 case UPDATED:
  167 + case ALARM_ACK:
  168 + case ALARM_CLEAR:
  169 + case RELATIONS_DELETED:
167 170 if (entity != null) {
168 171 ObjectNode entityNode = objectMapper.valueToTree(entity);
169 172 if (entityId.getEntityType() == EntityType.DASHBOARD) {
... ... @@ -240,6 +243,11 @@ public class AuditLogServiceImpl implements AuditLogService {
240 243 actionData.put("unassignedCustomerId", strCustomerId);
241 244 actionData.put("unassignedCustomerName", strCustomerName);
242 245 break;
  246 + case RELATION_ADD_OR_UPDATE:
  247 + case RELATION_DELETED:
  248 + EntityRelation relation = extractParameter(EntityRelation.class, 0, additionalInfo);
  249 + actionData.set("relation", objectMapper.valueToTree(relation));
  250 + break;
243 251 }
244 252 return actionData;
245 253 }
... ...
... ... @@ -57,7 +57,7 @@ public class DummyAuditLogServiceImpl implements AuditLogService {
57 57 }
58 58
59 59 @Override
60   - public <E extends BaseData<I> & HasName, I extends UUIDBased & EntityId> ListenableFuture<List<Void>> logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity, ActionType actionType, Exception e, Object... additionalInfo) {
  60 + public <E extends HasName, I extends EntityId> ListenableFuture<List<Void>> logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity, ActionType actionType, Exception e, Object... additionalInfo) {
61 61 return null;
62 62 }
63 63
... ...
... ... @@ -195,6 +195,21 @@ export default angular.module('thingsboard.types', [])
195 195 },
196 196 "ATTRIBUTES_READ": {
197 197 name: "audit-log.type-attributes-read"
  198 + },
  199 + "RELATION_ADD_OR_UPDATE": {
  200 + name: "audit-log.type-relation-add-or-update"
  201 + },
  202 + "RELATION_DELETED": {
  203 + name: "audit-log.type-relation-delete"
  204 + },
  205 + "RELATIONS_DELETED": {
  206 + name: "audit-log.type-relations-delete"
  207 + },
  208 + "ALARM_ACK": {
  209 + name: "audit-log.type-alarm-ack"
  210 + },
  211 + "ALARM_CLEAR": {
  212 + name: "audit-log.type-alarm-clear"
198 213 }
199 214 },
200 215 auditLogActionStatus: {
... ...
... ... @@ -288,6 +288,11 @@
288 288 "type-suspended": "Suspended",
289 289 "type-credentials-read": "Credentials read",
290 290 "type-attributes-read": "Attributes read",
  291 + "type-relation-add-or-update": "Relation updated",
  292 + "type-relation-delete": "Relation deleted",
  293 + "type-relations-delete": "All relation deleted",
  294 + "type-alarm-ack": "Acknowledged",
  295 + "type-alarm-clear": "Cleared",
291 296 "status-success": "Success",
292 297 "status-failure": "Failure",
293 298 "audit-log-details": "Audit log details",
... ...