Harden item creation by checking for validity of name (#1825)
Signed-off-by: Kai Kreuzer <kai@openhab.org>pull/1837/head
parent
d5e7fe3ab3
commit
70ca7655a2
|
@ -576,8 +576,8 @@ public class ItemResource implements RESTResource {
|
|||
@SecurityRequirement(name = "oauth2", scopes = { "admin" }) }, responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class))),
|
||||
@ApiResponse(responseCode = "201", description = "Item created."),
|
||||
@ApiResponse(responseCode = "400", description = "Item null."),
|
||||
@ApiResponse(responseCode = "404", description = "Item not found."),
|
||||
@ApiResponse(responseCode = "400", description = "Payload invalid."),
|
||||
@ApiResponse(responseCode = "404", description = "Item not found or name in path invalid."),
|
||||
@ApiResponse(responseCode = "405", description = "Item not editable.") })
|
||||
public Response createOrUpdateItem(final @Context UriInfo uriInfo, final @Context HttpHeaders httpHeaders,
|
||||
@HeaderParam(HttpHeaders.ACCEPT_LANGUAGE) @Parameter(description = "language") @Nullable String language,
|
||||
|
@ -588,31 +588,42 @@ public class ItemResource implements RESTResource {
|
|||
// If we didn't get an item bean, then return!
|
||||
if (item == null) {
|
||||
return Response.status(Status.BAD_REQUEST).build();
|
||||
}
|
||||
|
||||
Item newItem = ItemDTOMapper.map(item, itemBuilderFactory);
|
||||
if (newItem == null) {
|
||||
logger.warn("Received HTTP PUT request at '{}' with an invalid item type '{}'.", uriInfo.getPath(),
|
||||
item.type);
|
||||
} else if (!itemname.equalsIgnoreCase((item.name))) {
|
||||
logger.warn(
|
||||
"Received HTTP PUT request at '{}' with an item name '{}' that does not match the one in the url.",
|
||||
uriInfo.getPath(), item.name);
|
||||
return Response.status(Status.BAD_REQUEST).build();
|
||||
}
|
||||
|
||||
// Save the item
|
||||
if (getItem(itemname) == null) {
|
||||
// item does not yet exist, create it
|
||||
managedItemProvider.add(newItem);
|
||||
return getItemResponse(uriBuilder(uriInfo, httpHeaders), Status.CREATED, itemRegistry.get(itemname), locale,
|
||||
null);
|
||||
} else if (managedItemProvider.get(itemname) != null) {
|
||||
// item already exists as a managed item, update it
|
||||
managedItemProvider.update(newItem);
|
||||
return getItemResponse(uriBuilder(uriInfo, httpHeaders), Status.OK, itemRegistry.get(itemname), locale,
|
||||
null);
|
||||
} else {
|
||||
// Item exists but cannot be updated
|
||||
logger.warn("Cannot update existing item '{}', because is not managed.", itemname);
|
||||
return JSONResponse.createErrorResponse(Status.METHOD_NOT_ALLOWED,
|
||||
"Cannot update non-managed Item " + itemname);
|
||||
try {
|
||||
Item newItem = ItemDTOMapper.map(item, itemBuilderFactory);
|
||||
if (newItem == null) {
|
||||
logger.warn("Received HTTP PUT request at '{}' with an invalid item type '{}'.", uriInfo.getPath(),
|
||||
item.type);
|
||||
return Response.status(Status.BAD_REQUEST).build();
|
||||
}
|
||||
|
||||
// Save the item
|
||||
if (getItem(itemname) == null) {
|
||||
// item does not yet exist, create it
|
||||
managedItemProvider.add(newItem);
|
||||
return getItemResponse(uriBuilder(uriInfo, httpHeaders), Status.CREATED, itemRegistry.get(itemname),
|
||||
locale, null);
|
||||
} else if (managedItemProvider.get(itemname) != null) {
|
||||
// item already exists as a managed item, update it
|
||||
managedItemProvider.update(newItem);
|
||||
return getItemResponse(uriBuilder(uriInfo, httpHeaders), Status.OK, itemRegistry.get(itemname), locale,
|
||||
null);
|
||||
} else {
|
||||
// Item exists but cannot be updated
|
||||
logger.warn("Cannot update existing item '{}', because is not managed.", itemname);
|
||||
return JSONResponse.createErrorResponse(Status.METHOD_NOT_ALLOWED,
|
||||
"Cannot update non-managed Item " + itemname);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.warn("Received HTTP PUT request at '{}' with an invalid item name '{}'.", uriInfo.getPath(),
|
||||
item.name);
|
||||
return Response.status(Status.BAD_REQUEST).build();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,7 +639,7 @@ public class ItemResource implements RESTResource {
|
|||
@Operation(summary = "Adds a list of items to the registry or updates the existing items.", security = {
|
||||
@SecurityRequirement(name = "oauth2", scopes = { "admin" }) }, responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = String.class))),
|
||||
@ApiResponse(responseCode = "400", description = "Item list is null.") })
|
||||
@ApiResponse(responseCode = "400", description = "Payload is invalid.") })
|
||||
public Response createOrUpdateItems(
|
||||
@Parameter(description = "array of item data", required = true) GroupItemDTO @Nullable [] items) {
|
||||
// If we didn't get an item list bean, then return!
|
||||
|
@ -641,12 +652,17 @@ public class ItemResource implements RESTResource {
|
|||
Map<String, Collection<String>> tagMap = new HashMap<>();
|
||||
|
||||
for (GroupItemDTO item : items) {
|
||||
Item newItem = ItemDTOMapper.map(item, itemBuilderFactory);
|
||||
if (newItem == null) {
|
||||
wrongTypes.add(item);
|
||||
tagMap.put(item.name, item.tags);
|
||||
} else {
|
||||
activeItems.add(newItem);
|
||||
try {
|
||||
Item newItem = ItemDTOMapper.map(item, itemBuilderFactory);
|
||||
if (newItem == null) {
|
||||
wrongTypes.add(item);
|
||||
tagMap.put(item.name, item.tags);
|
||||
} else {
|
||||
activeItems.add(newItem);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.warn("Received HTTP PUT request with an invalid item name '{}'.", item.name);
|
||||
return Response.status(Status.BAD_REQUEST).build();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ public class ManagedItemProvider extends AbstractManagedProvider<Item, String, P
|
|||
}
|
||||
|
||||
/**
|
||||
* Removes an item and it´s member if recursive flag is set to true.
|
||||
* Removes an item and its member if recursive flag is set to true.
|
||||
*
|
||||
* @param itemName item name to remove
|
||||
* @param recursive if set to true all members of the item will be removed, too.
|
||||
|
@ -105,6 +105,14 @@ public class ManagedItemProvider extends AbstractManagedProvider<Item, String, P
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Item element) {
|
||||
if (!ItemUtil.isValidItemName(element.getName())) {
|
||||
throw new IllegalArgumentException("The item name '" + element.getName() + "' is invalid.");
|
||||
}
|
||||
super.add(element);
|
||||
}
|
||||
|
||||
private List<String> getMemberNamesRecursively(GroupItem groupItem, Collection<Item> allItems) {
|
||||
List<String> memberNames = new ArrayList<>();
|
||||
for (Item item : allItems) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.openhab.core.items.GroupItem;
|
|||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.items.ItemBuilder;
|
||||
import org.openhab.core.items.ItemBuilderFactory;
|
||||
import org.openhab.core.items.ItemUtil;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
|
@ -52,6 +53,10 @@ public class ItemDTOMapper {
|
|||
throw new IllegalArgumentException("The argument 'itemBuilderFactory' must no be null.");
|
||||
}
|
||||
|
||||
if (!ItemUtil.isValidItemName(itemDTO.name)) {
|
||||
throw new IllegalArgumentException("The item name '" + itemDTO.name + "' is invalid.");
|
||||
}
|
||||
|
||||
if (itemDTO.type != null) {
|
||||
ItemBuilder builder = itemBuilderFactory.newItemBuilder(itemDTO.type, itemDTO.name);
|
||||
|
||||
|
|
Loading…
Reference in New Issue