diff --git a/include/WebApi.h b/include/WebApi.h index 28ae7d33b..5e5af5278 100644 --- a/include/WebApi.h +++ b/include/WebApi.h @@ -22,6 +22,7 @@ #include "WebApi_webapp.h" #include "WebApi_ws_console.h" #include "WebApi_ws_live.h" +#include #include #include @@ -37,6 +38,8 @@ class WebApiClass { static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!"); + static bool parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, DynamicJsonDocument& json_document, size_t max_document_size = 1024); + private: AsyncWebServer _server; diff --git a/src/WebApi.cpp b/src/WebApi.cpp index 40809927a..10f3e28d9 100644 --- a/src/WebApi.cpp +++ b/src/WebApi.cpp @@ -85,4 +85,38 @@ void WebApiClass::writeConfig(JsonVariant& retMsg, const WebApiError code, const } } +bool WebApiClass::parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, DynamicJsonDocument& json_document, size_t max_document_size) +{ + auto& retMsg = response->getRoot(); + retMsg["type"] = "warning"; + + if (!request->hasParam("data", true)) { + retMsg["message"] = "No values found!"; + retMsg["code"] = WebApiError::GenericNoValueFound; + response->setLength(); + request->send(response); + return false; + } + + const String json = request->getParam("data", true)->value(); + if (json.length() > max_document_size) { + retMsg["message"] = "Data too large!"; + retMsg["code"] = WebApiError::GenericDataTooLarge; + response->setLength(); + request->send(response); + return false; + } + + const DeserializationError error = deserializeJson(json_document, json); + if (error) { + retMsg["message"] = "Failed to parse data!"; + retMsg["code"] = WebApiError::GenericParseError; + response->setLength(); + request->send(response); + return false; + } + + return true; +} + WebApiClass WebApi; diff --git a/src/WebApi_config.cpp b/src/WebApi_config.cpp index 29f353192..f76a2e0ad 100644 --- a/src/WebApi_config.cpp +++ b/src/WebApi_config.cpp @@ -53,38 +53,13 @@ void WebApiConfigClass::onConfigDelete(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("delete"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; diff --git a/src/WebApi_device.cpp b/src/WebApi_device.cpp index 2042f7daa..1cc142207 100644 --- a/src/WebApi_device.cpp +++ b/src/WebApi_device.cpp @@ -97,38 +97,13 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > MQTT_JSON_DOC_SIZE) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("curPin") || root.containsKey("display"))) { retMsg["message"] = "Values are missing!"; diff --git a/src/WebApi_dtu.cpp b/src/WebApi_dtu.cpp index 817e71b27..c6678b0a6 100644 --- a/src/WebApi_dtu.cpp +++ b/src/WebApi_dtu.cpp @@ -84,38 +84,13 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("serial") && root.containsKey("pollinterval") && root.containsKey("nrf_palevel") diff --git a/src/WebApi_inverter.cpp b/src/WebApi_inverter.cpp index 5f5e41016..eb48c8efa 100644 --- a/src/WebApi_inverter.cpp +++ b/src/WebApi_inverter.cpp @@ -88,38 +88,13 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("serial") && root.containsKey("name"))) { retMsg["message"] = "Values are missing!"; @@ -188,38 +163,13 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("id") && root.containsKey("serial") && root.containsKey("name") && root.containsKey("channel"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; @@ -333,38 +283,13 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("id"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; @@ -403,38 +328,13 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("order"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; diff --git a/src/WebApi_limit.cpp b/src/WebApi_limit.cpp index b5b9e1726..890589267 100644 --- a/src/WebApi_limit.cpp +++ b/src/WebApi_limit.cpp @@ -58,38 +58,13 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("serial") && root.containsKey("limit_value") && root.containsKey("limit_type"))) { diff --git a/src/WebApi_maintenance.cpp b/src/WebApi_maintenance.cpp index ba257efa8..538f087ab 100644 --- a/src/WebApi_maintenance.cpp +++ b/src/WebApi_maintenance.cpp @@ -23,38 +23,13 @@ void WebApiMaintenanceClass::onRebootPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > MQTT_JSON_DOC_SIZE) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("reboot"))) { retMsg["message"] = "Values are missing!"; retMsg["code"] = WebApiError::GenericValueMissing; diff --git a/src/WebApi_mqtt.cpp b/src/WebApi_mqtt.cpp index 29459a5b3..78fed2046 100644 --- a/src/WebApi_mqtt.cpp +++ b/src/WebApi_mqtt.cpp @@ -99,38 +99,13 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > MQTT_JSON_DOC_SIZE) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("mqtt_enabled") && root.containsKey("mqtt_hostname") && root.containsKey("mqtt_port") diff --git a/src/WebApi_network.cpp b/src/WebApi_network.cpp index 12f637adc..b7fbbe518 100644 --- a/src/WebApi_network.cpp +++ b/src/WebApi_network.cpp @@ -83,38 +83,13 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("ssid") && root.containsKey("password") && root.containsKey("hostname") diff --git a/src/WebApi_ntp.cpp b/src/WebApi_ntp.cpp index 02bbfb105..343d94b5a 100644 --- a/src/WebApi_ntp.cpp +++ b/src/WebApi_ntp.cpp @@ -95,38 +95,13 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("ntp_server") && root.containsKey("ntp_timezone") && root.containsKey("longitude") @@ -219,38 +194,13 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("year") && root.containsKey("month") && root.containsKey("day") diff --git a/src/WebApi_power.cpp b/src/WebApi_power.cpp index 08fe9c051..2f921d74d 100644 --- a/src/WebApi_power.cpp +++ b/src/WebApi_power.cpp @@ -51,38 +51,13 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!(root.containsKey("serial") && (root.containsKey("power") || root.containsKey("restart")))) { diff --git a/src/WebApi_security.cpp b/src/WebApi_security.cpp index b95ebb299..05f829c55 100644 --- a/src/WebApi_security.cpp +++ b/src/WebApi_security.cpp @@ -42,38 +42,13 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - auto& retMsg = response->getRoot(); - retMsg["type"] = "warning"; - - if (!request->hasParam("data", true)) { - retMsg["message"] = "No values found!"; - retMsg["code"] = WebApiError::GenericNoValueFound; - response->setLength(); - request->send(response); - return; - } - - const String json = request->getParam("data", true)->value(); - - if (json.length() > 1024) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return; - } - DynamicJsonDocument root(1024); - const DeserializationError error = deserializeJson(root, json); - - if (error) { - retMsg["message"] = "Failed to parse data!"; - retMsg["code"] = WebApiError::GenericParseError; - response->setLength(); - request->send(response); + if (!WebApi.parseRequestData(request, response, root)) { return; } + auto& retMsg = response->getRoot(); + if (!root.containsKey("password") && root.containsKey("allow_readonly")) { retMsg["message"] = "Values are missing!";