From 75e9bb220d94ae1132ce3d9f9c9b9b16261c100f Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Wed, 15 Feb 2023 13:28:58 +0200 Subject: [PATCH 1/9] Rule node description update --- .../rule/engine/metadata/TbFetchDeviceCredentialsNode.java | 2 +- .../thingsboard/rule/engine/metadata/TbGetAttributesNode.java | 2 +- .../rule/engine/metadata/TbGetCustomerDetailsNode.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java index f649083458..2aa3b7a837 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbFetchDeviceCredentialsNode.java @@ -41,7 +41,7 @@ import java.util.concurrent.ExecutionException; type = ComponentType.ENRICHMENT, name = "fetch device credentials", configClazz = TbFetchDeviceCredentialsNodeConfiguration.class, - nodeDescription = "Fetch device credentials for message originator", + nodeDescription = "Enrich the message body or metadata with the device credentials", nodeDetails = "Adds credentialsType and credentials properties to the message metadata if the " + "configuration parameter fetchToMetadata is set to true, otherwise, adds properties " + "to the message data. If originator type is not DEVICE or rule node failed to get device credentials " + diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java index 8eba395d11..7e42105e5d 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetAttributesNode.java @@ -34,7 +34,7 @@ import org.thingsboard.server.common.msg.TbMsg; @RuleNode(type = ComponentType.ENRICHMENT, name = "originator attributes", configClazz = TbGetAttributesNodeConfiguration.class, - nodeDescription = "Add Message Originator Attributes or Latest Telemetry into Message Data or Metadata", + nodeDescription = "Enrich the message body or metadata with the originator attributes and/or timeseries data", nodeDetails = "If Attributes enrichment configured, CLIENT/SHARED/SERVER attributes are added into Message data/metadata " + "with specific prefix: cs/shared/ss. Latest telemetry value added into Message data/metadata without prefix. " + "To access those attributes in other nodes this template can be used " + diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java index 353342285b..fa4f3552bc 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/metadata/TbGetCustomerDetailsNode.java @@ -38,7 +38,7 @@ import org.thingsboard.server.common.msg.TbMsg; @RuleNode(type = ComponentType.ENRICHMENT, name = "customer details", configClazz = TbGetCustomerDetailsNodeConfiguration.class, - nodeDescription = "Adds fields from Customer details to the message body or metadata", + nodeDescription = "Enrich the message body or metadata with the corresponding customer details: title, address, email, phone, etc.", nodeDetails = "If checkbox: Add selected details to the message metadata is selected, existing fields will be added to the message metadata instead of message data.

" + "Note: only Device, Asset, and Entity View type are allowed.

" + "If the originator of the message is not assigned to Customer, or originator type is not supported - Message will be forwarded to Failure chain, otherwise, Success chain will be used.", From 559b741749eb2d2a9a7556241508f3efa0fd3b31 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 16 Feb 2023 00:37:10 +0200 Subject: [PATCH 2/9] added REST method in UserController to get users by query --- .../server/controller/UserController.java | 96 +++++++++++++++++++ .../server/common/data/UserData.java | 38 ++++++++ .../server/common/data/query/KeyFilter.java | 6 ++ .../data/query/StringFilterPredicate.java | 6 ++ 4 files changed, 146 insertions(+) create mode 100644 common/data/src/main/java/org/thingsboard/server/common/data/UserData.java diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 3e202de938..711c67383d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -21,6 +21,7 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.ApplicationEventPublisher; import org.springframework.http.HttpStatus; @@ -38,7 +39,9 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.MailService; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.UserData; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; @@ -46,6 +49,16 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; +import org.thingsboard.server.common.data.query.EntityData; +import org.thingsboard.server.common.data.query.EntityDataPageLink; +import org.thingsboard.server.common.data.query.EntityDataQuery; +import org.thingsboard.server.common.data.query.EntityDataSortOrder; +import org.thingsboard.server.common.data.query.EntityKey; +import org.thingsboard.server.common.data.query.EntityKeyType; +import org.thingsboard.server.common.data.query.EntityTypeFilter; +import org.thingsboard.server.common.data.query.FilterPredicateValue; +import org.thingsboard.server.common.data.query.KeyFilter; +import org.thingsboard.server.common.data.query.StringFilterPredicate; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserSettings; @@ -53,6 +66,7 @@ import org.thingsboard.server.common.data.security.event.UserCredentialsInvalida import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.entitiy.user.TbUserService; import org.thingsboard.server.common.data.security.model.JwtPair; +import org.thingsboard.server.service.query.EntityQueryService; import org.thingsboard.server.service.security.model.SecurityUser; import org.thingsboard.server.service.security.model.UserPrincipal; import org.thingsboard.server.service.security.model.token.JwtTokenFactory; @@ -62,8 +76,14 @@ import org.thingsboard.server.service.security.system.SystemSecurityService; import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +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.common.data.query.FilterPredicateValue.fromString; +import static org.thingsboard.server.common.data.query.StringFilterPredicate.StringOperation.EQUAL; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEFAULT_DASHBOARD; @@ -106,6 +126,9 @@ public class UserController extends BaseController { private final ApplicationEventPublisher eventPublisher; private final TbUserService tbUserService; + @Autowired + private EntityQueryService entityQueryService; + @ApiOperation(value = "Get User (getUserById)", notes = "Fetch the User object based on the provided User Id. " + "If the user has the authority of 'SYS_ADMIN', the server does not perform additional checks. " + @@ -304,6 +327,66 @@ public class UserController extends BaseController { } } + @ApiOperation(value = "Find users by query (findUsersByQuery)", + notes = "Returns a page of user data owned by tenant or customer." + + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/users/find", method = RequestMethod.GET) + @ResponseBody + public PageData findUsersByQuery( + @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) + @RequestParam int pageSize, + @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) + @RequestParam int page, + @ApiParam(value = USER_TEXT_SEARCH_DESCRIPTION) + @RequestParam(required = false) String textSearch, + @ApiParam(value = SORT_PROPERTY_DESCRIPTION, allowableValues = USER_SORT_PROPERTY_ALLOWABLE_VALUES) + @RequestParam(required = false) String sortProperty, + @ApiParam(value = SORT_ORDER_DESCRIPTION, allowableValues = SORT_ORDER_ALLOWABLE_VALUES) + @RequestParam(required = false) String sortOrder) throws ThingsboardException { + SecurityUser securityUser = getCurrentUser(); + + EntityTypeFilter entityFilter = new EntityTypeFilter(); + entityFilter.setEntityType(EntityType.USER); + + EntityDataPageLink pageLink = new EntityDataPageLink(pageSize, page, textSearch, createEntityDataSortOrder(sortProperty, sortOrder)); + + List entityFields = Arrays.asList(new EntityKey(ENTITY_FIELD, "firstName"), + new EntityKey(ENTITY_FIELD, "lastName"), + new EntityKey(ENTITY_FIELD, "email")); + + List keyFilters = new ArrayList<>(); + KeyFilter tenantIdFilter = KeyFilter.builder() + .key(new EntityKey(ENTITY_FIELD, "tenantId")) + .predicate(StringFilterPredicate.builder() + .operation(EQUAL) + .value(fromString(securityUser.getTenantId().getId().toString())).build()) + .build(); + keyFilters.add(tenantIdFilter); + + if (!Authority.TENANT_ADMIN.equals(securityUser.getAuthority())) { + KeyFilter customerIdFilter = KeyFilter.builder() + .key(new EntityKey(ENTITY_FIELD, "customerId")) + .predicate(StringFilterPredicate.builder() + .operation(EQUAL) + .value(fromString(securityUser.getCustomerId().getId().toString())).build()) + .build(); + keyFilters.add(customerIdFilter); + } + + EntityDataQuery query = new EntityDataQuery(entityFilter, pageLink, entityFields, null, keyFilters); + + try { + return entityQueryService.findEntityDataByQuery(securityUser, query).mapData(entityData -> + new UserData(UserId.fromString(entityData.getEntityId().getId().toString()), + entityData.getLatest().get(ENTITY_FIELD).get("email").getValue(), + entityData.getLatest().get(ENTITY_FIELD).get("firstName").getValue(), + entityData.getLatest().get(ENTITY_FIELD).get("lastName").getValue())); + } catch (Exception e) { + throw handleException(e); + } + } + @ApiOperation(value = "Get Tenant Users (getTenantAdmins)", notes = "Returns a page of users owned by tenant. " + PAGE_DATA_PARAMETERS + SYSTEM_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAuthority('SYS_ADMIN')") @@ -434,4 +517,17 @@ public class UserController extends BaseController { SecurityUser currentUser = getCurrentUser(); userSettingsService.deleteUserSettings(currentUser.getTenantId(), currentUser.getId(), Arrays.asList(paths.split(","))); } + + private EntityDataSortOrder createEntityDataSortOrder(String sortProperty, String sortOrder) { + if (isNotEmpty(sortProperty)) { + EntityDataSortOrder entityDataSortOrder = new EntityDataSortOrder(); + entityDataSortOrder.setKey(new EntityKey(ENTITY_FIELD, sortProperty)); + if (isNotEmpty(sortOrder)) { + entityDataSortOrder.setDirection(EntityDataSortOrder.Direction.valueOf(sortOrder)); + } + return entityDataSortOrder; + } else { + return null; + } + } } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/UserData.java b/common/data/src/main/java/org/thingsboard/server/common/data/UserData.java new file mode 100644 index 0000000000..fd596ba639 --- /dev/null +++ b/common/data/src/main/java/org/thingsboard/server/common/data/UserData.java @@ -0,0 +1,38 @@ +/** + * Copyright © 2016-2023 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.common.data; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import org.thingsboard.server.common.data.id.UserId; + +@ApiModel +@Data +@AllArgsConstructor +public class UserData { + + @ApiModelProperty(position = 1, value = "User id") + private UserId id; + @ApiModelProperty(position = 2, value = "User email", example = "john@gmail.com") + private String email; + @ApiModelProperty(position = 3, value = "User first name", example = "John") + private String firstName; + @ApiModelProperty(position = 4, value = "User last name", example = "Brown") + private String lastName; + +} diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java index ad5d42e31d..c81b2b8db6 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java @@ -16,12 +16,18 @@ package org.thingsboard.server.common.data.query; import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import java.io.Serializable; @ApiModel @Data +@Builder +@AllArgsConstructor +@NoArgsConstructor public class KeyFilter implements Serializable { private EntityKey key; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java index 125ca4665a..f30ec6c9fd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java @@ -15,11 +15,17 @@ */ package org.thingsboard.server.common.data.query; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; import javax.validation.Valid; @Data +@Builder +@AllArgsConstructor +@NoArgsConstructor public class StringFilterPredicate implements SimpleKeyFilterPredicate { private StringOperation operation; From 39070ead536873841e93caecf615da19e2e2875e Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 16 Feb 2023 12:23:22 +0200 Subject: [PATCH 3/9] refactoring --- .../server/controller/UserController.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 711c67383d..7e768b747f 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -376,15 +376,11 @@ public class UserController extends BaseController { EntityDataQuery query = new EntityDataQuery(entityFilter, pageLink, entityFields, null, keyFilters); - try { - return entityQueryService.findEntityDataByQuery(securityUser, query).mapData(entityData -> - new UserData(UserId.fromString(entityData.getEntityId().getId().toString()), - entityData.getLatest().get(ENTITY_FIELD).get("email").getValue(), - entityData.getLatest().get(ENTITY_FIELD).get("firstName").getValue(), - entityData.getLatest().get(ENTITY_FIELD).get("lastName").getValue())); - } catch (Exception e) { - throw handleException(e); - } + return entityQueryService.findEntityDataByQuery(securityUser, query).mapData(entityData -> + new UserData(UserId.fromString(entityData.getEntityId().getId().toString()), + entityData.getLatest().get(ENTITY_FIELD).get("email").getValue(), + entityData.getLatest().get(ENTITY_FIELD).get("firstName").getValue(), + entityData.getLatest().get(ENTITY_FIELD).get("lastName").getValue())); } @ApiOperation(value = "Get Tenant Users (getTenantAdmins)", From 4470ae9a05079da0e25310b9596b6d706f9df51c Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 16 Feb 2023 13:45:01 +0200 Subject: [PATCH 4/9] added tests --- .../controller/BaseUserControllerTest.java | 169 ++++++++++++++++++ .../server/common/data/UserData.java | 3 +- 2 files changed, 171 insertions(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java index 983e33ed7a..5df1c8acb5 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.UserData; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; @@ -48,6 +49,7 @@ import org.thingsboard.server.service.mail.TestMailService; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsString; @@ -61,6 +63,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.SYSTEM_TENANT; public abstract class BaseUserControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); + private IdComparator userDataIdComparator = new IdComparator<>(); private CustomerId customerNUULId = (CustomerId) createEntityId_NULL_UUID(new Customer()); @@ -858,6 +861,172 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { Assert.assertEquals(expectedSettings, retrievedSettings); } + @Test + public void shouldFindCustomerUsersByFirstName() throws Exception { + loginSysAdmin(); + + User tenantAdmin = new User(); + tenantAdmin.setAuthority(Authority.TENANT_ADMIN); + tenantAdmin.setTenantId(tenantId); + tenantAdmin.setEmail("tenant2@thingsboard.org"); + tenantAdmin.setFirstName("Joe"); + tenantAdmin.setLastName("Downs"); + + createUserAndLogin(tenantAdmin, "testPassword1"); + + Customer customer = new Customer(); + customer.setTitle("My customer"); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + CustomerId customerId = savedCustomer.getId(); + + Customer customer2 = new Customer(); + customer2.setTitle("My customer2"); + Customer savedCustomer2 = doPost("/api/customer", customer2, Customer.class); + CustomerId customerId2 = savedCustomer2.getId(); + + List customerUsers = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + User user = new User(); + user.setAuthority(Authority.CUSTOMER_USER); + user.setCustomerId(customerId); + user.setFirstName("Name" + i); + user.setLastName("Lastname" + i); + user.setEmail("testCustomer" + i + "@thingsboard.org"); + customerUsers.add(doPost("/api/user", user, User.class)); + } + for (int i = 0; i < 10; i++) { + User user = new User(); + user.setAuthority(Authority.CUSTOMER_USER); + user.setCustomerId(customerId2); + user.setFirstName("SecondCustomerName" + i); + user.setLastName("SecondCustomerLastname" + i); + user.setEmail("SecondCustomerUser" + i + "@thingsboard.org"); + doPost("/api/user", user, User.class); + } + + User user = new User(); + user.setAuthority(Authority.CUSTOMER_USER); + user.setCustomerId(customerId); + user.setEmail("testCustomerUser@thingsboard.org"); + createUserAndLogin(user, "testPassword2"); + + // find user my name + List loadedCustomerUsers = new ArrayList<>(); + PageLink pageLink = new PageLink(10, 0, "Name"); + PageData pageData = null; + do { + pageData = doGetTypedWithPageLink("/api/users/find?", + new TypeReference<>() { + }, pageLink); + loadedCustomerUsers.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } while (pageData.hasNext()); + + List customerUserDatas = customerUsers.stream().map(customerUser -> new UserData(customerUser.getId(), + customerUser.getEmail(), customerUser.getFirstName(), customerUser.getLastName())) + .sorted(userDataIdComparator).collect(Collectors.toList()); + loadedCustomerUsers.sort(userDataIdComparator); + + Assert.assertEquals(customerUserDatas, loadedCustomerUsers); + + // find user my full name + loadedCustomerUsers.clear(); + pageLink = new PageLink(10, 0, "Name3"); + pageData = doGetTypedWithPageLink("/api/users/find?", + new TypeReference<>() { + }, pageLink); + loadedCustomerUsers.addAll(pageData.getData()); + Assert.assertEquals(pageData.getData().size(), 1); + Assert.assertEquals(pageData.getData().get(0).getEmail(), "testCustomer3@thingsboard.org"); + + //clear users + loginUser(tenantAdmin.getEmail(), "testPassword1"); + doDelete("/api/customer/" + customerId.getId().toString()) + .andExpect(status().isOk()); + } + + @Test + public void shouldFindTenantUsersByLastName() throws Exception { + loginSysAdmin(); + + User tenantAdmin = new User(); + tenantAdmin.setAuthority(Authority.TENANT_ADMIN); + tenantAdmin.setTenantId(tenantId); + tenantAdmin.setEmail("tenant2@thingsboard.org"); + tenantAdmin.setFirstName("Joe"); + tenantAdmin.setLastName("Downs"); + + createUserAndLogin(tenantAdmin, "testPassword1"); + + Customer customer = new Customer(); + customer.setTitle("My customer"); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + CustomerId customerId = savedCustomer.getId(); + + Customer customer2 = new Customer(); + customer2.setTitle("My customer2"); + Customer savedCustomer2 = doPost("/api/customer", customer2, Customer.class); + CustomerId customerId2 = savedCustomer2.getId(); + + List customerUsers = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + User user = new User(); + user.setAuthority(Authority.CUSTOMER_USER); + user.setCustomerId(customerId); + user.setFirstName("Name" + i); + user.setLastName("Lastname" + i); + user.setEmail("testCustomer" + i + "@thingsboard.org"); + customerUsers.add(doPost("/api/user", user, User.class)); + } + for (int i = 0; i < 10; i++) { + User user = new User(); + user.setAuthority(Authority.CUSTOMER_USER); + user.setCustomerId(customerId2); + user.setFirstName("SecondCustomerName" + i); + user.setLastName("SecondCustomerLastname" + i); + user.setEmail("SecondCustomerUser" + i + "@thingsboard.org"); + customerUsers.add(doPost("/api/user", user, User.class)); + } + + // find user my name + List loadedCustomerUsers = new ArrayList<>(); + PageLink pageLink = new PageLink(10, 0, "Name"); + PageData pageData = null; + do { + pageData = doGetTypedWithPageLink("/api/users/find?", + new TypeReference<>() { + }, pageLink); + loadedCustomerUsers.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } while (pageData.hasNext()); + + List customerUserDatas = customerUsers.stream().map(customerUser -> new UserData(customerUser.getId(), + customerUser.getEmail(), customerUser.getFirstName(), customerUser.getLastName())) + .sorted(userDataIdComparator).collect(Collectors.toList()); + loadedCustomerUsers.sort(userDataIdComparator); + + Assert.assertEquals(customerUserDatas, loadedCustomerUsers); + + // find user my full name + loadedCustomerUsers.clear(); + pageLink = new PageLink(10, 0, "SecondCustomerLastname3"); + pageData = doGetTypedWithPageLink("/api/users/find?", + new TypeReference<>() { + }, pageLink); + loadedCustomerUsers.addAll(pageData.getData()); + Assert.assertEquals(pageData.getData().size(), 1); + Assert.assertEquals(pageData.getData().get(0).getEmail(), "SecondCustomerUser3@thingsboard.org"); + + //clear users + loginUser(tenantAdmin.getEmail(), "testPassword1"); + doDelete("/api/customer/" + customerId.getId().toString()) + .andExpect(status().isOk()); + } + private User createUser() throws Exception { loginSysAdmin(); String email = "tenant2@thingsboard.org"; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/UserData.java b/common/data/src/main/java/org/thingsboard/server/common/data/UserData.java index fd596ba639..8edb5ec7cf 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/UserData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/UserData.java @@ -19,12 +19,13 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; +import org.thingsboard.server.common.data.id.HasId; import org.thingsboard.server.common.data.id.UserId; @ApiModel @Data @AllArgsConstructor -public class UserData { +public class UserData implements HasId { @ApiModelProperty(position = 1, value = "User id") private UserId id; From a613e1dbc6ed68e6533533561d43201252de50fe Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Thu, 16 Feb 2023 17:46:24 +0200 Subject: [PATCH 5/9] refactoring --- .../server/controller/UserController.java | 37 ++----------------- .../controller/BaseUserControllerTest.java | 8 ++-- .../server/common/data/query/KeyFilter.java | 6 --- .../data/query/StringFilterPredicate.java | 6 --- 4 files changed, 8 insertions(+), 49 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 7e768b747f..032d664c1b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -49,16 +49,11 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityDataPageLink; import org.thingsboard.server.common.data.query.EntityDataQuery; import org.thingsboard.server.common.data.query.EntityDataSortOrder; import org.thingsboard.server.common.data.query.EntityKey; -import org.thingsboard.server.common.data.query.EntityKeyType; import org.thingsboard.server.common.data.query.EntityTypeFilter; -import org.thingsboard.server.common.data.query.FilterPredicateValue; -import org.thingsboard.server.common.data.query.KeyFilter; -import org.thingsboard.server.common.data.query.StringFilterPredicate; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserSettings; @@ -76,14 +71,11 @@ import org.thingsboard.server.service.security.system.SystemSecurityService; import javax.servlet.http.HttpServletRequest; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; 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.common.data.query.FilterPredicateValue.fromString; -import static org.thingsboard.server.common.data.query.StringFilterPredicate.StringOperation.EQUAL; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; import static org.thingsboard.server.controller.ControllerConstants.DEFAULT_DASHBOARD; @@ -328,10 +320,10 @@ public class UserController extends BaseController { } @ApiOperation(value = "Find users by query (findUsersByQuery)", - notes = "Returns a page of user data owned by tenant or customer." + - PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) + notes = "Returns page of user data objects. Search is been executed by email, firstName and " + + "lastName fields. " + PAGE_DATA_PARAMETERS + TENANT_OR_CUSTOMER_AUTHORITY_PARAGRAPH) @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/users/find", method = RequestMethod.GET) + @RequestMapping(value = "/users/info", method = RequestMethod.GET) @ResponseBody public PageData findUsersByQuery( @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) @@ -348,33 +340,12 @@ public class UserController extends BaseController { EntityTypeFilter entityFilter = new EntityTypeFilter(); entityFilter.setEntityType(EntityType.USER); - EntityDataPageLink pageLink = new EntityDataPageLink(pageSize, page, textSearch, createEntityDataSortOrder(sortProperty, sortOrder)); - List entityFields = Arrays.asList(new EntityKey(ENTITY_FIELD, "firstName"), new EntityKey(ENTITY_FIELD, "lastName"), new EntityKey(ENTITY_FIELD, "email")); - List keyFilters = new ArrayList<>(); - KeyFilter tenantIdFilter = KeyFilter.builder() - .key(new EntityKey(ENTITY_FIELD, "tenantId")) - .predicate(StringFilterPredicate.builder() - .operation(EQUAL) - .value(fromString(securityUser.getTenantId().getId().toString())).build()) - .build(); - keyFilters.add(tenantIdFilter); - - if (!Authority.TENANT_ADMIN.equals(securityUser.getAuthority())) { - KeyFilter customerIdFilter = KeyFilter.builder() - .key(new EntityKey(ENTITY_FIELD, "customerId")) - .predicate(StringFilterPredicate.builder() - .operation(EQUAL) - .value(fromString(securityUser.getCustomerId().getId().toString())).build()) - .build(); - keyFilters.add(customerIdFilter); - } - - EntityDataQuery query = new EntityDataQuery(entityFilter, pageLink, entityFields, null, keyFilters); + EntityDataQuery query = new EntityDataQuery(entityFilter, pageLink, entityFields, null, null); return entityQueryService.findEntityDataByQuery(securityUser, query).mapData(entityData -> new UserData(UserId.fromString(entityData.getEntityId().getId().toString()), diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java index 5df1c8acb5..4c7b783dc0 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java @@ -915,7 +915,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { PageLink pageLink = new PageLink(10, 0, "Name"); PageData pageData = null; do { - pageData = doGetTypedWithPageLink("/api/users/find?", + pageData = doGetTypedWithPageLink("/api/users/info?", new TypeReference<>() { }, pageLink); loadedCustomerUsers.addAll(pageData.getData()); @@ -934,7 +934,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { // find user my full name loadedCustomerUsers.clear(); pageLink = new PageLink(10, 0, "Name3"); - pageData = doGetTypedWithPageLink("/api/users/find?", + pageData = doGetTypedWithPageLink("/api/users/info?", new TypeReference<>() { }, pageLink); loadedCustomerUsers.addAll(pageData.getData()); @@ -995,7 +995,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { PageLink pageLink = new PageLink(10, 0, "Name"); PageData pageData = null; do { - pageData = doGetTypedWithPageLink("/api/users/find?", + pageData = doGetTypedWithPageLink("/api/users/info?", new TypeReference<>() { }, pageLink); loadedCustomerUsers.addAll(pageData.getData()); @@ -1014,7 +1014,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { // find user my full name loadedCustomerUsers.clear(); pageLink = new PageLink(10, 0, "SecondCustomerLastname3"); - pageData = doGetTypedWithPageLink("/api/users/find?", + pageData = doGetTypedWithPageLink("/api/users/info?", new TypeReference<>() { }, pageLink); loadedCustomerUsers.addAll(pageData.getData()); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java index c81b2b8db6..ad5d42e31d 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/KeyFilter.java @@ -16,18 +16,12 @@ package org.thingsboard.server.common.data.query; import io.swagger.annotations.ApiModel; -import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; -import lombok.NoArgsConstructor; import java.io.Serializable; @ApiModel @Data -@Builder -@AllArgsConstructor -@NoArgsConstructor public class KeyFilter implements Serializable { private EntityKey key; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java index f30ec6c9fd..125ca4665a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/StringFilterPredicate.java @@ -15,17 +15,11 @@ */ package org.thingsboard.server.common.data.query; -import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; -import lombok.NoArgsConstructor; import javax.validation.Valid; @Data -@Builder -@AllArgsConstructor -@NoArgsConstructor public class StringFilterPredicate implements SimpleKeyFilterPredicate { private StringOperation operation; From bbbea0fc3158ca093a04966b92117e980b42c9ec Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 17 Feb 2023 00:01:50 +0200 Subject: [PATCH 6/9] added tests, refactoring --- .../server/controller/BaseController.java | 17 + .../server/controller/UserController.java | 25 +- .../controller/BaseUserControllerTest.java | 397 +++++++----------- 3 files changed, 187 insertions(+), 252 deletions(-) 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 970100d938..92536b985a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -93,6 +93,8 @@ import org.thingsboard.server.common.data.page.SortOrder; import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.plugin.ComponentDescriptor; import org.thingsboard.server.common.data.plugin.ComponentType; +import org.thingsboard.server.common.data.query.EntityDataSortOrder; +import org.thingsboard.server.common.data.query.EntityKey; import org.thingsboard.server.common.data.queue.Queue; import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rule.RuleChain; @@ -160,6 +162,8 @@ import java.util.Set; import java.util.UUID; 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; @@ -987,4 +991,17 @@ public abstract class BaseController { }, MoreExecutors.directExecutor()); return deferredResult; } + + protected EntityDataSortOrder createEntityDataSortOrder(String sortProperty, String sortOrder) { + if (isNotEmpty(sortProperty)) { + EntityDataSortOrder entityDataSortOrder = new EntityDataSortOrder(); + entityDataSortOrder.setKey(new EntityKey(ENTITY_FIELD, sortProperty)); + if (isNotEmpty(sortOrder)) { + entityDataSortOrder.setDirection(EntityDataSortOrder.Direction.valueOf(sortOrder)); + } + return entityDataSortOrder; + } else { + return null; + } + } } diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 032d664c1b..6177bdc74b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -54,6 +54,7 @@ import org.thingsboard.server.common.data.query.EntityDataQuery; import org.thingsboard.server.common.data.query.EntityDataSortOrder; import org.thingsboard.server.common.data.query.EntityKey; import org.thingsboard.server.common.data.query.EntityTypeFilter; +import org.thingsboard.server.common.data.query.TsValue; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.UserCredentials; import org.thingsboard.server.common.data.security.UserSettings; @@ -73,6 +74,7 @@ import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; +import java.util.Map; import static org.thingsboard.server.common.data.StringUtils.isNotEmpty; import static org.thingsboard.server.common.data.query.EntityKeyType.ENTITY_FIELD; @@ -348,10 +350,13 @@ public class UserController extends BaseController { EntityDataQuery query = new EntityDataQuery(entityFilter, pageLink, entityFields, null, null); return entityQueryService.findEntityDataByQuery(securityUser, query).mapData(entityData -> - new UserData(UserId.fromString(entityData.getEntityId().getId().toString()), - entityData.getLatest().get(ENTITY_FIELD).get("email").getValue(), - entityData.getLatest().get(ENTITY_FIELD).get("firstName").getValue(), - entityData.getLatest().get(ENTITY_FIELD).get("lastName").getValue())); + { + Map keyValueMap = entityData.getLatest().get(ENTITY_FIELD); + return new UserData(UserId.fromString(entityData.getEntityId().getId().toString()), + keyValueMap.get("email").getValue(), + keyValueMap.get("firstName").getValue(), + keyValueMap.get("lastName").getValue()); + }); } @ApiOperation(value = "Get Tenant Users (getTenantAdmins)", @@ -485,16 +490,4 @@ public class UserController extends BaseController { userSettingsService.deleteUserSettings(currentUser.getTenantId(), currentUser.getId(), Arrays.asList(paths.split(","))); } - private EntityDataSortOrder createEntityDataSortOrder(String sortProperty, String sortOrder) { - if (isNotEmpty(sortProperty)) { - EntityDataSortOrder entityDataSortOrder = new EntityDataSortOrder(); - entityDataSortOrder.setKey(new EntityKey(ENTITY_FIELD, sortProperty)); - if (isNotEmpty(sortOrder)) { - entityDataSortOrder.setDirection(EntityDataSortOrder.Direction.valueOf(sortOrder)); - } - return entityDataSortOrder; - } else { - return null; - } - } } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java index 4c7b783dc0..d78b8b08ef 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java @@ -18,6 +18,7 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import org.jetbrains.annotations.NotNull; import org.junit.After; import org.junit.Assert; import org.junit.Ignore; @@ -87,21 +88,15 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { public void testSaveUser() throws Exception { loginSysAdmin(); - String email = "tenant2@thingsboard.org"; - User user = new User(); - user.setAuthority(Authority.TENANT_ADMIN); - user.setTenantId(tenantId); - user.setEmail(email); - user.setFirstName("Joe"); - user.setLastName("Downs"); - + User user = createTenantAdminUser(); + String email = user.getEmail(); Mockito.reset(tbClusterService, auditLogService); User savedUser = doPost("/api/user", user, User.class); Assert.assertNotNull(savedUser); Assert.assertNotNull(savedUser.getId()); Assert.assertTrue(savedUser.getCreatedTime() > 0); - Assert.assertEquals(user.getEmail(), savedUser.getEmail()); + Assert.assertEquals(email, savedUser.getEmail()); User foundUser = doGet("/api/user/" + savedUser.getId().getId().toString(), User.class); Assert.assertEquals(foundUser, savedUser); @@ -156,13 +151,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { Mockito.reset(tbClusterService, auditLogService); - String email = "tenant2@thingsboard.org"; - User user = new User(); - user.setAuthority(Authority.TENANT_ADMIN); - user.setTenantId(tenantId); - user.setEmail(email); - user.setFirstName(StringUtils.randomAlphabetic(300)); - user.setLastName("Downs"); + User user = createTenantAdminUser(StringUtils.randomAlphabetic(300), "Brown"); String msgError = msgErrorFieldLength("first name"); doPost("/api/user", user) .andExpect(status().isBadRequest()) @@ -189,12 +178,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { public void testUpdateUserFromDifferentTenant() throws Exception { loginSysAdmin(); - User tenantAdmin = new User(); - tenantAdmin.setAuthority(Authority.TENANT_ADMIN); - tenantAdmin.setTenantId(tenantId); - tenantAdmin.setEmail("tenant2@thingsboard.org"); - tenantAdmin.setFirstName("Joe"); - tenantAdmin.setLastName("Downs"); + User tenantAdmin = createTenantAdminUser(); tenantAdmin = createUserAndLogin(tenantAdmin, "testPassword1"); loginDifferentTenant(); @@ -214,14 +198,8 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { public void testResetPassword() throws Exception { loginSysAdmin(); - String email = "tenant2@thingsboard.org"; - User user = new User(); - user.setAuthority(Authority.TENANT_ADMIN); - user.setTenantId(tenantId); - user.setEmail(email); - user.setFirstName("Joe"); - user.setLastName("Downs"); - + User user = createTenantAdminUser(); + String email = user.getEmail(); User savedUser = createUserAndLogin(user, "testPassword1"); resetTokens(); @@ -266,13 +244,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { public void testFindUserById() throws Exception { loginSysAdmin(); - String email = "tenant2@thingsboard.org"; - User user = new User(); - user.setAuthority(Authority.TENANT_ADMIN); - user.setTenantId(tenantId); - user.setEmail(email); - user.setFirstName("Joe"); - user.setLastName("Downs"); + User user = createTenantAdminUser(); User savedUser = doPost("/api/user", user, User.class); User foundUser = doGet("/api/user/" + savedUser.getId().getId().toString(), User.class); @@ -286,15 +258,12 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { Mockito.reset(tbClusterService, auditLogService); - String email = TENANT_ADMIN_EMAIL; User user = new User(); user.setAuthority(Authority.TENANT_ADMIN); user.setTenantId(tenantId); - user.setEmail(email); - user.setFirstName("Joe"); - user.setLastName("Downs"); + user.setEmail(TENANT_ADMIN_EMAIL); - String msgError = "User with email '" + email + "' already present in database"; + String msgError = "User with email '" + TENANT_ADMIN_EMAIL + "' already present in database"; doPost("/api/user", user) .andExpect(status().isBadRequest()) .andExpect(statusReason(containsString(msgError))); @@ -311,12 +280,8 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { Mockito.reset(tbClusterService, auditLogService); String email = "tenant_thingsboard.org"; - User user = new User(); - user.setAuthority(Authority.TENANT_ADMIN); - user.setTenantId(tenantId); + User user = createTenantAdminUser(); user.setEmail(email); - user.setFirstName("Joe"); - user.setLastName("Downs"); String msgError = "Invalid email address format '" + email + "'"; doPost("/api/user", user) @@ -377,13 +342,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { public void testDeleteUser() throws Exception { loginSysAdmin(); - String email = "tenant2@thingsboard.org"; - User user = new User(); - user.setAuthority(Authority.TENANT_ADMIN); - user.setTenantId(tenantId); - user.setEmail(email); - user.setFirstName("Joe"); - user.setLastName("Downs"); + User user = createTenantAdminUser(); User savedUser = doPost("/api/user", user, User.class); User foundUser = doGet("/api/user/" + savedUser.getId().getId().toString(), User.class); @@ -565,20 +524,10 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { public void testFindCustomerUsers() throws Exception { loginSysAdmin(); - User tenantAdmin = new User(); - tenantAdmin.setAuthority(Authority.TENANT_ADMIN); - tenantAdmin.setTenantId(tenantId); - tenantAdmin.setEmail("tenant2@thingsboard.org"); - tenantAdmin.setFirstName("Joe"); - tenantAdmin.setLastName("Downs"); - + User tenantAdmin = createTenantAdminUser(); createUserAndLogin(tenantAdmin, "testPassword1"); - Customer customer = new Customer(); - customer.setTitle("My customer"); - Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - - CustomerId customerId = savedCustomer.getId(); + CustomerId customerId = postCustomer(); List customerUsers = new ArrayList<>(); for (int i = 0; i < 56; i++) { @@ -615,47 +564,22 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { public void testFindCustomerUsersByEmail() throws Exception { loginSysAdmin(); - User tenantAdmin = new User(); - tenantAdmin.setAuthority(Authority.TENANT_ADMIN); - tenantAdmin.setTenantId(tenantId); - tenantAdmin.setEmail("tenant2@thingsboard.org"); - tenantAdmin.setFirstName("Joe"); - tenantAdmin.setLastName("Downs"); - + User tenantAdmin = createTenantAdminUser(); createUserAndLogin(tenantAdmin, "testPassword1"); - Customer customer = new Customer(); - customer.setTitle("My customer"); - Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - - CustomerId customerId = savedCustomer.getId(); + CustomerId customerId = postCustomer(); String email1 = "testEmail1"; - List customerUsersEmail1 = new ArrayList<>(); - - for (int i = 0; i < 74; i++) { - User user = new User(); - user.setAuthority(Authority.CUSTOMER_USER); - user.setCustomerId(customerId); - String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); - String email = email1 + suffix + "@thingsboard.org"; - email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase(); - user.setEmail(email); - customerUsersEmail1.add(doPost("/api/user", user, User.class)); - } - String email2 = "testEmail2"; - List customerUsersEmail2 = new ArrayList<>(); - - for (int i = 0; i < 92; i++) { - User user = new User(); - user.setAuthority(Authority.CUSTOMER_USER); - user.setCustomerId(customerId); - String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); - String email = email2 + suffix + "@thingsboard.org"; - email = i % 2 == 0 ? email.toLowerCase() : email.toUpperCase(); - user.setEmail(email); - customerUsersEmail2.add(doPost("/api/user", user, User.class)); + List customerUsersEmail1 = new ArrayList<>(); + List customerUsersEmail2= new ArrayList<>(); + for (int i = 0; i < 45; i++) { + User customerUser = createCustomerUser( customerId); + customerUser.setEmail(email1 + StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)) + "@thingsboard.org"); + customerUsersEmail1.add(doPost("/api/user", customerUser, User.class)); + + customerUser.setEmail(email2 + StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)) + "@thingsboard.org"); + customerUsersEmail2.add(doPost("/api/user", customerUser, User.class)); } List loadedCustomerUsersEmail1 = new ArrayList<>(); @@ -723,14 +647,18 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { @Test public void testDeleteUserWithDeleteRelationsOk() throws Exception { - UserId userId = createUser().getId(); + loginSysAdmin(); + User tenantAdminUser = createTenantAdminUser(); + UserId userId = doPost("/api/user", tenantAdminUser, User.class).getId(); testEntityDaoWithRelationsOk(tenantId, userId, "/api/user/" + userId); } @Ignore @Test public void testDeleteUserExceptionWithRelationsTransactional() throws Exception { - UserId userId = createUser().getId(); + loginSysAdmin(); + User tenantAdminUser = createTenantAdminUser("Joe", "Downs"); + UserId userId = doPost("/api/user", tenantAdminUser, User.class).getId(); testEntityDaoWithRelationsTransactionalException(userDao, tenantId, userId, "/api/user/" + userId); } @@ -862,180 +790,177 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { } @Test - public void shouldFindCustomerUsersByFirstName() throws Exception { + public void checkCustomerUserDoNotSeeTenantAndOtherCustomerUsers() throws Exception { loginSysAdmin(); - User tenantAdmin = new User(); - tenantAdmin.setAuthority(Authority.TENANT_ADMIN); - tenantAdmin.setTenantId(tenantId); - tenantAdmin.setEmail("tenant2@thingsboard.org"); - tenantAdmin.setFirstName("Joe"); - tenantAdmin.setLastName("Downs"); + User tenantAdmin = createTenantAdminUser("Joe", "Brown"); + createUserAndLogin(tenantAdmin, "testPassword1"); + + CustomerId customerId = postCustomer(); + User user = createCustomerUser("Joe", "Downs", customerId); + doPost("/api/user", user, User.class); + CustomerId customerId2 = postCustomer(); + User user2 = createCustomerUser(customerId2); + createUserAndLogin(user2, "testPassword2"); + + PageLink pageLink = new PageLink(10, 0, "Joe"); + List usersInfo = getUsersInfo(pageLink); + + Assert.assertEquals(usersInfo.size(), 0); + } + + @Test + public void shouldFindCustomerUsersByFirstName() throws Exception { + loginSysAdmin(); + User tenantAdmin = createTenantAdminUser(); createUserAndLogin(tenantAdmin, "testPassword1"); - Customer customer = new Customer(); - customer.setTitle("My customer"); - Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - CustomerId customerId = savedCustomer.getId(); + String searchText = "Philip"; - Customer customer2 = new Customer(); - customer2.setTitle("My customer2"); - Customer savedCustomer2 = doPost("/api/customer", customer2, Customer.class); - CustomerId customerId2 = savedCustomer2.getId(); + CustomerId customerId = postCustomer(); + CustomerId customerId2 = postCustomer(); - List customerUsers = new ArrayList<>(); + List customerUsersContainingWord = new ArrayList<>(); for (int i = 0; i < 10; i++) { - User user = new User(); - user.setAuthority(Authority.CUSTOMER_USER); - user.setCustomerId(customerId); - user.setFirstName("Name" + i); - user.setLastName("Lastname" + i); - user.setEmail("testCustomer" + i + "@thingsboard.org"); - customerUsers.add(doPost("/api/user", user, User.class)); - } - for (int i = 0; i < 10; i++) { - User user = new User(); - user.setAuthority(Authority.CUSTOMER_USER); - user.setCustomerId(customerId2); - user.setFirstName("SecondCustomerName" + i); - user.setLastName("SecondCustomerLastname" + i); - user.setEmail("SecondCustomerUser" + i + "@thingsboard.org"); - doPost("/api/user", user, User.class); + String suffix = StringUtils.randomAlphabetic((int) (5 + Math.random() * 10)); + + customerUsersContainingWord.add(doPost("/api/user", createCustomerUser(searchText + i, "Last" + i, customerId), User.class)); + customerUsersContainingWord.add(doPost("/api/user", createCustomerUser(null, null, searchText + suffix + "@thingsboard.org", customerId), User.class)); + doPost("/api/user", createCustomerUser(null, null, customerId), User.class); + + doPost("/api/user", createCustomerUser(searchText + i, "Last" + i, customerId2), User.class); } - User user = new User(); - user.setAuthority(Authority.CUSTOMER_USER); - user.setCustomerId(customerId); - user.setEmail("testCustomerUser@thingsboard.org"); - createUserAndLogin(user, "testPassword2"); + createUserAndLogin(createCustomerUser(customerId), "testPassword2"); - // find user my name - List loadedCustomerUsers = new ArrayList<>(); - PageLink pageLink = new PageLink(10, 0, "Name"); - PageData pageData = null; - do { - pageData = doGetTypedWithPageLink("/api/users/info?", - new TypeReference<>() { - }, pageLink); - loadedCustomerUsers.addAll(pageData.getData()); - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } while (pageData.hasNext()); + // find users by search text + PageLink pageLink = new PageLink(10, 0, searchText); + List usersInfo = getUsersInfo(pageLink); - List customerUserDatas = customerUsers.stream().map(customerUser -> new UserData(customerUser.getId(), - customerUser.getEmail(), customerUser.getFirstName(), customerUser.getLastName())) + List expectedUserInfos = customerUsersContainingWord.stream().map(customerUser -> new UserData(customerUser.getId(), + customerUser.getEmail(), customerUser.getFirstName() == null ? "" : customerUser.getFirstName(), + customerUser.getLastName() == null ? "" : customerUser.getLastName())) .sorted(userDataIdComparator).collect(Collectors.toList()); - loadedCustomerUsers.sort(userDataIdComparator); + usersInfo.sort(userDataIdComparator); - Assert.assertEquals(customerUserDatas, loadedCustomerUsers); + Assert.assertEquals(expectedUserInfos, usersInfo); - // find user my full name - loadedCustomerUsers.clear(); - pageLink = new PageLink(10, 0, "Name3"); - pageData = doGetTypedWithPageLink("/api/users/info?", - new TypeReference<>() { - }, pageLink); - loadedCustomerUsers.addAll(pageData.getData()); - Assert.assertEquals(pageData.getData().size(), 1); - Assert.assertEquals(pageData.getData().get(0).getEmail(), "testCustomer3@thingsboard.org"); + // find user by full name + pageLink = new PageLink(10, 0, searchText + "5"); + usersInfo = getUsersInfo(pageLink); + Assert.assertEquals(1, usersInfo.size()); //clear users loginUser(tenantAdmin.getEmail(), "testPassword1"); doDelete("/api/customer/" + customerId.getId().toString()) .andExpect(status().isOk()); + doDelete("/api/customer/" + customerId2.getId().toString()) + .andExpect(status().isOk()); } @Test - public void shouldFindTenantUsersByLastName() throws Exception { + public void shouldFindTenantUsersByTextFromLastName() throws Exception { loginSysAdmin(); - User tenantAdmin = new User(); - tenantAdmin.setAuthority(Authority.TENANT_ADMIN); - tenantAdmin.setTenantId(tenantId); - tenantAdmin.setEmail("tenant2@thingsboard.org"); - tenantAdmin.setFirstName("Joe"); - tenantAdmin.setLastName("Downs"); - + User tenantAdmin = createTenantAdminUser(); createUserAndLogin(tenantAdmin, "testPassword1"); + CustomerId customerId = postCustomer(); + CustomerId customerId2 = postCustomer(); - Customer customer = new Customer(); - customer.setTitle("My customer"); - Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - CustomerId customerId = savedCustomer.getId(); - - Customer customer2 = new Customer(); - customer2.setTitle("My customer2"); - Customer savedCustomer2 = doPost("/api/customer", customer2, Customer.class); - CustomerId customerId2 = savedCustomer2.getId(); + String searchText = "Brown"; - List customerUsers = new ArrayList<>(); + List usersContainingWord = new ArrayList<>(); for (int i = 0; i < 10; i++) { - User user = new User(); - user.setAuthority(Authority.CUSTOMER_USER); - user.setCustomerId(customerId); - user.setFirstName("Name" + i); - user.setLastName("Lastname" + i); - user.setEmail("testCustomer" + i + "@thingsboard.org"); - customerUsers.add(doPost("/api/user", user, User.class)); - } - for (int i = 0; i < 10; i++) { - User user = new User(); - user.setAuthority(Authority.CUSTOMER_USER); - user.setCustomerId(customerId2); - user.setFirstName("SecondCustomerName" + i); - user.setLastName("SecondCustomerLastname" + i); - user.setEmail("SecondCustomerUser" + i + "@thingsboard.org"); - customerUsers.add(doPost("/api/user", user, User.class)); + String suffix = StringUtils.randomAlphabetic((int) (5 + Math.random() * 10)); + usersContainingWord.add(doPost("/api/user", createCustomerUser("First" + i, searchText + i, customerId), User.class)); + usersContainingWord.add(doPost("/api/user", createCustomerUser(null, null, searchText + suffix + "@thingsboard.org", customerId), User.class)); + + suffix = StringUtils.randomAlphabetic((int) (5 + Math.random() * 10)); + usersContainingWord.add(doPost("/api/user", createCustomerUser("First" + i, searchText + i, customerId2), User.class)); + usersContainingWord.add(doPost("/api/user", createCustomerUser(null, null, searchText + suffix + "@thingsboard.org", customerId2), User.class)); } - // find user my name - List loadedCustomerUsers = new ArrayList<>(); - PageLink pageLink = new PageLink(10, 0, "Name"); - PageData pageData = null; - do { - pageData = doGetTypedWithPageLink("/api/users/info?", - new TypeReference<>() { - }, pageLink); - loadedCustomerUsers.addAll(pageData.getData()); - if (pageData.hasNext()) { - pageLink = pageLink.nextPageLink(); - } - } while (pageData.hasNext()); + loginDifferentTenant(); + CustomerId customerId3 = postCustomer(); + doPost("/api/user", createCustomerUser("Jane", searchText, customerId3), User.class); - List customerUserDatas = customerUsers.stream().map(customerUser -> new UserData(customerUser.getId(), - customerUser.getEmail(), customerUser.getFirstName(), customerUser.getLastName())) + // find users by search text + loginUser(tenantAdmin.getEmail(), "testPassword1"); + PageLink pageLink = new PageLink(10, 0, searchText); + List usersInfo = getUsersInfo(pageLink); + + List expectedUserInfos = usersContainingWord.stream().map(customerUser -> new UserData(customerUser.getId(), + customerUser.getEmail(), customerUser.getFirstName() == null ? "" : customerUser.getFirstName(), + customerUser.getLastName() == null ? "" : customerUser.getLastName())) .sorted(userDataIdComparator).collect(Collectors.toList()); - loadedCustomerUsers.sort(userDataIdComparator); + usersInfo.sort(userDataIdComparator); - Assert.assertEquals(customerUserDatas, loadedCustomerUsers); + Assert.assertEquals(expectedUserInfos, usersInfo); - // find user my full name - loadedCustomerUsers.clear(); - pageLink = new PageLink(10, 0, "SecondCustomerLastname3"); - pageData = doGetTypedWithPageLink("/api/users/info?", - new TypeReference<>() { - }, pageLink); - loadedCustomerUsers.addAll(pageData.getData()); - Assert.assertEquals(pageData.getData().size(), 1); - Assert.assertEquals(pageData.getData().get(0).getEmail(), "SecondCustomerUser3@thingsboard.org"); + // find user by full last name + pageLink = new PageLink(10, 0, searchText + "3"); + usersInfo = getUsersInfo(pageLink); + Assert.assertEquals(2, usersInfo.size()); //clear users - loginUser(tenantAdmin.getEmail(), "testPassword1"); doDelete("/api/customer/" + customerId.getId().toString()) .andExpect(status().isOk()); + doDelete("/api/customer/" + customerId2.getId().toString()) + .andExpect(status().isOk()); } - private User createUser() throws Exception { - loginSysAdmin(); - String email = "tenant2@thingsboard.org"; + private CustomerId postCustomer() { + Customer customer = new Customer(); + customer.setTitle(StringUtils.randomAlphabetic(9)); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + return savedCustomer.getId(); + } + + private static User createCustomerUser(CustomerId customerId) { + return createCustomerUser(null, null, customerId); + } + private static User createCustomerUser(String firstName, String lastName, CustomerId customerId) { + String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); + return createCustomerUser(firstName, lastName, "testMail" + suffix + "@thingsboard.org", customerId); + } + + private static User createCustomerUser(String firstName, String lastName, String email, CustomerId customerId) { User user = new User(); - user.setAuthority(Authority.TENANT_ADMIN); - user.setTenantId(tenantId); + user.setAuthority(Authority.CUSTOMER_USER); + user.setFirstName(firstName); + user.setLastName(lastName); + user.setCustomerId(customerId); user.setEmail(email); - user.setFirstName("Joe"); - user.setLastName("Downs"); - return doPost("/api/user", user, User.class); + return user; + } + + private User createTenantAdminUser() { + return createTenantAdminUser(null, null); + } + private User createTenantAdminUser(String firstName, String lastName) { + String suffix = StringUtils.randomAlphanumeric((int) (5 + Math.random() * 10)); + + User tenantAdmin = new User(); + tenantAdmin.setAuthority(Authority.TENANT_ADMIN); + tenantAdmin.setTenantId(tenantId); + tenantAdmin.setEmail("testEmail" + suffix + "@thingsbord.org"); + tenantAdmin.setFirstName(firstName); + tenantAdmin.setLastName(lastName); + return tenantAdmin; } + + private List getUsersInfo(PageLink pageLink) throws Exception { + List loadedCustomerUsers = new ArrayList<>(); + PageData pageData = null; + do { + pageData = doGetTypedWithPageLink("/api/users/info?", new TypeReference<>() {}, pageLink); + loadedCustomerUsers.addAll(pageData.getData()); + if (pageData.hasNext()) { + pageLink = pageLink.nextPageLink(); + } + } while (pageData.hasNext()); + return loadedCustomerUsers; + } + } From a111473a8f0896e84f19e27c1268a395857350e6 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 17 Feb 2023 00:12:11 +0200 Subject: [PATCH 7/9] minor improvement --- .../server/controller/BaseUserControllerTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java index d78b8b08ef..3efecf3ca2 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java @@ -811,7 +811,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { } @Test - public void shouldFindCustomerUsersByFirstName() throws Exception { + public void shouldFindCustomerUsersBySearchText() throws Exception { loginSysAdmin(); User tenantAdmin = createTenantAdminUser(); createUserAndLogin(tenantAdmin, "testPassword1"); @@ -829,7 +829,9 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { customerUsersContainingWord.add(doPost("/api/user", createCustomerUser(null, null, searchText + suffix + "@thingsboard.org", customerId), User.class)); doPost("/api/user", createCustomerUser(null, null, customerId), User.class); + suffix = StringUtils.randomAlphabetic((int) (5 + Math.random() * 10)); doPost("/api/user", createCustomerUser(searchText + i, "Last" + i, customerId2), User.class); + doPost("/api/user", createCustomerUser(null, null, searchText + suffix + "@thingsboard.org", customerId2), User.class); } createUserAndLogin(createCustomerUser(customerId), "testPassword2"); @@ -860,7 +862,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { } @Test - public void shouldFindTenantUsersByTextFromLastName() throws Exception { + public void shouldFindTenantUsersBySearchText() throws Exception { loginSysAdmin(); User tenantAdmin = createTenantAdminUser(); @@ -875,6 +877,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { String suffix = StringUtils.randomAlphabetic((int) (5 + Math.random() * 10)); usersContainingWord.add(doPost("/api/user", createCustomerUser("First" + i, searchText + i, customerId), User.class)); usersContainingWord.add(doPost("/api/user", createCustomerUser(null, null, searchText + suffix + "@thingsboard.org", customerId), User.class)); + doPost("/api/user", createCustomerUser(null, null, customerId), User.class); suffix = StringUtils.randomAlphabetic((int) (5 + Math.random() * 10)); usersContainingWord.add(doPost("/api/user", createCustomerUser("First" + i, searchText + i, customerId2), User.class)); From 5dec719947d586674ae33f99a1a787943a6ebc66 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 17 Feb 2023 10:45:42 +0200 Subject: [PATCH 8/9] minor improvements to tests --- .../server/controller/UserController.java | 8 ++--- .../controller/BaseUserControllerTest.java | 30 ++++++++++++++----- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index 6177bdc74b..ef6f7b4075 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -351,11 +351,11 @@ public class UserController extends BaseController { return entityQueryService.findEntityDataByQuery(securityUser, query).mapData(entityData -> { - Map keyValueMap = entityData.getLatest().get(ENTITY_FIELD); + Map fieldValues = entityData.getLatest().get(ENTITY_FIELD); return new UserData(UserId.fromString(entityData.getEntityId().getId().toString()), - keyValueMap.get("email").getValue(), - keyValueMap.get("firstName").getValue(), - keyValueMap.get("lastName").getValue()); + fieldValues.get("email").getValue(), + fieldValues.get("firstName").getValue(), + fieldValues.get("lastName").getValue()); }); } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java index 3efecf3ca2..b677a47b13 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java @@ -790,24 +790,40 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { } @Test - public void checkCustomerUserDoNotSeeTenantAndOtherCustomerUsers() throws Exception { + public void checkCustomerUserDoNotSeeTenantUsersOtherTenantUsersOtherCustomerUsers() throws Exception { loginSysAdmin(); + String searchText = "Joe"; - User tenantAdmin = createTenantAdminUser("Joe", "Brown"); + loginDifferentTenant(); + CustomerId customerId1 = postCustomer(); + doPost("/api/user", createCustomerUser(searchText, "Ress", customerId1), User.class); + + loginSysAdmin(); + User tenantAdmin = createTenantAdminUser(searchText, "Brown"); createUserAndLogin(tenantAdmin, "testPassword1"); - CustomerId customerId = postCustomer(); - User user = createCustomerUser("Joe", "Downs", customerId); + CustomerId customerId2 = postCustomer(); + User user = createCustomerUser(searchText, "Downs", customerId2); doPost("/api/user", user, User.class); - CustomerId customerId2 = postCustomer(); - User user2 = createCustomerUser(customerId2); + CustomerId customerId3 = postCustomer(); + User user2 = createCustomerUser(customerId3); createUserAndLogin(user2, "testPassword2"); - PageLink pageLink = new PageLink(10, 0, "Joe"); + PageLink pageLink = new PageLink(10, 0, searchText); List usersInfo = getUsersInfo(pageLink); Assert.assertEquals(usersInfo.size(), 0); + + //clear users + loginDifferentTenant(); + doDelete("/api/customer/" + customerId1.getId().toString()) + .andExpect(status().isOk()); + loginUser(tenantAdmin.getEmail(), "testPassword1"); + doDelete("/api/customer/" + customerId2.getId().toString()) + .andExpect(status().isOk()); + doDelete("/api/customer/" + customerId3.getId().toString()) + .andExpect(status().isOk()); } @Test From b261cb2ab1b7af75c1d47ab51ace645eb8e29be6 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Fri, 17 Feb 2023 11:12:46 +0200 Subject: [PATCH 9/9] renamed UserData to UserEmailInfo --- .../server/controller/UserController.java | 8 +++---- .../controller/BaseUserControllerTest.java | 21 +++++++++---------- .../{UserData.java => UserEmailInfo.java} | 2 +- 3 files changed, 14 insertions(+), 17 deletions(-) rename common/data/src/main/java/org/thingsboard/server/common/data/{UserData.java => UserEmailInfo.java} (96%) diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index ef6f7b4075..e57bb73262 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -41,7 +41,7 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.UserData; +import org.thingsboard.server.common.data.UserEmailInfo; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; @@ -51,7 +51,6 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.query.EntityDataPageLink; import org.thingsboard.server.common.data.query.EntityDataQuery; -import org.thingsboard.server.common.data.query.EntityDataSortOrder; import org.thingsboard.server.common.data.query.EntityKey; import org.thingsboard.server.common.data.query.EntityTypeFilter; import org.thingsboard.server.common.data.query.TsValue; @@ -76,7 +75,6 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -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.CUSTOMER_ID; import static org.thingsboard.server.controller.ControllerConstants.CUSTOMER_ID_PARAM_DESCRIPTION; @@ -327,7 +325,7 @@ public class UserController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/users/info", method = RequestMethod.GET) @ResponseBody - public PageData findUsersByQuery( + public PageData findUsersByQuery( @ApiParam(value = PAGE_SIZE_DESCRIPTION, required = true) @RequestParam int pageSize, @ApiParam(value = PAGE_NUMBER_DESCRIPTION, required = true) @@ -352,7 +350,7 @@ public class UserController extends BaseController { return entityQueryService.findEntityDataByQuery(securityUser, query).mapData(entityData -> { Map fieldValues = entityData.getLatest().get(ENTITY_FIELD); - return new UserData(UserId.fromString(entityData.getEntityId().getId().toString()), + return new UserEmailInfo(UserId.fromString(entityData.getEntityId().getId().toString()), fieldValues.get("email").getValue(), fieldValues.get("firstName").getValue(), fieldValues.get("lastName").getValue()); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java index b677a47b13..f289c8066f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseUserControllerTest.java @@ -18,7 +18,6 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import org.jetbrains.annotations.NotNull; import org.junit.After; import org.junit.Assert; import org.junit.Ignore; @@ -35,7 +34,7 @@ import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.UserData; +import org.thingsboard.server.common.data.UserEmailInfo; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; @@ -64,7 +63,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.SYSTEM_TENANT; public abstract class BaseUserControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); - private IdComparator userDataIdComparator = new IdComparator<>(); + private IdComparator userDataIdComparator = new IdComparator<>(); private CustomerId customerNUULId = (CustomerId) createEntityId_NULL_UUID(new Customer()); @@ -811,7 +810,7 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { createUserAndLogin(user2, "testPassword2"); PageLink pageLink = new PageLink(10, 0, searchText); - List usersInfo = getUsersInfo(pageLink); + List usersInfo = getUsersInfo(pageLink); Assert.assertEquals(usersInfo.size(), 0); @@ -854,9 +853,9 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { // find users by search text PageLink pageLink = new PageLink(10, 0, searchText); - List usersInfo = getUsersInfo(pageLink); + List usersInfo = getUsersInfo(pageLink); - List expectedUserInfos = customerUsersContainingWord.stream().map(customerUser -> new UserData(customerUser.getId(), + List expectedUserInfos = customerUsersContainingWord.stream().map(customerUser -> new UserEmailInfo(customerUser.getId(), customerUser.getEmail(), customerUser.getFirstName() == null ? "" : customerUser.getFirstName(), customerUser.getLastName() == null ? "" : customerUser.getLastName())) .sorted(userDataIdComparator).collect(Collectors.toList()); @@ -907,9 +906,9 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { // find users by search text loginUser(tenantAdmin.getEmail(), "testPassword1"); PageLink pageLink = new PageLink(10, 0, searchText); - List usersInfo = getUsersInfo(pageLink); + List usersInfo = getUsersInfo(pageLink); - List expectedUserInfos = usersContainingWord.stream().map(customerUser -> new UserData(customerUser.getId(), + List expectedUserInfos = usersContainingWord.stream().map(customerUser -> new UserEmailInfo(customerUser.getId(), customerUser.getEmail(), customerUser.getFirstName() == null ? "" : customerUser.getFirstName(), customerUser.getLastName() == null ? "" : customerUser.getLastName())) .sorted(userDataIdComparator).collect(Collectors.toList()); @@ -969,9 +968,9 @@ public abstract class BaseUserControllerTest extends AbstractControllerTest { return tenantAdmin; } - private List getUsersInfo(PageLink pageLink) throws Exception { - List loadedCustomerUsers = new ArrayList<>(); - PageData pageData = null; + private List getUsersInfo(PageLink pageLink) throws Exception { + List loadedCustomerUsers = new ArrayList<>(); + PageData pageData = null; do { pageData = doGetTypedWithPageLink("/api/users/info?", new TypeReference<>() {}, pageLink); loadedCustomerUsers.addAll(pageData.getData()); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/UserData.java b/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java similarity index 96% rename from common/data/src/main/java/org/thingsboard/server/common/data/UserData.java rename to common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java index 8edb5ec7cf..f1eb95c805 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/UserData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/UserEmailInfo.java @@ -25,7 +25,7 @@ import org.thingsboard.server.common.data.id.UserId; @ApiModel @Data @AllArgsConstructor -public class UserData implements HasId { +public class UserEmailInfo implements HasId { @ApiModelProperty(position = 1, value = "User id") private UserId id;