Files
infix/package/rousette/0011-restconf-add-internal-RPC-handler-dispatcher.patch
T
Joachim Wiberg 096a8ab2e2 package/rousette: use v2-kkit branch for reduced patch set
To be able to maintain our own set of patches on top rousette, a kkit
branch have been set up with a reduced set of backported fixes.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-09-28 07:26:43 +02:00

93 lines
3.9 KiB
Diff

From d72adb3da31cb509e64c8f33174e375fa9468b0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <tomas.pecka@cesnet.cz>
Date: Mon, 19 May 2025 12:23:16 +0200
Subject: [PATCH 11/13] restconf: add internal RPC handler dispatcher
Organization: Wires
This code adds a new internal RPC handler dispatcher that checks if user
is authorized to call the RPC (we are bypassing sysrepo, so we have to
check this manually) and then calls the RPC handler.
So far, there are no RPCs processed, but support for the
ietf-subscribed-notifications:establish-subscription RPC is coming soon.
Change-Id: I99121a511011229e4098f95e91601b39d333444a
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/restconf/Server.cpp | 24 ++++++++++++++++++++----
tests/restconf-rpc.cpp | 18 ++++++++++++++++++
2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/src/restconf/Server.cpp b/src/restconf/Server.cpp
index 8544210..74c06f7 100644
--- a/src/restconf/Server.cpp
+++ b/src/restconf/Server.cpp
@@ -438,10 +438,26 @@ libyang::CreatedNodes createEditForPutAndPatch(libyang::Context& ctx, const std:
return {editNode, replacementNode};
}
-std::optional<libyang::DataNode> processInternalRPC(sysrepo::Session&, const libyang::DataNode&)
+std::optional<libyang::DataNode> processInternalRPC(sysrepo::Session& sess, const libyang::DataNode& rpcInput, const libyang::DataFormat requestEncoding)
{
- // TODO: Implement internal RPCs
- throw ErrorResponse(501, "application", "operation-not-supported", "Internal RPCs are not yet supported.");
+ using InternalRPCHandler = std::function<void(sysrepo::Session&, const libyang::DataFormat, const libyang::DataNode&, libyang::DataNode&)>;
+ const std::map<std::string, InternalRPCHandler> handlers;
+
+ const auto rpcPath = rpcInput.path();
+
+ // Is the user authorized to call the operation?
+ auto [parent, rpcNode] = sess.getContext().newPath2(rpcPath, std::nullopt);
+ if (!sess.checkNacmOperation(*rpcNode)) {
+ throw ErrorResponse(403, "application", "access-denied", "Access denied.", rpcNode->path());
+ }
+
+ if (auto it = handlers.find(rpcPath); it != handlers.end()) {
+ auto [parent, rpcOutput] = sess.getContext().newPath2(rpcPath, std::nullopt);
+ it->second(sess, requestEncoding, rpcInput, *rpcOutput);
+ return *parent;
+ }
+
+ throw ErrorResponse(501, "application", "operation-not-supported", "Unsupported RPC call to " + rpcPath, rpcPath);
}
void processActionOrRPC(std::shared_ptr<RequestContext> requestCtx, const std::chrono::milliseconds timeout)
@@ -478,7 +494,7 @@ void processActionOrRPC(std::shared_ptr<RequestContext> requestCtx, const std::c
if (requestCtx->restconfRequest.type == RestconfRequest::Type::Execute) {
rpcReply = requestCtx->sess.sendRPC(*rpcNode, timeout);
} else if (requestCtx->restconfRequest.type == RestconfRequest::Type::ExecuteInternal) {
- rpcReply = processInternalRPC(requestCtx->sess, *rpcNode);
+ rpcReply = processInternalRPC(requestCtx->sess, *rpcNode, *requestCtx->dataFormat.request);
}
if (!rpcReply || rpcReply->immediateChildren().empty()) {
diff --git a/tests/restconf-rpc.cpp b/tests/restconf-rpc.cpp
index a3e9309..43aaed4 100644
--- a/tests/restconf-rpc.cpp
+++ b/tests/restconf-rpc.cpp
@@ -420,4 +420,22 @@ TEST_CASE("invoking actions and rpcs")
)"});
}
}
+
+ SECTION("Internal RPC handlers")
+ {
+ // check NACM access
+ REQUIRE(post(RESTCONF_OPER_ROOT "/ietf-subscribed-notifications:kill-subscription", {CONTENT_TYPE_JSON}, R"({"ietf-subscribed-notifications:input": {}})") == Response{403, jsonHeaders, R"({
+ "ietf-restconf:errors": {
+ "error": [
+ {
+ "error-type": "application",
+ "error-tag": "access-denied",
+ "error-path": "/ietf-subscribed-notifications:kill-subscription",
+ "error-message": "Access denied."
+ }
+ ]
+ }
+}
+)"});
+ }
}
--
2.43.0