From 41d2f5a44784a9f94f2e543df47d9e007492e473 Mon Sep 17 00:00:00 2001 From: Dulana Peiris Date: Tue, 10 Oct 2023 12:28:07 +0530 Subject: [PATCH] Added basic shell command I/O functionality --- src/msg/bson/usrmsg_bson.cpp | 33 +++++++++++++++++++++++++++++++++ src/msg/bson/usrmsg_bson.hpp | 2 ++ src/msg/json/usrmsg_json.cpp | 32 ++++++++++++++++++++++++++++++++ src/msg/json/usrmsg_json.hpp | 2 ++ src/msg/usrmsg_common.hpp | 2 ++ src/msg/usrmsg_parser.cpp | 8 ++++++++ src/msg/usrmsg_parser.hpp | 2 ++ src/usr/usr.cpp | 16 ++++++++++++++++ 8 files changed, 97 insertions(+) diff --git a/src/msg/bson/usrmsg_bson.cpp b/src/msg/bson/usrmsg_bson.cpp index 7b7e26df..7f8eb79c 100644 --- a/src/msg/bson/usrmsg_bson.cpp +++ b/src/msg/bson/usrmsg_bson.cpp @@ -497,6 +497,39 @@ namespace msg::usrmsg::bson return 0; } + /** + * Extracts a contract shell input message sent by user. + * + * @param extracted_content The content to be passed to the contract, extracted from the message. + * @param d The bson document holding the shell input message. + * Accepted signed input container format: + * { + * "type": "contract_shell_input", + * "id": "", + * "content": + * } + * @return 0 on successful extraction. -1 for failure. + */ + int extract_shell_input(std::string &extracted_id, std::string &extracted_content, const jsoncons::ojson &d) + { + if (!d.contains(msg::usrmsg::FLD_ID) || !d[msg::usrmsg::FLD_ID].is()) + { + LOG_DEBUG << "Shell input 'id' field missing or invalid."; + return -1; + } + + if (!d.contains(msg::usrmsg::FLD_CONTENT) || !d[msg::usrmsg::FLD_CONTENT].is_byte_string_view()) + { + LOG_DEBUG << "Shell input 'content' field missing or invalid."; + return -1; + } + + extracted_id = d[msg::usrmsg::FLD_ID].as(); + const jsoncons::byte_string_view &bsv = d[msg::usrmsg::FLD_CONTENT].as_byte_string_view(); + extracted_content = std::string_view(reinterpret_cast(bsv.data()), bsv.size()); + return 0; + } + /** * Extracts a signed input container message sent by user. * diff --git a/src/msg/bson/usrmsg_bson.hpp b/src/msg/bson/usrmsg_bson.hpp index e5ac95dd..9a511f36 100644 --- a/src/msg/bson/usrmsg_bson.hpp +++ b/src/msg/bson/usrmsg_bson.hpp @@ -43,6 +43,8 @@ namespace msg::usrmsg::bson int extract_read_request(std::string &extracted_id, std::string &extracted_content, const jsoncons::ojson &d); + int extract_shell_input(std::string &extracted_id, std::string &extracted_content, const jsoncons::ojson &d); + int extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig, const jsoncons::ojson &d); diff --git a/src/msg/json/usrmsg_json.cpp b/src/msg/json/usrmsg_json.cpp index a4d5b7af..a867e99d 100644 --- a/src/msg/json/usrmsg_json.cpp +++ b/src/msg/json/usrmsg_json.cpp @@ -872,6 +872,38 @@ namespace msg::usrmsg::json return 0; } + /** + * Extracts a contract shell input message sent by user. + * + * @param extracted_content The content to be passed to the contract, extracted from the message. + * @param d The json document holding the shell input message. + * Accepted signed input container format: + * { + * "type": "contract_shell_input", + * "id": "", + * "content": "" + * } + * @return 0 on successful extraction. -1 for failure. + */ + int extract_shell_input(std::string &extracted_id, std::string &extracted_content, const jsoncons::json &d) + { + if (!d.contains(msg::usrmsg::FLD_ID) || !d[msg::usrmsg::FLD_ID].is()) + { + LOG_DEBUG << "Shell input 'id' field missing or invalid."; + return -1; + } + + if (!d.contains(msg::usrmsg::FLD_CONTENT) || !d[msg::usrmsg::FLD_CONTENT].is()) + { + LOG_DEBUG << "Shell input 'content' field missing or invalid."; + return -1; + } + + extracted_id = d[msg::usrmsg::FLD_ID].as(); + extracted_content = d[msg::usrmsg::FLD_CONTENT].as(); + return 0; + } + /** * Extracts a signed input container message sent by user. * diff --git a/src/msg/json/usrmsg_json.hpp b/src/msg/json/usrmsg_json.hpp index f959b8be..eef0e06c 100644 --- a/src/msg/json/usrmsg_json.hpp +++ b/src/msg/json/usrmsg_json.hpp @@ -47,6 +47,8 @@ namespace msg::usrmsg::json int extract_read_request(std::string &extracted_id, std::string &extracted_content, const jsoncons::json &d); + int extract_shell_input(std::string &extracted_id, std::string &extracted_content, const jsoncons::json &d); + int extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig, const jsoncons::json &d); diff --git a/src/msg/usrmsg_common.hpp b/src/msg/usrmsg_common.hpp index 3a6ca510..d8682e49 100644 --- a/src/msg/usrmsg_common.hpp +++ b/src/msg/usrmsg_common.hpp @@ -80,6 +80,8 @@ namespace msg::usrmsg constexpr const char *MSGTYPE_SERVER_CHALLENGE_RESPONSE = "server_challenge_response"; constexpr const char *MSGTYPE_CONTRACT_READ_REQUEST = "contract_read_request"; constexpr const char *MSGTYPE_CONTRACT_READ_RESPONSE = "contract_read_response"; + constexpr const char *MSGTYPE_CONTRACT_SHELL_INPUT = "contract_shell_input"; + constexpr const char *MSGTYPE_CONTRACT_SHELL_OUTPUT = "contract_shell_output"; constexpr const char *MSGTYPE_CONTRACT_INPUT = "contract_input"; constexpr const char *MSGTYPE_CONTRACT_INPUT_STATUS = "contract_input_status"; constexpr const char *MSGTYPE_CONTRACT_OUTPUT = "contract_output"; diff --git a/src/msg/usrmsg_parser.cpp b/src/msg/usrmsg_parser.cpp index 48a0b8ba..d87822f4 100644 --- a/src/msg/usrmsg_parser.cpp +++ b/src/msg/usrmsg_parser.cpp @@ -121,6 +121,14 @@ namespace msg::usrmsg return busrmsg::extract_read_request(extracted_id, extracted_content, bdoc); } + int usrmsg_parser::extract_shell_input(std::string &extracted_id, std::string &extracted_content) const + { + if (protocol == util::PROTOCOL::JSON) + return jusrmsg::extract_shell_input(extracted_id, extracted_content, jdoc); + else + return busrmsg::extract_shell_input(extracted_id, extracted_content, bdoc); + } + int usrmsg_parser::extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig) const { if (protocol == util::PROTOCOL::JSON) diff --git a/src/msg/usrmsg_parser.hpp b/src/msg/usrmsg_parser.hpp index 51ca0af9..8d721416 100644 --- a/src/msg/usrmsg_parser.hpp +++ b/src/msg/usrmsg_parser.hpp @@ -49,6 +49,8 @@ namespace msg::usrmsg int extract_read_request(std::string &extracted_id, std::string &extracted_content) const; + int extract_shell_input(std::string &extracted_id, std::string &extracted_content) const; + int extract_signed_input_container(std::string &extracted_input_container, std::string &extracted_sig) const; int extract_input_container(std::string &input, uint64_t &nonce, diff --git a/src/usr/usr.cpp b/src/usr/usr.cpp index 061f48e8..c7d672fb 100644 --- a/src/usr/usr.cpp +++ b/src/usr/usr.cpp @@ -272,6 +272,22 @@ namespace usr user.session.send(resp); return 0; } + else if (msg_type == msg::usrmsg::MSGTYPE_CONTRACT_SHELL_INPUT) + { + std::string id, content; + if (parser.extract_shell_input(id, content) != -1){ + LOG_INFO << "Received Shell Input."; + LOG_INFO << "User PubKey:" << user.pubkey; + LOG_INFO << "ID:" << id; + LOG_INFO << "Content:" << content; + return 0; + } + else + { + send_input_status(parser, user.session, msg::usrmsg::STATUS_REJECTED, msg::usrmsg::REASON_BAD_MSG_FORMAT, ""); + return -1; + } + } else { LOG_DEBUG << "Invalid user message type: " << msg_type;