5 API::API(
fw::Firewall *firewall,
const char *cert,
const char *key,
const char *username,
const char *password,
const String ip,
const uint16_t port)
7 this->firewall = firewall;
10 if (this->setup_auth(username, password) == ERROR)
13 this->server =
new ESP8266WebServerSecure(port);
14 this->serverCache =
new ServerSessions(5);
16 this->server =
new WebServer(port);
18 this->setup_routing(cert, key);
19 this->server->begin();
20 Serial.printf(
"%s endpoints -> %s/api\n", TAG, this->get_url_base().c_str());
24 this->server->handleClient();
37 void API::handle_client()
39 this->server->handleClient();
43 String API::get_url_base()
46 return "https://" + this->api_ip +
":" + this->api_port;
48 return "http://" + this->api_ip +
":" + this->api_port;
52 ok_t API::setup_auth(
const char *username,
const char *password)
54 if (!username || *username == 0x00 || strlen(username) > CREDENTIALS_LENGTH)
56 Serial.printf(
"%s Username too long or missing!\n", TAG);
59 strncpy(credentials.username, username, CREDENTIALS_LENGTH);
60 if (!password || *password == 0x00 || strlen(password) > CREDENTIALS_LENGTH)
62 Serial.printf(
"%s Password too long or missing!\n", TAG);
65 strncpy(credentials.password, password, CREDENTIALS_LENGTH);
69 auth_t API::check_auth()
71 if (server->authenticate(this->credentials.username, this->credentials.password))
75 this->json_message_response(
"unauthorized", 403);
79 void API::setup_routing(
const char *cert,
const char *key)
82 this->server->getServer().setRSACert(
new BearSSL::X509List(cert),
new BearSSL::PrivateKey(key));
83 this->server->getServer().setCache(serverCache);
85 this->server->on(
"/api/firewall/rules", HTTP_GET, std::bind(&API::get_firewall_rules_handler,
this));
86 this->server->on(UriBraces(
"/api/firewall/rules/{}"), HTTP_GET, std::bind(&API::get_firewall_rule_handler,
this));
87 this->server->on(
"/api/firewall/rules", HTTP_POST, std::bind(&API::post_firewall_handler,
this));
88 this->server->on(UriBraces(
"/api/firewall/rules/{}"), HTTP_PUT, std::bind(&API::put_firewall_handler,
this));
89 this->server->on(UriBraces(
"/api/firewall/rules/{}"), HTTP_DELETE, std::bind(&API::delete_firewall_handler,
this));
90 this->server->on(
"/api", HTTP_GET, std::bind(&API::get_endpoint_list_handler,
this));
91 this->server->onNotFound(std::bind(&API::not_found_handler,
this));
93 add_endpoint_to_list(
"/api/firewall/rules",
"GET",
"Get all Firewall Rules");
94 add_endpoint_to_list(
"/api/firewall/rules/<key>",
"GET",
"Get Firewall Rule by key");
95 add_endpoint_to_list(
"/api/firewall/rules",
"POST",
"Create Firewall Rule");
96 add_endpoint_to_list(
"/api/firewall/rules/<key>",
"PUT",
"Update Firewall Rule by key");
97 add_endpoint_to_list(
"/api/firewall/rules/<key>",
"DELETE",
"Delete Firewall Rule by key");
100 void API::add_endpoint_to_list(
const String uri,
const char *method,
const char *description)
102 api_endpoint_t *temp;
103 const String url = get_url_base() + uri;
105 api_endpoint_t *api_ptr = (api_endpoint_t *)malloc(
sizeof(api_endpoint_t));
106 strncpy(api_ptr->uri, url.c_str(),
sizeof(api_ptr->uri));
107 strncpy(api_ptr->method, method,
sizeof(api_ptr->method));
108 strncpy(api_ptr->description, description,
sizeof(api_ptr->description));
110 if (this->endpoint_head == NULL)
112 this->endpoint_head = api_ptr;
113 api_ptr->next = NULL;
116 temp = this->endpoint_head;
117 while (temp->next != NULL)
121 temp->next = api_ptr;
122 api_ptr->next = NULL;
126 void API::not_found_handler()
128 this->json_message_response(
"see " + get_url_base() +
"/api for available routes", 404);
131 void API::get_endpoint_list_handler()
133 this->json_array_response(this->construct_json_api(), 200);
136 void API::get_firewall_rule_handler()
138 if (this->check_auth() == DENIED)
140 String param = this->server->pathArg(0);
141 int rule_number = atoi(param.c_str());
142 firewall_rule_t *rule_ptr = firewall->get_rule_from_firewall(rule_number);
143 if (rule_ptr == NULL)
144 this->json_message_response(
"rule does not exist", 404);
146 this->json_generic_response(this->construct_json_firewall_rule(rule_ptr), 200);
149 void API::get_firewall_rules_handler()
151 if (this->check_auth() == DENIED)
153 this->json_array_response(this->construct_json_firewall(), 200);
156 void API::post_firewall_handler()
158 if (this->check_auth() == DENIED)
160 if (request_has_all_firewall_parameter())
162 String args[IPV4ADDRESS_LENGTH] = {};
163 for (uint8_t i = 0; i < firewall_fields_amount; i++)
165 args[i] = this->server->arg(firewall_fields[i]);
167 firewall_rule_t *rule_ptr = firewall->add_rule_to_firewall(args);
168 this->json_generic_response(this->construct_json_firewall_rule(rule_ptr), 201);
172 this->json_message_response(
"not enough parameter provided", 400);
176 void API::put_firewall_handler()
178 if (this->check_auth() == DENIED)
180 String param = this->server->pathArg(0);
181 int rule_number = atoi(param.c_str());
182 if (request_has_all_firewall_parameter())
184 String args[IPV4ADDRESS_LENGTH] = {};
185 for (uint8_t i = 0; i < firewall_fields_amount; i++)
187 args[i] = this->server->arg(firewall_fields[i]);
189 firewall_rule_t *rule_ptr = firewall->update_rule_of_firewall(args, rule_number);
190 if (rule_ptr == NULL)
191 this->json_message_response(
"rule does not exist", 404);
193 this->json_generic_response(this->construct_json_firewall_rule(rule_ptr), 200);
197 this->json_message_response(
"not enough parameter provided", 400);
201 void API::delete_firewall_handler()
203 if (this->check_auth() == DENIED)
205 String param = this->server->pathArg(0);
206 int rule_number = atoi(param.c_str());
207 if (firewall->delete_rule_from_firewall(rule_number) == SUCCESS)
208 this->json_message_response(
"firewall rule deleted", 200);
210 this->json_message_response(
"cannot delete firewall rule", 500);
213 bool API::request_has_all_firewall_parameter()
215 if (!this->server->args())
217 for (uint8_t i = 0; i < firewall_fields_amount; i++)
219 if (i != KEY && !this->server->hasArg(firewall_fields[i]))
225 String API::json_new_attribute(String key, String value,
bool last)
228 json_string +=
"\"" + key +
"\": \"" + value +
"\"";
234 String API::json_new_attribute(String key, uint32_t value,
bool last)
236 return json_new_attribute(key, String(value), last);
239 void API::json_generic_response(String serialized_string,
const uint16_t response_code)
241 this->server->send(response_code, json_response_type, serialized_string);
244 void API::json_array_response(String serialized_string,
const uint16_t response_code)
246 this->server->send(response_code, json_response_type,
"[" + serialized_string +
"]");
249 void API::json_message_response(String message,
const uint16_t response_code)
251 String serialized_string =
"{";
252 serialized_string += json_new_attribute(
"message", message,
true);
253 serialized_string +=
"}";
254 this->server->send(response_code, json_response_type, serialized_string);
257 String API::construct_json_firewall_rule(firewall_rule_t *rule_ptr)
259 String serialized_string =
"{";
260 serialized_string += json_new_attribute(firewall_fields[KEY], rule_ptr->key);
261 serialized_string += json_new_attribute(firewall_fields[IP], rule_ptr->ip);
262 serialized_string += json_new_attribute(firewall_fields[PORT_FROM], rule_ptr->port_from);
263 serialized_string += json_new_attribute(firewall_fields[PORT_TO], rule_ptr->port_to);
264 serialized_string += json_new_attribute(firewall_fields[PROTOCOL], protocol_to_string(rule_ptr->protocol));
265 serialized_string += json_new_attribute(firewall_fields[TARGET], target_to_string(rule_ptr->target),
true);
266 serialized_string +=
"}";
267 return serialized_string;
270 String API::construct_json_firewall()
272 firewall_rule_t *rule_ptr = firewall->get_rule_head();
273 String serialized_string;
274 while (rule_ptr != NULL)
276 serialized_string += construct_json_firewall_rule(rule_ptr);
277 rule_ptr = rule_ptr->next;
278 if (rule_ptr != NULL)
279 serialized_string +=
",";
281 return serialized_string;
284 String API::construct_json_api_endpoint(api_endpoint_t *api_ptr)
286 String serialized_string =
"{";
287 serialized_string += json_new_attribute(
"endpoint", api_ptr->uri);
288 serialized_string += json_new_attribute(
"description", api_ptr->description);
289 serialized_string += json_new_attribute(
"method", api_ptr->method,
true);
290 serialized_string +=
"}";
291 return serialized_string;
294 String API::construct_json_api()
296 api_endpoint_t *api_ptr = this->endpoint_head;
297 String serialized_string;
298 while (api_ptr != NULL)
300 serialized_string += construct_json_api_endpoint(api_ptr);
301 api_ptr = api_ptr->next;
303 serialized_string +=
",";
305 return serialized_string;
API(Firewall *, const char *cert, const char *key, const char *username, const char *password, const String ip, const uint16_t port=8080)
Construct a new API object.
~API()
Destroy the API object.