From 9e748520e848daaf23254777df6e3ba70fcf418f Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Fri, 9 Jan 2026 14:52:31 +0200 Subject: [PATCH] Fix invalid notification targets search by type --- .../NotificationTargetApiTest.java | 28 +++++++++++++++++++ .../JpaNotificationTargetDao.java | 2 +- .../NotificationTargetRepository.java | 15 +++++++--- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java b/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java index adfe8a2435..2d865542a1 100644 --- a/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java +++ b/application/src/test/java/org/thingsboard/server/service/notification/NotificationTargetApiTest.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.notification; import com.fasterxml.jackson.core.type.TypeReference; +import org.apache.commons.lang3.RandomStringUtils; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -30,7 +31,12 @@ import org.thingsboard.server.common.data.notification.targets.NotificationTarge import org.thingsboard.server.common.data.notification.targets.platform.AllUsersFilter; 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.SystemAdministratorsFilter; import org.thingsboard.server.common.data.notification.targets.platform.UserListFilter; +import org.thingsboard.server.common.data.notification.targets.platform.UsersFilterType; +import org.thingsboard.server.common.data.notification.targets.slack.SlackConversation; +import org.thingsboard.server.common.data.notification.targets.slack.SlackConversationType; +import org.thingsboard.server.common.data.notification.targets.slack.SlackNotificationTargetConfig; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.dao.notification.NotificationTargetDao; @@ -175,6 +181,28 @@ public class NotificationTargetApiTest extends AbstractNotificationApiTest { assertThat(error).containsIgnoringCase("referenced by scheduled notification request"); } + @Test + public void findByTenantIdAndUsersFilterType() throws Exception { + loginSysAdmin(); + NotificationTarget sysAdmins = createNotificationTarget(new SystemAdministratorsFilter()); + + NotificationTarget slack = new NotificationTarget(); + slack.setName(RandomStringUtils.randomNumeric(5)); + SlackNotificationTargetConfig slackConfig = new SlackNotificationTargetConfig(); + SlackConversation slackConversation = new SlackConversation(); + slackConversation.setType(SlackConversationType.DIRECT); + slackConversation.setId("U12345678"); + slackConversation.setName("test"); + slackConfig.setConversation(slackConversation); + slack.setConfiguration(slackConfig); + slack = saveNotificationTarget(slack); + + List sysAdminTargets = notificationTargetDao.findByTenantIdAndUsersFilterType( + TenantId.SYS_TENANT_ID, UsersFilterType.SYSTEM_ADMINISTRATORS + ); + assertThat(sysAdminTargets).containsOnly(sysAdmins); + } + private String saveAndGetError(NotificationTarget notificationTarget, ResultMatcher statusMatcher) throws Exception { return getErrorMessage(save(notificationTarget, statusMatcher)); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTargetDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTargetDao.java index d05172e255..00dddd0114 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTargetDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/JpaNotificationTargetDao.java @@ -67,7 +67,7 @@ public class JpaNotificationTargetDao extends JpaAbstractDao findByTenantIdAndUsersFilterType(TenantId tenantId, UsersFilterType filterType) { - return DaoUtil.convertDataList(notificationTargetRepository.findByTenantIdAndSearchTextAndUsersFilterTypeIfPresent(tenantId.getId(), null, + return DaoUtil.convertDataList(notificationTargetRepository.findByTenantIdAndUsersFilterType(tenantId.getId(), List.of(filterType.name()), DaoUtil.toPageable(new PageLink(Integer.MAX_VALUE))).getContent()); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationTargetRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationTargetRepository.java index 961e734c9e..e807a6bffb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationTargetRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/notification/NotificationTargetRepository.java @@ -33,20 +33,27 @@ import java.util.UUID; public interface NotificationTargetRepository extends JpaRepository, ExportableEntityRepository { @Query("SELECT t FROM NotificationTargetEntity t WHERE t.tenantId = :tenantId " + - "AND (:searchText is NULL OR ilike(t.name, concat('%', :searchText, '%')) = true)") + "AND (:searchText is NULL OR ilike(t.name, concat('%', :searchText, '%')) = true)") Page findByTenantIdAndSearchText(@Param("tenantId") UUID tenantId, @Param("searchText") String searchText, Pageable pageable); @Query(value = "SELECT * FROM notification_target t WHERE t.tenant_id = :tenantId " + - "AND (:searchText IS NULL OR t.name ILIKE concat('%', :searchText, '%')) " + - "AND (cast(t.configuration as json) ->> 'type' <> 'PLATFORM_USERS' OR " + - "cast(t.configuration as json) -> 'usersFilter' ->> 'type' IN :usersFilterTypes)", nativeQuery = true) + "AND (:searchText IS NULL OR t.name ILIKE concat('%', :searchText, '%')) " + + "AND (cast(t.configuration as json) ->> 'type' <> 'PLATFORM_USERS' OR " + + "cast(t.configuration as json) -> 'usersFilter' ->> 'type' IN :usersFilterTypes)", nativeQuery = true) Page findByTenantIdAndSearchTextAndUsersFilterTypeIfPresent(@Param("tenantId") UUID tenantId, @Param("searchText") String searchText, @Param("usersFilterTypes") List usersFilterTypes, Pageable pageable); + @Query(value = "SELECT * FROM notification_target t WHERE t.tenant_id = :tenantId " + + "AND (cast(t.configuration as json) ->> 'type' = 'PLATFORM_USERS' AND " + + "cast(t.configuration as json) -> 'usersFilter' ->> 'type' IN :usersFilterTypes)", nativeQuery = true) + Page findByTenantIdAndUsersFilterType(@Param("tenantId") UUID tenantId, + @Param("usersFilterTypes") List usersFilterTypes, + Pageable pageable); + List findByTenantIdAndIdIn(UUID tenantId, List ids); @Transactional