diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index c950f7a7e6..de3b7ffab6 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -25,7 +25,6 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.http.MediaType; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; @@ -173,7 +172,6 @@ import java.util.stream.Collectors; import static org.thingsboard.server.common.data.StringUtils.isNotEmpty; import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD; -import static org.thingsboard.server.controller.ControllerConstants.INCORRECT_TENANT_ID; import static org.thingsboard.server.controller.UserController.YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION; import static org.thingsboard.server.dao.service.Validator.validateId; @@ -603,12 +601,16 @@ public abstract class BaseController { } protected & HasTenantId, I extends EntityId> E checkEntityId(I entityId, ThrowingBiFunction findingFunction, Operation operation) throws ThingsboardException { + return checkEntityId(Resource.of(entityId.getEntityType()), operation, entityId, findingFunction); + } + + protected & HasTenantId, I extends EntityId> E checkEntityId(Resource resource, Operation operation, I entityId, ThrowingBiFunction findingFunction) throws ThingsboardException { try { - validateId((UUIDBased) entityId, "Invalid " + entityId.getClass().getSimpleName().toLowerCase()); + validateId((UUIDBased) entityId, "Invalid entity id"); SecurityUser user = getCurrentUser(); E entity = findingFunction.apply(user.getTenantId(), entityId); - checkNotNull(entity, entity.getClass().getSimpleName() + " with id [" + entityId + "] not found"); - accessControlService.checkPermission(user, Resource.of(entityId.getEntityType()), operation, entityId, entity); + checkNotNull(entity, entityId.getEntityType() + " with id [" + entityId + "] not found"); + accessControlService.checkPermission(user, resource, operation, entityId, entity); return entity; } catch (Exception e) { throw handleException(e, false); @@ -665,7 +667,7 @@ public abstract class BaseController { if (!alarmId.equals(alarmComment.getAlarmId())) { throw new ThingsboardException("Alarm id does not match with comment alarm id", ThingsboardErrorCode.BAD_REQUEST_PARAMS); } - return alarmComment; + return alarmComment; } catch (Exception e) { throw handleException(e, false); } diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java index 9554d62c1b..45b99920ac 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationController.java @@ -63,10 +63,13 @@ import org.thingsboard.server.service.security.permission.Resource; import javax.validation.Valid; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; +import static org.thingsboard.server.service.security.permission.Resource.NOTIFICATION; + @RestController @TbCoreComponent @RequestMapping("/api") @@ -140,6 +143,7 @@ public class NotificationController extends BaseController { @RequestParam(required = false) String sortOrder, @RequestParam(defaultValue = "false") boolean unreadOnly, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { + // no permissions PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return notificationService.findNotificationsByRecipientIdAndReadStatus(user.getTenantId(), user.getId(), unreadOnly, pageLink); } @@ -148,6 +152,7 @@ public class NotificationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") public void markNotificationAsRead(@PathVariable UUID id, @AuthenticationPrincipal SecurityUser user) { + // no permissions NotificationId notificationId = new NotificationId(id); notificationCenter.markNotificationAsRead(user.getTenantId(), user.getId(), notificationId); } @@ -155,6 +160,7 @@ public class NotificationController extends BaseController { @PutMapping("/notifications/read") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") public void markAllNotificationsAsRead(@AuthenticationPrincipal SecurityUser user) { + // no permissions notificationCenter.markAllNotificationsAsRead(user.getTenantId(), user.getId()); } @@ -162,6 +168,7 @@ public class NotificationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") public void deleteNotification(@PathVariable UUID id, @AuthenticationPrincipal SecurityUser user) { + // no permissions NotificationId notificationId = new NotificationId(id); notificationCenter.deleteNotification(user.getTenantId(), user.getId(), notificationId); } @@ -174,7 +181,7 @@ public class NotificationController extends BaseController { throw new IllegalArgumentException("Notification request cannot be updated. You may only cancel/delete it"); } notificationRequest.setTenantId(user.getTenantId()); - checkEntity(notificationRequest.getId(), notificationRequest, Resource.NOTIFICATION_REQUEST); + checkEntity(notificationRequest.getId(), notificationRequest, NOTIFICATION); notificationRequest.setOriginatorEntityId(user.getId()); if (notificationRequest.getInfo() != null && !(notificationRequest.getInfo() instanceof UserOriginatedNotificationInfo)) { @@ -190,13 +197,15 @@ public class NotificationController extends BaseController { @PostMapping("/notification/request/preview") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public NotificationRequestPreview getNotificationRequestPreview(@RequestBody @Valid NotificationRequest request, - @AuthenticationPrincipal SecurityUser user) { + @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { NotificationRequestPreview preview = new NotificationRequestPreview(); request.setOriginatorEntityId(user.getId()); NotificationTemplate template; if (request.getTemplateId() != null) { template = notificationTemplateService.findNotificationTemplateById(user.getTenantId(), request.getTemplateId()); + checkNotNull(template, "Template not found"); + accessControlService.checkPermission(user, NOTIFICATION, Operation.READ, template.getId(), template); } else { template = request.getTemplate(); } @@ -222,21 +231,19 @@ public class NotificationController extends BaseController { })); preview.setProcessedTemplates(processedTemplates); + // generic permission Map recipientsCountByTarget = new HashMap<>(); - request.getTargets().forEach(targetId -> { - NotificationTarget notificationTarget = notificationTargetService.findNotificationTargetById(user.getTenantId(), new NotificationTargetId(targetId)); - if (notificationTarget == null) { - throw new IllegalArgumentException("Notification target with id " + targetId + " not found"); - } - + List targets = notificationTargetService.findNotificationTargetsByTenantIdAndIds(user.getTenantId(), + request.getTargets().stream().map(NotificationTargetId::new).collect(Collectors.toList())); + for (NotificationTarget target : targets) { int recipientsCount; - if (notificationTarget.getConfiguration().getType() == NotificationTargetType.PLATFORM_USERS) { - recipientsCount = notificationTargetService.countRecipientsForNotificationTargetConfig(user.getTenantId(), notificationTarget.getConfiguration()); + if (target.getConfiguration().getType() == NotificationTargetType.PLATFORM_USERS) { + recipientsCount = notificationTargetService.countRecipientsForNotificationTargetConfig(user.getTenantId(), target.getConfiguration()); } else { recipientsCount = 1; } - recipientsCountByTarget.put(notificationTarget.getName(), recipientsCount); - }); + recipientsCountByTarget.put(target.getName(), recipientsCount); + } preview.setRecipientsCountByTarget(recipientsCountByTarget); preview.setTotalRecipientsCount(recipientsCountByTarget.values().stream().mapToInt(Integer::intValue).sum()); @@ -247,7 +254,7 @@ public class NotificationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public NotificationRequestInfo getNotificationRequestById(@PathVariable UUID id) throws ThingsboardException { NotificationRequestId notificationRequestId = new NotificationRequestId(id); - return checkEntityId(notificationRequestId, notificationRequestService::findNotificationRequestInfoById, Operation.READ); + return checkEntityId(NOTIFICATION, Operation.READ, notificationRequestId, notificationRequestService::findNotificationRequestInfoById); } @GetMapping("/notification/requests") @@ -258,6 +265,7 @@ public class NotificationController extends BaseController { @RequestParam(required = false) String sortProperty, @RequestParam(required = false) String sortOrder, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { + // generic permission PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return notificationRequestService.findNotificationRequestsInfosByTenantIdAndOriginatorType(user.getTenantId(), EntityType.USER, pageLink); } @@ -266,7 +274,7 @@ public class NotificationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public void deleteNotificationRequest(@PathVariable UUID id) throws Exception { NotificationRequestId notificationRequestId = new NotificationRequestId(id); - NotificationRequest notificationRequest = checkEntityId(notificationRequestId, notificationRequestService::findNotificationRequestById, Operation.DELETE); + NotificationRequest notificationRequest = checkEntityId(NOTIFICATION, Operation.DELETE, notificationRequestId, notificationRequestService::findNotificationRequestById); doDeleteAndLog(EntityType.NOTIFICATION_REQUEST, notificationRequest, notificationCenter::deleteNotificationRequest); } @@ -275,6 +283,7 @@ public class NotificationController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public NotificationSettings saveNotificationSettings(@RequestBody @Valid NotificationSettings notificationSettings, @AuthenticationPrincipal SecurityUser user) { + // generic permission TenantId tenantId = user.isSystemAdmin() ? TenantId.SYS_TENANT_ID : user.getTenantId(); notificationSettingsService.saveNotificationSettings(tenantId, notificationSettings); return notificationSettings; @@ -283,6 +292,7 @@ public class NotificationController extends BaseController { @GetMapping("/notification/settings") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public NotificationSettings getNotificationSettings(@AuthenticationPrincipal SecurityUser user) { + // generic permission TenantId tenantId = user.isSystemAdmin() ? TenantId.SYS_TENANT_ID : user.getTenantId(); return notificationSettingsService.findNotificationSettings(tenantId); } diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java index 22c93e16d7..492a9eb079 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationRuleController.java @@ -44,6 +44,8 @@ import org.thingsboard.server.service.security.permission.Resource; import javax.validation.Valid; import java.util.UUID; +import static org.thingsboard.server.service.security.permission.Resource.NOTIFICATION; + @RestController @TbCoreComponent @RequestMapping("/api/notification") @@ -57,7 +59,7 @@ public class NotificationRuleController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") public NotificationRule saveNotificationRule(@RequestBody @Valid NotificationRule notificationRule) throws Exception { notificationRule.setTenantId(getTenantId()); - checkEntity(notificationRule.getId(), notificationRule, Resource.NOTIFICATION_RULE); + checkEntity(notificationRule.getId(), notificationRule, NOTIFICATION); return doSaveAndLog(EntityType.NOTIFICATION_RULE, notificationRule, notificationRuleService::saveNotificationRule); } @@ -65,7 +67,7 @@ public class NotificationRuleController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN')") public NotificationRuleInfo getNotificationRuleById(@PathVariable UUID id) throws ThingsboardException { NotificationRuleId notificationRuleId = new NotificationRuleId(id); - return checkEntityId(notificationRuleId, notificationRuleService::findNotificationRuleInfoById, Operation.READ); + return checkEntityId(NOTIFICATION, Operation.READ, notificationRuleId, notificationRuleService::findNotificationRuleInfoById); } @GetMapping("/rules") @@ -76,6 +78,7 @@ public class NotificationRuleController extends BaseController { @RequestParam(required = false) String sortProperty, @RequestParam(required = false) String sortOrder, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { + // generic permission PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return notificationRuleService.findNotificationRulesInfosByTenantId(user.getTenantId(), pageLink); } @@ -85,7 +88,7 @@ public class NotificationRuleController extends BaseController { public void deleteNotificationRule(@PathVariable UUID id, @AuthenticationPrincipal SecurityUser user) throws Exception { NotificationRuleId notificationRuleId = new NotificationRuleId(id); - NotificationRule notificationRule = checkEntityId(notificationRuleId, notificationRuleService::findNotificationRuleById, Operation.DELETE); + NotificationRule notificationRule = checkEntityId(NOTIFICATION, Operation.DELETE, notificationRuleId, notificationRuleService::findNotificationRuleById); doDeleteAndLog(EntityType.NOTIFICATION_RULE, notificationRule, notificationRuleService::deleteNotificationRuleById); tbClusterService.broadcastEntityStateChangeEvent(user.getTenantId(), notificationRuleId, ComponentLifecycleEvent.DELETED); } diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java index 10eed23528..24d21bfade 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationTargetController.java @@ -31,10 +31,15 @@ import org.springframework.web.bind.annotation.RestController; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.NotificationTargetId; import org.thingsboard.server.common.data.notification.targets.NotificationTarget; import org.thingsboard.server.common.data.notification.targets.NotificationTargetConfig; import org.thingsboard.server.common.data.notification.targets.NotificationTargetType; +import org.thingsboard.server.common.data.notification.targets.platform.CustomerUsersFilter; +import org.thingsboard.server.common.data.notification.targets.platform.PlatformUsersNotificationTargetConfig; +import org.thingsboard.server.common.data.notification.targets.platform.UsersFilter; +import org.thingsboard.server.common.data.notification.targets.platform.UsersFilterType; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.page.PageLink; @@ -51,6 +56,7 @@ import java.util.UUID; import java.util.stream.Collectors; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; +import static org.thingsboard.server.service.security.permission.Resource.NOTIFICATION; @RestController @TbCoreComponent @@ -78,17 +84,11 @@ public class NotificationTargetController extends BaseController { public NotificationTarget saveNotificationTarget(@RequestBody @Valid NotificationTarget notificationTarget, @AuthenticationPrincipal SecurityUser user) throws Exception { notificationTarget.setTenantId(user.getTenantId()); - checkEntity(notificationTarget.getId(), notificationTarget, Resource.NOTIFICATION_TARGET); - if (!user.isSystemAdmin()) { - NotificationTargetConfig targetConfig = notificationTarget.getConfiguration(); - if (targetConfig.getType() == NotificationTargetType.PLATFORM_USERS) { - PageDataIterable recipients = new PageDataIterable<>(pageLink -> { - return notificationTargetService.findRecipientsForNotificationTargetConfig(user.getTenantId(), null, targetConfig, pageLink); - }, 200); - for (User recipient : recipients) { - accessControlService.checkPermission(user, Resource.USER, Operation.READ, recipient.getId(), recipient); - } - } + checkEntity(notificationTarget.getId(), notificationTarget, NOTIFICATION); + + NotificationTargetConfig targetConfig = notificationTarget.getConfiguration(); + if (targetConfig.getType() == NotificationTargetType.PLATFORM_USERS) { + checkTargetUsers(user, targetConfig); } return doSaveAndLog(EntityType.NOTIFICATION_TARGET, notificationTarget, notificationTargetService::saveNotificationTarget); @@ -101,10 +101,10 @@ public class NotificationTargetController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public NotificationTarget getNotificationTargetById(@PathVariable UUID id) throws ThingsboardException { NotificationTargetId notificationTargetId = new NotificationTargetId(id); - return checkEntityId(notificationTargetId, notificationTargetService::findNotificationTargetById, Operation.READ); + return checkEntityId(NOTIFICATION, Operation.READ, notificationTargetId, notificationTargetService::findNotificationTargetById); } - @ApiOperation(value = "Get recipient for notification target config (getRecipientsForNotificationTargetConfig)", + @ApiOperation(value = "Get recipients for notification target config (getRecipientsForNotificationTargetConfig)", notes = "Get the list (page) of recipients (users) for such notification target configuration." + SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH) @PostMapping("/target/recipients") @@ -113,20 +113,23 @@ public class NotificationTargetController extends BaseController { @RequestParam int pageSize, @RequestParam int page, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { - PageLink pageLink = createPageLink(pageSize, page, null, null, null); - PageData recipients = notificationTargetService.findRecipientsForNotificationTargetConfig(user.getTenantId(), null, notificationTarget.getConfiguration(), pageLink); - if (!user.isSystemAdmin()) { - for (User recipient : recipients.getData()) { - accessControlService.checkPermission(user, Resource.USER, Operation.READ, recipient.getId(), recipient); - } + // generic permission + NotificationTargetConfig targetConfig = notificationTarget.getConfiguration(); + if (targetConfig.getType() == NotificationTargetType.PLATFORM_USERS) { + checkTargetUsers(user, targetConfig); + } else { + throw new IllegalArgumentException("Target type is not platform users"); } - return recipients; + + PageLink pageLink = createPageLink(pageSize, page, null, null, null); + return notificationTargetService.findRecipientsForNotificationTargetConfig(user.getTenantId(), null, notificationTarget.getConfiguration(), pageLink); } @GetMapping(value = "/targets", params = {"ids"}) @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public List getNotificationTargetsByIds(@RequestParam("ids") UUID[] ids, @AuthenticationPrincipal SecurityUser user) { + // generic permission List targetsIds = Arrays.stream(ids).map(NotificationTargetId::new).collect(Collectors.toList()); return notificationTargetService.findNotificationTargetsByTenantIdAndIds(user.getTenantId(), targetsIds); } @@ -142,6 +145,7 @@ public class NotificationTargetController extends BaseController { @RequestParam(required = false) String sortProperty, @RequestParam(required = false) String sortOrder, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { + // generic permission PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); return notificationTargetService.findNotificationTargetsByTenantId(user.getTenantId(), pageLink); } @@ -154,8 +158,27 @@ public class NotificationTargetController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public void deleteNotificationTargetById(@PathVariable UUID id) throws Exception { NotificationTargetId notificationTargetId = new NotificationTargetId(id); - NotificationTarget notificationTarget = checkEntityId(notificationTargetId, notificationTargetService::findNotificationTargetById, Operation.DELETE); + NotificationTarget notificationTarget = checkEntityId(NOTIFICATION, Operation.DELETE, notificationTargetId, notificationTargetService::findNotificationTargetById); doDeleteAndLog(EntityType.NOTIFICATION_TARGET, notificationTarget, notificationTargetService::deleteNotificationTargetById); } + private void checkTargetUsers(SecurityUser user, NotificationTargetConfig targetConfig) throws ThingsboardException { + if (user.isSystemAdmin()) { + return; + } + // generic permission for users + UsersFilter usersFilter = ((PlatformUsersNotificationTargetConfig) targetConfig).getUsersFilter(); + if (usersFilter.getType() == UsersFilterType.USER_LIST) { + PageDataIterable recipients = new PageDataIterable<>(pageLink -> { + return notificationTargetService.findRecipientsForNotificationTargetConfig(user.getTenantId(), null, targetConfig, pageLink); + }, 200); + for (User recipient : recipients) { + accessControlService.checkPermission(user, Resource.USER, Operation.READ, recipient.getId(), recipient); + } + } else if (usersFilter.getType() == UsersFilterType.CUSTOMER_USERS) { + CustomerId customerId = new CustomerId(((CustomerUsersFilter) usersFilter).getCustomerId()); + checkEntityId(customerId, Operation.READ); + } + } + } diff --git a/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java b/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java index edf399da98..ee90f8c694 100644 --- a/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java +++ b/application/src/main/java/org/thingsboard/server/controller/NotificationTemplateController.java @@ -52,6 +52,7 @@ import java.util.List; import java.util.UUID; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_OR_TENANT_AUTHORITY_PARAGRAPH; +import static org.thingsboard.server.service.security.permission.Resource.NOTIFICATION; @RestController @TbCoreComponent @@ -82,7 +83,7 @@ public class NotificationTemplateController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public NotificationTemplate saveNotificationTemplate(@RequestBody @Valid NotificationTemplate notificationTemplate) throws Exception { notificationTemplate.setTenantId(getTenantId()); - checkEntity(notificationTemplate.getId(), notificationTemplate, Resource.NOTIFICATION_TEMPLATE); + checkEntity(notificationTemplate.getId(), notificationTemplate, NOTIFICATION); return doSaveAndLog(EntityType.NOTIFICATION_TEMPLATE, notificationTemplate, notificationTemplateService::saveNotificationTemplate); } @@ -93,7 +94,7 @@ public class NotificationTemplateController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public NotificationTemplate getNotificationTemplateById(@PathVariable UUID id) throws ThingsboardException { NotificationTemplateId notificationTemplateId = new NotificationTemplateId(id); - return checkEntityId(notificationTemplateId, notificationTemplateService::findNotificationTemplateById, Operation.READ); + return checkEntityId(NOTIFICATION, Operation.READ, notificationTemplateId, notificationTemplateService::findNotificationTemplateById); } @ApiOperation(value = "Get notification templates (getNotificationTemplates)", @@ -108,6 +109,7 @@ public class NotificationTemplateController extends BaseController { @RequestParam(required = false) String sortOrder, @RequestParam(required = false) NotificationType[] notificationTypes, @AuthenticationPrincipal SecurityUser user) throws ThingsboardException { + // generic permission PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder); if (notificationTypes == null || notificationTypes.length == 0) { notificationTypes = NotificationType.values(); @@ -124,7 +126,7 @@ public class NotificationTemplateController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public void deleteNotificationTemplateById(@PathVariable UUID id) throws Exception { NotificationTemplateId notificationTemplateId = new NotificationTemplateId(id); - NotificationTemplate notificationTemplate = checkEntityId(notificationTemplateId, notificationTemplateService::findNotificationTemplateById, Operation.DELETE); + NotificationTemplate notificationTemplate = checkEntityId(NOTIFICATION, Operation.DELETE, notificationTemplateId, notificationTemplateService::findNotificationTemplateById); doDeleteAndLog(EntityType.NOTIFICATION_TEMPLATE, notificationTemplate, notificationTemplateService::deleteNotificationTemplateById); } @@ -136,6 +138,7 @@ public class NotificationTemplateController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") public List listSlackConversations(@RequestParam SlackConversationType type, @AuthenticationPrincipal SecurityUser user) { + // generic permission NotificationSettings settings = notificationSettingsService.findNotificationSettings(user.getTenantId()); SlackNotificationDeliveryMethodConfig slackConfig = (SlackNotificationDeliveryMethodConfig) settings.getDeliveryMethodsConfigs().get(NotificationDeliveryMethod.SLACK); diff --git a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java index 8e7bb5aea0..9b1820331c 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/DefaultNotificationCenter.java @@ -107,15 +107,8 @@ public class DefaultNotificationCenter extends AbstractSubscriptionService imple } if (notificationTemplate == null) throw new IllegalArgumentException("Template is missing"); - List targets = notificationRequest.getTargets().stream() - .map(NotificationTargetId::new) - .map(targetId -> notificationTargetService.findNotificationTargetById(tenantId, targetId)) - .peek(target -> { - if (target == null) { - throw new IllegalArgumentException("Some of the targets no longer exist"); - } - }) - .collect(Collectors.toList()); + List targets = notificationTargetService.findNotificationTargetsByTenantIdAndIds(tenantId, + notificationRequest.getTargets().stream().map(NotificationTargetId::new).collect(Collectors.toList())); notificationTemplate.getConfiguration().getDeliveryMethodsTemplates().forEach((deliveryMethod, template) -> { if (!template.isEnabled()) return; diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java index d800487b6b..049385756d 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/Resource.java @@ -44,10 +44,7 @@ public enum Resource { RPC(EntityType.RPC), QUEUE(EntityType.QUEUE), VERSION_CONTROL, - NOTIFICATION_TARGET(EntityType.NOTIFICATION_TARGET), - NOTIFICATION_TEMPLATE(EntityType.NOTIFICATION_TEMPLATE), - NOTIFICATION_REQUEST(EntityType.NOTIFICATION_REQUEST), - NOTIFICATION_RULE(EntityType.NOTIFICATION_RULE); + NOTIFICATION; private final EntityType entityType; diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java index 6601f772b6..4169aa1c2e 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/SysAdminPermissions.java @@ -40,9 +40,7 @@ public class SysAdminPermissions extends AbstractPermissions { put(Resource.TENANT_PROFILE, PermissionChecker.allowAllPermissionChecker); put(Resource.TB_RESOURCE, systemEntityPermissionChecker); put(Resource.QUEUE, systemEntityPermissionChecker); - put(Resource.NOTIFICATION_TARGET, systemEntityPermissionChecker); - put(Resource.NOTIFICATION_TEMPLATE, systemEntityPermissionChecker); - put(Resource.NOTIFICATION_REQUEST, systemEntityPermissionChecker); + put(Resource.NOTIFICATION, systemEntityPermissionChecker); } private static final PermissionChecker systemEntityPermissionChecker = new PermissionChecker() { diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java index 6d25ae1293..cb924cabca 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java +++ b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java @@ -49,10 +49,7 @@ public class TenantAdminPermissions extends AbstractPermissions { put(Resource.RPC, tenantEntityPermissionChecker); put(Resource.QUEUE, queuePermissionChecker); put(Resource.VERSION_CONTROL, PermissionChecker.allowAllPermissionChecker); - put(Resource.NOTIFICATION_TARGET, tenantEntityPermissionChecker); - put(Resource.NOTIFICATION_TEMPLATE, tenantEntityPermissionChecker); - put(Resource.NOTIFICATION_REQUEST, tenantEntityPermissionChecker); - put(Resource.NOTIFICATION_RULE, tenantEntityPermissionChecker); + put(Resource.NOTIFICATION, tenantEntityPermissionChecker); } public static final PermissionChecker tenantEntityPermissionChecker = new PermissionChecker() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java index b4be74f447..bd37d1315c 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/notification/NotificationRequest.java @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.notification.info.NotificationInfo; import org.thingsboard.server.common.data.notification.template.NotificationTemplate; import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.List; import java.util.UUID; @@ -46,7 +47,7 @@ import java.util.UUID; public class NotificationRequest extends BaseData implements HasTenantId, HasName { private TenantId tenantId; - @NotNull + @NotEmpty private List targets; private NotificationTemplateId templateId;