added REST method in UserController to get users by query

This commit is contained in:
dashevchenko 2023-02-16 00:37:10 +02:00
parent 42c7a59f27
commit 559b741749
4 changed files with 146 additions and 0 deletions

View File

@ -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<UserData> 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<EntityKey> entityFields = Arrays.asList(new EntityKey(ENTITY_FIELD, "firstName"),
new EntityKey(ENTITY_FIELD, "lastName"),
new EntityKey(ENTITY_FIELD, "email"));
List<KeyFilter> 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;
}
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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<String> {
private StringOperation operation;