Implement action model validator
authorChanggyu Choi <changyu.choi@samsung.com>
Sun, 27 Apr 2025 05:21:50 +0000 (14:21 +0900)
committerChanggyu Choi <changyu.choi@samsung.com>
Mon, 28 Apr 2025 04:07:39 +0000 (13:07 +0900)
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
src/action/action_request_handler.cc
src/action/utils/action_validator.cc
src/action/utils/action_validator.hh
src/common/action_schema.cc
src/common/utils/safe_json.hpp

index 37127c785e8942ef8a59c7241f4b509ab3beb6b9..36859a995bce3cf8cd78b0e811e801cc869086e7 100755 (executable)
@@ -196,13 +196,8 @@ void ActionRequestHandler::OnExecute(const std::string& instance, pid_t pid,
                                      uid_t uid, rpc::ActionModel& action) {
   auto db = std::make_unique<action::SqliteDb>();
   std::string schema_json = db->GetAction(action.Getaction_id());
-  std::string error;
-
-  if (!ActionValidator().CheckModelValid(schema_json, action.Getjson(),
-                                         error)) {
-    LOG(ERROR) << "Invalid model. error: " << error;
+  if (!ActionValidator().CheckModelValid(schema_json, action.Getjson()))
     return;
-  }
 
   common::ActionSchema schema(schema_json);
   LOG(DEBUG) << "OnExecute action : " << schema.GetActionId();
index 7e74118e319e7ee81fc2111dc4b169d8ce78e00a..eb93c8d3f16bb81ba3469ec329fab6fff213835e 100644 (file)
 #include <rapidjson/error/en.h>
 #include <rapidjson/schema.h>
 
+#include "common/utils/logging.hh"
+#include "common/utils/safe_json.hpp"
+
 namespace action {
+
 bool ActionValidator::CheckSchemaValid(const std::string& schemajson) const {
   // TODO: implement this.
   return false;
 }
 
 bool ActionValidator::CheckModelValid(const std::string& schemajson,
-                                      const std::string& modeljson,
-                                      std::string& errMsg) const {
-  // TODO: implement this.
+                                      const std::string& modeljson) const {
+  try {
+    common::SafeJson schema(schemajson);
+    common::SafeJson model(modeljson);
+
+    for (auto& [key, item] : schema.members("params")) {
+      std::string type = common::SafeJson::get<std::string>(*item, "type");
+      bool isRequired = false;
+      try {
+        isRequired = common::SafeJson::get<bool>(*item, "isRequired");
+      } catch (const std::runtime_error& e) {
+        isRequired = false;
+      }
+
+      try {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-variable"
+        if (type == "int") {
+          int value = model.get<int>({"params", key});
+        } else if (type == "string") {
+          std::string value = model.get<std::string>({"params", key});
+        } else if (type == "bool") {  // TODO: change to boolean
+          bool value = model.get<bool>({"params", key});
+        } else if (type == "array") {
+          auto value = model.array({"params", key});
+        } else if (type == "object") {
+          auto value = model.members({"params", key});
+        } else if (type == "double") {  // TODO: change to number
+          double value = model.get<double>({"params", key});
+        } else {
+          LOG(ERROR) << "Unknown type: " << type;
+          return false;
+        }
+#pragma GCC diagnostic pop
+      } catch (const std::runtime_error& e) {
+        if (isRequired) {
+          LOG(ERROR) << e.what();
+          return false;
+        }
+      }
+    }
+  } catch (const std::runtime_error& e) {
+    LOG(ERROR) << e.what();
+    return false;
+  }
+
   return true;
 }
 
index 72f3a532413ed7374872909f49fc286554f3f0fc..549f371f664544ca93f21edaeaaec26d23fa6619 100644 (file)
@@ -26,7 +26,7 @@ class ActionValidator {
   ActionValidator() = default;
   bool CheckSchemaValid(const std::string& schemajson) const;
   bool CheckModelValid(const std::string& schemajson,
-                  const std::string& modeljson, std::string& errMsg) const;
+                       const std::string& modeljson) const;
 };
 
 }  // namespace action
index cd584609b4d1e01dad988e8b13510dd7f2e22236..58955791b418e2b5e43394b27a51cfb576b0654b 100644 (file)
@@ -55,13 +55,15 @@ namespace common {
 
 ActionSchema::ActionSchema() {}
 
-#include <iostream>
 ActionSchema::ActionSchema(const std::string& json_str) {
   try {
     SafeJson root(json_str);
     action_id_ = root.get<std::string>("name");
     appid_ = root.get<std::string>("appId");  // TODO: Change to details::appId
-    category_ = root.get<std::string>("category");
+    try {
+      category_ = root.get<std::string>("category");
+    } catch (...) {
+    }
     description_ = root.get<std::string>("desc");
     type_ = GetActionTypeFromString(root.get<std::string>("type"));
     // params
@@ -90,9 +92,10 @@ ActionSchema::ActionSchema(const std::string& json_str) {
 
     for (auto const& it : root.array("required-privileges"))
       privileges_.push_back(it->GetString());
-  } catch (...) {
+  } catch (const std::runtime_error& e) {
     // TODO: how to handle invalid json case?
-    LOG(ERROR) << "Failed to parse json string";
+    LOG(ERROR) << "Failed to parse json string: " << e.what();
+    LOG(ERROR) << json_str;
   }
 }
 
index c63c8f306e6b07b6b9e4767a8cb7712d8fb29b2f..add38fc3e294c9a5daea2291422e7e6358c712a5 100644 (file)
@@ -138,7 +138,6 @@ class SafeJson {
   }
 };
 
-// νŠΉμˆ˜ν™”
 template <>
 inline std::string SafeJson::extract<std::string>(
     const rapidjson::Value& val) const {