Browse Source

Audit Log improvements

pull/951/head
Andrew Shvayka 8 years ago
parent
commit
8db6820256
  1. 17
      application/src/main/java/org/thingsboard/server/controller/AlarmController.java
  2. 11
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  3. 31
      application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java
  4. 1
      application/src/main/resources/thingsboard.yml
  5. 7
      common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java
  6. 1
      common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java
  7. 19
      dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java
  8. 14
      dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java
  9. 2
      dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java
  10. 15
      ui/src/app/common/types.constant.js
  11. 5
      ui/src/app/locale/locale.constant-en_US.json

17
application/src/main/java/org/thingsboard/server/controller/AlarmController.java

@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmId;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.alarm.AlarmQuery;
import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
@ -53,7 +55,6 @@ public class AlarmController extends BaseController {
checkParameter(ALARM_ID, strAlarmId);
try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
return checkAlarmId(alarmId);
} catch (Exception e) {
throw handleException(e);
@ -79,8 +80,14 @@ public class AlarmController extends BaseController {
public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException {
try {
alarm.setTenantId(getCurrentUser().getTenantId());
return checkNotNull(alarmService.createOrUpdateAlarm(alarm));
Alarm savedAlarm = checkNotNull(alarmService.createOrUpdateAlarm(alarm));
logEntityAction(savedAlarm.getId(), savedAlarm,
getCurrentUser().getCustomerId(),
savedAlarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null);
return savedAlarm;
} catch (Exception e) {
logEntityAction(emptyId(EntityType.ASSET), alarm,
null, alarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e);
throw handleException(e);
}
}
@ -92,8 +99,9 @@ public class AlarmController extends BaseController {
checkParameter(ALARM_ID, strAlarmId);
try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
checkAlarmId(alarmId);
Alarm alarm = checkAlarmId(alarmId);
alarmService.ackAlarm(alarmId, System.currentTimeMillis()).get();
logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null);
} catch (Exception e) {
throw handleException(e);
}
@ -106,8 +114,9 @@ public class AlarmController extends BaseController {
checkParameter(ALARM_ID, strAlarmId);
try {
AlarmId alarmId = new AlarmId(toUUID(strAlarmId));
checkAlarmId(alarmId);
Alarm alarm = checkAlarmId(alarmId);
alarmService.clearAlarm(alarmId, null, System.currentTimeMillis()).get();
logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null);
} catch (Exception e) {
throw handleException(e);
}

11
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -529,18 +529,16 @@ public abstract class BaseController {
return baseUrl;
}
protected <I extends UUIDBased & EntityId> I emptyId(EntityType entityType) {
protected <I extends EntityId> I emptyId(EntityType entityType) {
return (I)EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
}
protected <E extends BaseData<I> & HasName,
I extends UUIDBased & EntityId> void logEntityAction(I entityId, E entity, CustomerId customerId,
protected <E extends HasName, I extends EntityId> void logEntityAction(I entityId, E entity, CustomerId customerId,
ActionType actionType, Exception e, Object... additionalInfo) throws ThingsboardException {
logEntityAction(getCurrentUser(), entityId, entity, customerId, actionType, e, additionalInfo);
}
protected <E extends BaseData<I> & HasName,
I extends UUIDBased & EntityId> void logEntityAction(User user, I entityId, E entity, CustomerId customerId,
protected <E extends HasName, I extends EntityId> void logEntityAction(User user, I entityId, E entity, CustomerId customerId,
ActionType actionType, Exception e, Object... additionalInfo) throws ThingsboardException {
if (customerId == null || customerId.isNullUid()) {
customerId = user.getCustomerId();
@ -556,8 +554,7 @@ public abstract class BaseController {
return error != null ? (Exception.class.isInstance(error) ? (Exception) error : new Exception(error)) : null;
}
private <E extends BaseData<I> & HasName,
I extends UUIDBased & EntityId> void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId,
private <E extends HasName, I extends EntityId> void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId,
ActionType actionType, Object... additionalInfo) {
String msgType = null;
switch (actionType) {

31
application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java

@ -24,10 +24,13 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationInfo;
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
@ -58,7 +61,15 @@ public class EntityRelationController extends BaseController {
relation.setTypeGroup(RelationTypeGroup.COMMON);
}
relationService.saveRelation(relation);
logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_ADD_OR_UPDATE, null, relation);
logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_ADD_OR_UPDATE, null, relation);
} catch (Exception e) {
logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_ADD_OR_UPDATE, e, relation);
logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_ADD_OR_UPDATE, e, relation);
throw handleException(e);
}
}
@ -81,12 +92,21 @@ public class EntityRelationController extends BaseController {
checkEntityId(fromId);
checkEntityId(toId);
RelationTypeGroup relationTypeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON);
EntityRelation relation = new EntityRelation(fromId, toId, strRelationType, relationTypeGroup);
try {
Boolean found = relationService.deleteRelation(fromId, toId, strRelationType, relationTypeGroup);
if (!found) {
throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND);
}
logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_DELETED, null, relation);
logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_DELETED, null, relation);
} catch (Exception e) {
logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_DELETED, e, relation);
logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(),
ActionType.RELATION_DELETED, e, relation);
throw handleException(e);
}
}
@ -102,7 +122,9 @@ public class EntityRelationController extends BaseController {
checkEntityId(entityId);
try {
relationService.deleteEntityRelations(entityId);
logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, null);
} catch (Exception e) {
logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, e);
throw handleException(e);
}
}
@ -210,8 +232,8 @@ public class EntityRelationController extends BaseController {
@RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE})
@ResponseBody
public List<EntityRelationInfo> findInfoByTo(@RequestParam(TO_ID) String strToId,
@RequestParam(TO_TYPE) String strToType,
@RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
@RequestParam(TO_TYPE) String strToType,
@RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException {
checkParameter(TO_ID, strToId);
checkParameter(TO_TYPE, strToType);
EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId);
@ -276,10 +298,11 @@ public class EntityRelationController extends BaseController {
private RelationTypeGroup parseRelationTypeGroup(String strRelationTypeGroup, RelationTypeGroup defaultValue) {
RelationTypeGroup result = defaultValue;
if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length()>0) {
if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length() > 0) {
try {
result = RelationTypeGroup.valueOf(strRelationTypeGroup);
} catch (IllegalArgumentException e) { }
} catch (IllegalArgumentException e) {
}
}
return result;
}

1
application/src/main/resources/thingsboard.yml

@ -385,6 +385,7 @@ audit_log:
"customer": "${AUDIT_LOG_MASK_CUSTOMER:W}"
"user": "${AUDIT_LOG_MASK_USER:W}"
"rule_chain": "${AUDIT_LOG_MASK_RULE_CHAIN:W}"
"alarm": "${AUDIT_LOG_MASK_ALARM:W}"
sink:
# Type of external sink. possible options: none, elasticsearch
type: "${AUDIT_LOG_SINK_TYPE:none}"

7
common/data/src/main/java/org/thingsboard/server/common/data/audit/ActionType.java

@ -31,7 +31,12 @@ public enum ActionType {
ACTIVATED(false), // log string id
SUSPENDED(false), // log string id
CREDENTIALS_READ(true), // log device id
ATTRIBUTES_READ(true); // log attributes
ATTRIBUTES_READ(true), // log attributes
RELATION_ADD_OR_UPDATE (false),
RELATION_DELETED (false),
RELATIONS_DELETED (false),
ALARM_ACK (false),
ALARM_CLEAR (false);
private final boolean isRead;

1
common/data/src/main/java/org/thingsboard/server/common/data/id/EntityIdFactory.java

@ -60,4 +60,5 @@ public class EntityIdFactory {
}
throw new IllegalArgumentException("EntityType " + type + " is not supported!");
}
}

19
dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogService.java

@ -40,15 +40,14 @@ public interface AuditLogService {
TimePageData<AuditLog> findAuditLogsByTenantId(TenantId tenantId, TimePageLink pageLink);
<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);
<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);
}

14
dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java

@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.dao.audit.sink.AuditLogSink;
@ -115,7 +116,7 @@ public class AuditLogServiceImpl implements AuditLogService {
}
@Override
public <E extends BaseData<I> & HasName, I extends UUIDBased & EntityId> ListenableFuture<List<Void>>
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) {
if (canLog(entityId.getEntityType(), actionType)) {
@ -156,14 +157,16 @@ public class AuditLogServiceImpl implements AuditLogService {
}
}
private <E extends BaseData<I> & HasName, I extends UUIDBased & EntityId> JsonNode constructActionData(I entityId,
E entity,
private <E extends HasName, I extends EntityId> JsonNode constructActionData(I entityId, E entity,
ActionType actionType,
Object... additionalInfo) {
ObjectNode actionData = objectMapper.createObjectNode();
switch(actionType) {
case ADDED:
case UPDATED:
case ALARM_ACK:
case ALARM_CLEAR:
case RELATIONS_DELETED:
if (entity != null) {
ObjectNode entityNode = objectMapper.valueToTree(entity);
if (entityId.getEntityType() == EntityType.DASHBOARD) {
@ -240,6 +243,11 @@ public class AuditLogServiceImpl implements AuditLogService {
actionData.put("unassignedCustomerId", strCustomerId);
actionData.put("unassignedCustomerName", strCustomerName);
break;
case RELATION_ADD_OR_UPDATE:
case RELATION_DELETED:
EntityRelation relation = extractParameter(EntityRelation.class, 0, additionalInfo);
actionData.set("relation", objectMapper.valueToTree(relation));
break;
}
return actionData;
}

2
dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java

@ -57,7 +57,7 @@ public class DummyAuditLogServiceImpl implements AuditLogService {
}
@Override
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) {
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) {
return null;
}

15
ui/src/app/common/types.constant.js

@ -195,6 +195,21 @@ export default angular.module('thingsboard.types', [])
},
"ATTRIBUTES_READ": {
name: "audit-log.type-attributes-read"
},
"RELATION_ADD_OR_UPDATE": {
name: "audit-log.type-relation-add-or-update"
},
"RELATION_DELETED": {
name: "audit-log.type-relation-delete"
},
"RELATIONS_DELETED": {
name: "audit-log.type-relations-delete"
},
"ALARM_ACK": {
name: "audit-log.type-alarm-ack"
},
"ALARM_CLEAR": {
name: "audit-log.type-alarm-clear"
}
},
auditLogActionStatus: {

5
ui/src/app/locale/locale.constant-en_US.json

@ -288,6 +288,11 @@
"type-suspended": "Suspended",
"type-credentials-read": "Credentials read",
"type-attributes-read": "Attributes read",
"type-relation-add-or-update": "Relation updated",
"type-relation-delete": "Relation deleted",
"type-relations-delete": "All relation deleted",
"type-alarm-ack": "Acknowledged",
"type-alarm-clear": "Cleared",
"status-success": "Success",
"status-failure": "Failure",
"audit-log-details": "Audit log details",

Loading…
Cancel
Save