diff --git a/include/WebApi.h b/include/WebApi.h index 28ae7d3..5e5af52 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 @@ public: 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 4080992..10f3e28 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 29f3531..f76a2e0 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 2042f7d..1cc1422 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 817e71b..c6678b0 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 5f5e410..eb48c8e 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 b5b9e17..8905892 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 ba257ef..538f087 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 29459a5..78fed20 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 12f637a..b7fbbe5 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 02bbfb1..343d94b 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 08fe9c0..2f921d7 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 b95ebb2..05f829c 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!";