Try to merge esp32 and esp8266
This commit is contained in:
parent
ad36e66ccf
commit
0af9c39fa3
4 changed files with 29 additions and 347 deletions
|
@ -1,4 +1,3 @@
|
||||||
#ifdef ESP8266
|
|
||||||
#include "API.hpp"
|
#include "API.hpp"
|
||||||
|
|
||||||
namespace fw
|
namespace fw
|
||||||
|
@ -10,11 +9,23 @@ namespace fw
|
||||||
this->api_port = port;
|
this->api_port = port;
|
||||||
if (this->setup_auth(username, password) == ERROR)
|
if (this->setup_auth(username, password) == ERROR)
|
||||||
endless_loop();
|
endless_loop();
|
||||||
|
#ifdef ESP8266
|
||||||
this->server = new ESP8266WebServerSecure(port);
|
this->server = new ESP8266WebServerSecure(port);
|
||||||
this->serverCache = new ServerSessions(5);
|
this->serverCache = new ServerSessions(5);
|
||||||
|
#else
|
||||||
|
this->server = new WebServer(port);
|
||||||
|
#endif
|
||||||
this->setup_routing(cert, key);
|
this->setup_routing(cert, key);
|
||||||
this->server->begin();
|
this->server->begin();
|
||||||
Serial.printf("%s endpoints -> %s/api\n", TAG, this->get_url_base().c_str());
|
Serial.printf("%s endpoints -> %s/api\n", TAG, this->get_url_base().c_str());
|
||||||
|
#if !defined(ESP8266)
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
this->server->handleClient();
|
||||||
|
// https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
API::~API()
|
API::~API()
|
||||||
|
@ -22,10 +33,12 @@ namespace fw
|
||||||
this->server->stop();
|
this->server->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
void API::handle_client()
|
void API::handle_client()
|
||||||
{
|
{
|
||||||
this->server->handleClient();
|
this->server->handleClient();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
String API::get_url_base()
|
String API::get_url_base()
|
||||||
{
|
{
|
||||||
|
@ -61,8 +74,10 @@ namespace fw
|
||||||
|
|
||||||
void API::setup_routing(const char *cert, const char *key)
|
void API::setup_routing(const char *cert, const char *key)
|
||||||
{
|
{
|
||||||
|
#ifdef ESP8266
|
||||||
this->server->getServer().setRSACert(new BearSSL::X509List(cert), new BearSSL::PrivateKey(key));
|
this->server->getServer().setRSACert(new BearSSL::X509List(cert), new BearSSL::PrivateKey(key));
|
||||||
this->server->getServer().setCache(serverCache);
|
this->server->getServer().setCache(serverCache);
|
||||||
|
#endif
|
||||||
this->server->on("/api/firewall/rules", HTTP_GET, std::bind(&API::get_firewall_rules_handler, this));
|
this->server->on("/api/firewall/rules", HTTP_GET, std::bind(&API::get_firewall_rules_handler, this));
|
||||||
this->server->on(UriBraces("/api/firewall/rules/{}"), HTTP_GET, std::bind(&API::get_firewall_rule_handler, this));
|
this->server->on(UriBraces("/api/firewall/rules/{}"), HTTP_GET, std::bind(&API::get_firewall_rule_handler, this));
|
||||||
this->server->on("/api/firewall/rules", HTTP_POST, std::bind(&API::post_firewall_handler, this));
|
this->server->on("/api/firewall/rules", HTTP_POST, std::bind(&API::post_firewall_handler, this));
|
||||||
|
@ -286,4 +301,3 @@ namespace fw
|
||||||
return serialized_string;
|
return serialized_string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
|
@ -1,10 +1,14 @@
|
||||||
#ifndef ESP8266_API_HPP
|
#ifndef API_HPP
|
||||||
#define ESP8266_API_HPP
|
#define API_HPP
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
#include "ESP8266WebServerSecure.h"
|
#include "ESP8266WebServerSecure.h"
|
||||||
|
#else
|
||||||
|
#include "WebServer.h"
|
||||||
|
#endif
|
||||||
#include "uri/UriBraces.h"
|
#include "uri/UriBraces.h"
|
||||||
#include "Firewall.hpp"
|
#include "Firewall.hpp"
|
||||||
#include "../Utils.hpp"
|
#include "Utils.hpp"
|
||||||
|
|
||||||
namespace fw
|
namespace fw
|
||||||
{
|
{
|
||||||
|
@ -13,11 +17,17 @@ namespace fw
|
||||||
public:
|
public:
|
||||||
API(Firewall *, const char *cert, const char *key, const char *username, const char *password, const String ip, const uint16_t port = 8080);
|
API(Firewall *, const char *cert, const char *key, const char *username, const char *password, const String ip, const uint16_t port = 8080);
|
||||||
~API();
|
~API();
|
||||||
|
#ifdef ESP8266
|
||||||
void handle_client();
|
void handle_client();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
#ifdef ESP8266
|
||||||
BearSSL::ESP8266WebServerSecure *server;
|
BearSSL::ESP8266WebServerSecure *server;
|
||||||
BearSSL::ServerSessions *serverCache;
|
BearSSL::ServerSessions *serverCache;
|
||||||
|
#else
|
||||||
|
WebServer *server;
|
||||||
|
#endif
|
||||||
Firewall *firewall;
|
Firewall *firewall;
|
||||||
credential_t credentials;
|
credential_t credentials;
|
||||||
api_endpoint_t *endpoint_head = NULL;
|
api_endpoint_t *endpoint_head = NULL;
|
|
@ -1,287 +0,0 @@
|
||||||
#if !defined(ESP8266)
|
|
||||||
#include "API.hpp"
|
|
||||||
|
|
||||||
namespace fw
|
|
||||||
{
|
|
||||||
API::API(fw::Firewall *firewall, const char *username, const char *password, const String ip, const uint16_t port)
|
|
||||||
{
|
|
||||||
this->firewall = firewall;
|
|
||||||
this->api_ip = ip;
|
|
||||||
this->api_port = port;
|
|
||||||
if (this->setup_auth(username, password) == ERROR)
|
|
||||||
endless_loop();
|
|
||||||
this->server = new WebServer(port);
|
|
||||||
this->setup_routing();
|
|
||||||
this->server->begin();
|
|
||||||
Serial.printf("%s endpoints -> %s/api\n", TAG, this->get_url_base().c_str());
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
this->server->handleClient();
|
|
||||||
// https://docs.espressif.com/projects/arduino-esp32/en/latest/esp-idf_component.html
|
|
||||||
sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
API::~API()
|
|
||||||
{
|
|
||||||
this->server->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
String API::get_url_base()
|
|
||||||
{
|
|
||||||
return "http://" + this->api_ip + ":" + this->api_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
ok_t API::setup_auth(const char *username, const char *password)
|
|
||||||
{
|
|
||||||
if (!username || *username == 0x00 || strlen(username) > CREDENTIALS_LENGTH)
|
|
||||||
{
|
|
||||||
Serial.printf("%s Username too long or missing!\n", TAG);
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
strncpy(credentials.username, username, CREDENTIALS_LENGTH);
|
|
||||||
if (!password || *password == 0x00 || strlen(password) > CREDENTIALS_LENGTH)
|
|
||||||
{
|
|
||||||
Serial.printf("%s Password too long or missing!\n", TAG);
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
strncpy(credentials.password, password, CREDENTIALS_LENGTH);
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
auth_t API::check_auth()
|
|
||||||
{
|
|
||||||
if (server->authenticate(this->credentials.username, this->credentials.password))
|
|
||||||
{
|
|
||||||
return AUTHENTICATED;
|
|
||||||
}
|
|
||||||
this->json_message_response("unauthorized", 403);
|
|
||||||
return DENIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::setup_routing()
|
|
||||||
{
|
|
||||||
this->server->on("/api/firewall/rules", HTTP_GET, std::bind(&API::get_firewall_rules_handler, this));
|
|
||||||
this->server->on(UriBraces("/api/firewall/rules/{}"), HTTP_GET, std::bind(&API::get_firewall_rule_handler, this));
|
|
||||||
this->server->on("/api/firewall/rules", HTTP_POST, std::bind(&API::post_firewall_handler, this));
|
|
||||||
this->server->on(UriBraces("/api/firewall/rules/{}"), HTTP_PUT, std::bind(&API::put_firewall_handler, this));
|
|
||||||
this->server->on(UriBraces("/api/firewall/rules/{}"), HTTP_DELETE, std::bind(&API::delete_firewall_handler, this));
|
|
||||||
this->server->on("/api", HTTP_GET, std::bind(&API::get_endpoint_list_handler, this));
|
|
||||||
this->server->onNotFound(std::bind(&API::not_found_handler, this));
|
|
||||||
|
|
||||||
add_endpoint_to_list("/api/firewall/rules", "GET", "Get all Firewall Rules");
|
|
||||||
add_endpoint_to_list("/api/firewall/rules/<key>", "GET", "Get Firewall Rule by key");
|
|
||||||
add_endpoint_to_list("/api/firewall/rules", "POST", "Create Firewall Rule");
|
|
||||||
add_endpoint_to_list("/api/firewall/rules/<key>", "PUT", "Update Firewall Rule by key");
|
|
||||||
add_endpoint_to_list("/api/firewall/rules/<key>", "DELETE", "Delete Firewall Rule by key");
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::add_endpoint_to_list(const String uri, const char *method, const char *description)
|
|
||||||
{
|
|
||||||
api_endpoint_t *temp;
|
|
||||||
const String url = get_url_base() + uri;
|
|
||||||
|
|
||||||
api_endpoint_t *api_ptr = (api_endpoint_t *)malloc(sizeof(api_endpoint_t));
|
|
||||||
strncpy(api_ptr->uri, url.c_str(), sizeof(api_ptr->uri));
|
|
||||||
strncpy(api_ptr->method, method, sizeof(api_ptr->method));
|
|
||||||
strncpy(api_ptr->description, description, sizeof(api_ptr->description));
|
|
||||||
|
|
||||||
if (this->endpoint_head == NULL)
|
|
||||||
{
|
|
||||||
this->endpoint_head = api_ptr;
|
|
||||||
api_ptr->next = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
temp = this->endpoint_head;
|
|
||||||
while (temp->next != NULL)
|
|
||||||
{
|
|
||||||
temp = temp->next;
|
|
||||||
}
|
|
||||||
temp->next = api_ptr;
|
|
||||||
api_ptr->next = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::not_found_handler()
|
|
||||||
{
|
|
||||||
this->json_message_response("see " + get_url_base() + "/api for available routes", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::get_endpoint_list_handler()
|
|
||||||
{
|
|
||||||
this->json_array_response(this->construct_json_api(), 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::get_firewall_rule_handler()
|
|
||||||
{
|
|
||||||
if (this->check_auth() == DENIED)
|
|
||||||
return;
|
|
||||||
String param = this->server->pathArg(0);
|
|
||||||
int rule_number = atoi(param.c_str());
|
|
||||||
firewall_rule_t *rule_ptr = firewall->get_rule_from_firewall(rule_number);
|
|
||||||
if (rule_ptr == NULL)
|
|
||||||
this->json_message_response("rule does not exist", 404);
|
|
||||||
else
|
|
||||||
this->json_generic_response(this->construct_json_firewall_rule(rule_ptr), 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::get_firewall_rules_handler()
|
|
||||||
{
|
|
||||||
if (this->check_auth() == DENIED)
|
|
||||||
return;
|
|
||||||
this->json_array_response(this->construct_json_firewall(), 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::post_firewall_handler()
|
|
||||||
{
|
|
||||||
if (this->check_auth() == DENIED)
|
|
||||||
return;
|
|
||||||
if (request_has_all_firewall_parameter())
|
|
||||||
{
|
|
||||||
String args[IPV4ADDRESS_LENGTH] = {};
|
|
||||||
for (uint8_t i = 0; i < firewall_fields_amount; i++)
|
|
||||||
{
|
|
||||||
args[i] = this->server->arg(firewall_fields[i]);
|
|
||||||
}
|
|
||||||
firewall_rule_t *rule_ptr = firewall->add_rule_to_firewall(args);
|
|
||||||
this->json_generic_response(this->construct_json_firewall_rule(rule_ptr), 201);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->json_message_response("not enough parameter provided", 400);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::put_firewall_handler()
|
|
||||||
{
|
|
||||||
if (this->check_auth() == DENIED)
|
|
||||||
return;
|
|
||||||
String param = this->server->pathArg(0);
|
|
||||||
int rule_number = atoi(param.c_str());
|
|
||||||
if (request_has_all_firewall_parameter())
|
|
||||||
{
|
|
||||||
String args[IPV4ADDRESS_LENGTH] = {};
|
|
||||||
for (uint8_t i = 0; i < firewall_fields_amount; i++)
|
|
||||||
{
|
|
||||||
args[i] = this->server->arg(firewall_fields[i]);
|
|
||||||
}
|
|
||||||
firewall_rule_t *rule_ptr = firewall->update_rule_of_firewall(args, rule_number);
|
|
||||||
if (rule_ptr == NULL)
|
|
||||||
this->json_message_response("rule does not exist", 404);
|
|
||||||
else
|
|
||||||
this->json_generic_response(this->construct_json_firewall_rule(rule_ptr), 200);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->json_message_response("not enough parameter provided", 400);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::delete_firewall_handler()
|
|
||||||
{
|
|
||||||
if (this->check_auth() == DENIED)
|
|
||||||
return;
|
|
||||||
String param = this->server->pathArg(0);
|
|
||||||
int rule_number = atoi(param.c_str());
|
|
||||||
if (firewall->delete_rule_from_firewall(rule_number) == SUCCESS)
|
|
||||||
this->json_message_response("firewall rule deleted", 200);
|
|
||||||
else
|
|
||||||
this->json_message_response("cannot delete firewall rule", 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool API::request_has_all_firewall_parameter()
|
|
||||||
{
|
|
||||||
if (!this->server->args())
|
|
||||||
return false;
|
|
||||||
for (uint8_t i = 0; i < firewall_fields_amount; i++)
|
|
||||||
{
|
|
||||||
if (i != KEY && !this->server->hasArg(firewall_fields[i]))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String API::json_new_attribute(String key, String value, bool last)
|
|
||||||
{
|
|
||||||
String json_string;
|
|
||||||
json_string += "\"" + key + "\": \"" + value + "\"";
|
|
||||||
if (!last)
|
|
||||||
json_string += ",";
|
|
||||||
return json_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
String API::json_new_attribute(String key, uint32_t value, bool last)
|
|
||||||
{
|
|
||||||
return json_new_attribute(key, String(value), last);
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::json_generic_response(String serialized_string, const uint16_t response_code)
|
|
||||||
{
|
|
||||||
this->server->send(response_code, json_response_type, serialized_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::json_array_response(String serialized_string, const uint16_t response_code)
|
|
||||||
{
|
|
||||||
this->server->send(response_code, json_response_type, "[" + serialized_string + "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
void API::json_message_response(String message, const uint16_t response_code)
|
|
||||||
{
|
|
||||||
String serialized_string = "{";
|
|
||||||
serialized_string += json_new_attribute("message", message, true);
|
|
||||||
serialized_string += "}";
|
|
||||||
this->server->send(response_code, json_response_type, serialized_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
String API::construct_json_firewall_rule(firewall_rule_t *rule_ptr)
|
|
||||||
{
|
|
||||||
String serialized_string = "{";
|
|
||||||
serialized_string += json_new_attribute(firewall_fields[KEY], rule_ptr->key);
|
|
||||||
serialized_string += json_new_attribute(firewall_fields[IP], rule_ptr->ip);
|
|
||||||
serialized_string += json_new_attribute(firewall_fields[PORT_FROM], rule_ptr->port_from);
|
|
||||||
serialized_string += json_new_attribute(firewall_fields[PORT_TO], rule_ptr->port_to);
|
|
||||||
serialized_string += json_new_attribute(firewall_fields[PROTOCOL], protocol_to_string(rule_ptr->protocol));
|
|
||||||
serialized_string += json_new_attribute(firewall_fields[TARGET], target_to_string(rule_ptr->target), true);
|
|
||||||
serialized_string += "}";
|
|
||||||
return serialized_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
String API::construct_json_firewall()
|
|
||||||
{
|
|
||||||
firewall_rule_t *rule_ptr = firewall->get_rule_head();
|
|
||||||
String serialized_string;
|
|
||||||
while (rule_ptr != NULL)
|
|
||||||
{
|
|
||||||
serialized_string += construct_json_firewall_rule(rule_ptr);
|
|
||||||
rule_ptr = rule_ptr->next;
|
|
||||||
if (rule_ptr != NULL)
|
|
||||||
serialized_string += ",";
|
|
||||||
}
|
|
||||||
return serialized_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
String API::construct_json_api_endpoint(api_endpoint_t *api_ptr)
|
|
||||||
{
|
|
||||||
String serialized_string = "{";
|
|
||||||
serialized_string += json_new_attribute("endpoint", api_ptr->uri);
|
|
||||||
serialized_string += json_new_attribute("description", api_ptr->description);
|
|
||||||
serialized_string += json_new_attribute("method", api_ptr->method, true);
|
|
||||||
serialized_string += "}";
|
|
||||||
return serialized_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
String API::construct_json_api()
|
|
||||||
{
|
|
||||||
api_endpoint_t *api_ptr = this->endpoint_head;
|
|
||||||
String serialized_string;
|
|
||||||
while (api_ptr != NULL)
|
|
||||||
{
|
|
||||||
serialized_string += construct_json_api_endpoint(api_ptr);
|
|
||||||
api_ptr = api_ptr->next;
|
|
||||||
if (api_ptr != NULL)
|
|
||||||
serialized_string += ",";
|
|
||||||
}
|
|
||||||
return serialized_string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,55 +0,0 @@
|
||||||
#ifndef ESP32_API_HPP
|
|
||||||
#define ESP32_API_HPP
|
|
||||||
|
|
||||||
#include "WebServer.h"
|
|
||||||
#include "uri/UriBraces.h"
|
|
||||||
#include "Firewall.hpp"
|
|
||||||
#include "../Utils.hpp"
|
|
||||||
|
|
||||||
namespace fw
|
|
||||||
{
|
|
||||||
class API
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
API(Firewall *firewall, const char *username, const char *password, const String ip, const uint16_t port = 8080);
|
|
||||||
~API();
|
|
||||||
|
|
||||||
private:
|
|
||||||
WebServer *server;
|
|
||||||
Firewall *firewall;
|
|
||||||
credential_t credentials;
|
|
||||||
api_endpoint_t *endpoint_head = NULL;
|
|
||||||
String api_ip = "0.0.0.0";
|
|
||||||
uint16_t api_port;
|
|
||||||
String json_response_type = "application/json; charset=utf-8";
|
|
||||||
const char *TAG = "[API]";
|
|
||||||
|
|
||||||
String get_url_base();
|
|
||||||
ok_t setup_auth(const char *username, const char *password);
|
|
||||||
auth_t check_auth();
|
|
||||||
|
|
||||||
void setup_routing();
|
|
||||||
void add_endpoint_to_list(const String uri, const char *method, const char *description);
|
|
||||||
void not_found_handler();
|
|
||||||
void get_endpoint_list_handler();
|
|
||||||
void get_firewall_rule_handler();
|
|
||||||
void get_firewall_rules_handler();
|
|
||||||
void post_firewall_handler();
|
|
||||||
void put_firewall_handler();
|
|
||||||
void delete_firewall_handler();
|
|
||||||
|
|
||||||
bool request_has_all_firewall_parameter();
|
|
||||||
String json_new_attribute(String key, String value, bool last = false);
|
|
||||||
String json_new_attribute(String key, uint32_t value, bool last = false);
|
|
||||||
void json_generic_response(String serialized_string, const uint16_t response_code);
|
|
||||||
void json_array_response(String serialized_string, const uint16_t response_code);
|
|
||||||
void json_message_response(String message, const uint16_t response_code);
|
|
||||||
|
|
||||||
String construct_json_firewall_rule(firewall_rule_t *rule_ptr);
|
|
||||||
String construct_json_firewall();
|
|
||||||
String construct_json_api_endpoint(api_endpoint_t *api_ptr);
|
|
||||||
String construct_json_api();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
Reference in a new issue