Add proper path validation 80/103980/4
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 11 Jan 2023 00:03:25 +0000 (01:03 +0100)
committerRobert Varga <nite@hq.sk>
Mon, 30 Jan 2023 15:00:31 +0000 (15:00 +0000)
Rather than incurring CCEs, make sure actually validate data and report
what is wrong.

Change-Id: I70b8172732e08bc44c999bea05ff5c0ce28beff0
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
restconf/restconf-nb/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/CreateStreamUtil.java

index 71e22d205dca927511aa78467a84f817cebac8ef..9ddce5fbae6a464842f1815d3646f0539ddcd54a 100644 (file)
@@ -39,6 +39,7 @@ import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
@@ -156,18 +157,23 @@ final class CreateStreamUtil {
         // FIXME: ugly cast
         final ContainerNode data = (ContainerNode) requireNonNull(payload).getData();
         // FIXME: ugly cast
-        final YangInstanceIdentifier value =
+        final YangInstanceIdentifier path =
             (YangInstanceIdentifier) data.findChildByArg(DEVICE_NOTIFICATION_PATH_NODEID)
                 .map(DataContainerChild::body)
-                .orElseThrow(() -> new RestconfDocumentedException("Mount point not available", ErrorType.APPLICATION,
-                    ErrorTag.OPERATION_FAILED));
+                .orElseThrow(() -> new RestconfDocumentedException("No path specified", ErrorType.APPLICATION,
+                    ErrorTag.DATA_MISSING));
 
-        // FIXME: just beautiful: a ClassCastException if it is something different!
-        final String deviceName =
-            ((YangInstanceIdentifier.NodeIdentifierWithPredicates.Singleton)value.getLastPathArgument())
-            .values().getElement().toString();
+        if (!(path.getLastPathArgument() instanceof NodeIdentifierWithPredicates listId)) {
+            throw new RestconfDocumentedException("Path does not refer to a list item", ErrorType.APPLICATION,
+                ErrorTag.INVALID_VALUE);
+        }
+        if (listId.size() != 1) {
+            throw new RestconfDocumentedException("Target list uses multiple keys", ErrorType.APPLICATION,
+                ErrorTag.INVALID_VALUE);
+        }
+        final String deviceName = listId.values().iterator().next().toString();
 
-        final DOMMountPoint mountPoint = mountPointService.getMountPoint(value)
+        final DOMMountPoint mountPoint = mountPointService.getMountPoint(path)
             .orElseThrow(() -> new RestconfDocumentedException("Mount point not available", ErrorType.APPLICATION,
                 ErrorTag.OPERATION_FAILED));