315 lines
9.5 KiB
C++
315 lines
9.5 KiB
C++
#include "WebConsole.h"
|
|
|
|
using namespace webconsole;
|
|
|
|
WebConsole::WebConsole()
|
|
{
|
|
}
|
|
WebConsole::~WebConsole()
|
|
{
|
|
_server->close();
|
|
delete (_server);
|
|
}
|
|
bool WebConsole::init(userdb::UserDb *userdb)
|
|
{
|
|
_server = new ESP8266WebServer(80);
|
|
this->userdb = userdb;
|
|
const char *headerkeys[] = {"Authentification"};
|
|
size_t headerkeyssize = sizeof(headerkeys) / sizeof(char *);
|
|
_server->collectHeaders(headerkeys, headerkeyssize);
|
|
_server->begin();
|
|
_server->on("/api/auth", HTTPMethod::HTTP_POST, std::bind(&WebConsole::_auth, this));
|
|
_server->on("/api/userdb", HTTPMethod::HTTP_DELETE, std::bind(&WebConsole::_dropUserDb, this));
|
|
_server->on("/api/userdb", HTTPMethod::HTTP_GET, std::bind(&WebConsole::_getUserDb, this));
|
|
_server->on("/api/rfid", HTTPMethod::HTTP_GET, std::bind(&WebConsole::_catchRFID, this));
|
|
_server->on("/api/debug/printfile", std::bind(&WebConsole::_print_db_raw, this));
|
|
_server->on(UriBraces("/api/user/{}"), HTTPMethod::HTTP_DELETE, std::bind(&WebConsole::_deleteUser, this));
|
|
_server->on(UriBraces("/api/user/{}"), HTTPMethod::HTTP_GET, std::bind(&WebConsole::_getUser, this));
|
|
_server->on(UriBraces("/api/user/{}"), HTTPMethod::HTTP_PUT, std::bind(&WebConsole::_createUser, this));
|
|
_server->on(UriBraces("/api/user/{}"), HTTPMethod::HTTP_POST, std::bind(&WebConsole::_updateUser, this));
|
|
_server->on(UriBraces("/api/config/{}"), std::bind(&WebConsole::_deleteUser, this));
|
|
//_server->on("/bypin",std::bind(&WebConsole::_findPin,this));
|
|
_server->serveStatic("/", LittleFS, "/s/");
|
|
_server->onNotFound(std::bind(&WebConsole::_handleUnknown, this));
|
|
return true;
|
|
}
|
|
void WebConsole::attachRfid(Rfid *rfid)
|
|
{
|
|
this->rfid = rfid;
|
|
}
|
|
void WebConsole::serve()
|
|
{
|
|
if (catch_rfid)
|
|
{
|
|
if (millis() - catch_rfid_millis > 2000){
|
|
catch_rfid = 0;
|
|
}
|
|
else if (catch_rfid > 1 && rfid != nullptr && rfid->available())
|
|
{
|
|
rfid_buffer = rfid->getID();
|
|
catch_rfid = 1;
|
|
}
|
|
}
|
|
_server->handleClient();
|
|
}
|
|
uint8_t WebConsole::isInterceptingRfid()
|
|
{
|
|
if(catch_rfid==3){
|
|
catch_rfid=2;
|
|
return 3;
|
|
}
|
|
|
|
return catch_rfid;
|
|
}
|
|
bool WebConsole::_isAuth()
|
|
{
|
|
if (!_server->hasHeader("Authentification"))
|
|
{
|
|
_server->send(401, "text/plain", "Error 401: Unauthorized (missing auth token)");
|
|
return false;
|
|
}
|
|
const char *token = _server->header("Authentification").c_str();
|
|
bool res = auth.isAuth(token);
|
|
if (!res)
|
|
_server->send(401, "text/plain", "Error 401: Unauthorized (missing auth token)");
|
|
return res;
|
|
}
|
|
void WebConsole::_auth()
|
|
{
|
|
_sendCORS();
|
|
String action = _server->arg("action");
|
|
if (action.equals("check"))
|
|
{
|
|
const char *token = _server->arg("token").c_str();
|
|
bool res = auth.isAuth(token);
|
|
_server->send(200, "text/plain", res ? "valid" : "invalid");
|
|
}
|
|
else if (action.equals("login"))
|
|
{
|
|
char *token = auth.login(_server->arg("username"), _server->arg("password"));
|
|
if (token == nullptr)
|
|
_server->send(401, "text/plain", "login_failed");
|
|
else
|
|
_server->send(200, "text/plain", token);
|
|
}
|
|
else if (action.equals("logout"))
|
|
{
|
|
const char *token = _server->arg("token").c_str();
|
|
bool res = auth.logout(token);
|
|
_server->send(200, "text/plain", res ? "success" : "failed");
|
|
}
|
|
else if (action.equals("update"))
|
|
{
|
|
// if (!_isAuth())
|
|
// return;
|
|
bool res = auth.setAuth(_server->arg("username"), _server->arg("password"));
|
|
_server->send(200, "text/plain", res ? "success" : "failed");
|
|
}
|
|
else
|
|
_server->send(404, "text/plain", "unknown action");
|
|
}
|
|
void WebConsole::_sendCORS()
|
|
{
|
|
_server->sendHeader("Access-Control-Allow-Origin", "*");
|
|
_server->sendHeader("Access-Control-Max-Age", "10000");
|
|
_server->sendHeader("Access-Control-Allow-Methods", "PUT,POST,GET,OPTIONS,DELETE");
|
|
_server->sendHeader("Access-Control-Allow-Headers", "*");
|
|
}
|
|
void WebConsole::_handleUnknown()
|
|
{
|
|
_sendCORS();
|
|
if (_server->method() == HTTP_OPTIONS)
|
|
{
|
|
_server->send(204);
|
|
}
|
|
else
|
|
{
|
|
File src = LittleFS.open("s/index.html", "r");
|
|
_server->streamFile(src, "text/html");
|
|
src.close();
|
|
}
|
|
}
|
|
|
|
void WebConsole::_getUserDb()
|
|
{
|
|
_sendCORS();
|
|
if (!_isAuth())
|
|
return;
|
|
File src = LittleFS.open("userdb.csv", "r");
|
|
if (src)
|
|
{
|
|
_server->streamFile(src, "text/csv");
|
|
}
|
|
src.close();
|
|
}
|
|
void WebConsole::_deleteUser()
|
|
{
|
|
_sendCORS();
|
|
if (!_isAuth())
|
|
return;
|
|
if (userdb == nullptr)
|
|
{
|
|
_server->send(500, "text/json", "{\"error\":\"UserDb not initialized\"}");
|
|
return;
|
|
}
|
|
String uid = _server->pathArg(0);
|
|
userdb::User del = userdb->user_by_uid(uid);
|
|
if (del.match == true)
|
|
{
|
|
userdb->remove_user(del);
|
|
_server->send(200, "text/plain", del.toJSONString());
|
|
}
|
|
else
|
|
{
|
|
_server->send(500, "text/json", "{\"error\":\"User not found.\"}");
|
|
}
|
|
}
|
|
|
|
void WebConsole::_getUser()
|
|
{
|
|
_sendCORS();
|
|
if (!_isAuth())
|
|
return;
|
|
if (userdb == nullptr)
|
|
{
|
|
_server->send(500, "text/json", "{\"error\":\"UserDb not initialized\"}");
|
|
return;
|
|
}
|
|
String uid = _server->pathArg(0);
|
|
userdb::User res = userdb->user_by_uid(uid);
|
|
if (res.match == true)
|
|
{
|
|
_server->send(200, "text/json", res.toJSONString());
|
|
}
|
|
else
|
|
{
|
|
_server->send(500, "text/json", "{\"error\":\"User not found.\"}");
|
|
}
|
|
}
|
|
void WebConsole::_updateUser()
|
|
{
|
|
_sendCORS();
|
|
if (!_isAuth())
|
|
return;
|
|
userdb::User updated;
|
|
String body = _server->arg("plain");
|
|
const int capacity = 256;
|
|
StaticJsonDocument<capacity> doc;
|
|
DeserializationError err = deserializeJson(doc, body);
|
|
if (err.code() != err.Ok)
|
|
{
|
|
Serial.println(err.c_str());
|
|
Serial.println(body);
|
|
String response = "{\"error\":\"";
|
|
response += err.c_str();
|
|
response += "\"}";
|
|
_server->send(500, "text/json", response);
|
|
return;
|
|
}
|
|
if (doc.containsKey("line"))
|
|
{
|
|
updated = userdb->user_by_line(doc["line"].as<userdb::linenumber>());
|
|
}
|
|
if (!updated.match && doc.containsKey("uid"))
|
|
{
|
|
updated = userdb->user_by_uid(doc["uid"].as<unsigned long>());
|
|
}
|
|
if (!updated.match && !_server->pathArg(0).isEmpty())
|
|
{
|
|
updated = userdb->user_by_uid(_server->pathArg(0).toInt());
|
|
}
|
|
|
|
if (updated.match == false)
|
|
{
|
|
_server->send(500, "text/json", "{\"error\":\"user could not be found.\"}");
|
|
return;
|
|
}
|
|
// created.line = doc["line"].as<uint32_t>();
|
|
if (doc.containsKey("uid"))
|
|
updated.uid = doc["uid"].as<unsigned long>();
|
|
if (doc.containsKey("first_name"))
|
|
updated.first_name = doc["first_name"].as<String>();
|
|
if (doc.containsKey("last_name"))
|
|
updated.last_name = doc["last_name"].as<String>();
|
|
if (doc.containsKey("rfid_uid"))
|
|
updated.rfid_uid = doc["rfid_uid"].as<String>();
|
|
if (doc.containsKey("user_pin"))
|
|
updated.user_pin = doc["user_pin"].as<String>();
|
|
if (doc.containsKey("enabled"))
|
|
updated.enabled = doc["enabled"].as<bool>();
|
|
userdb->update_user(&updated);
|
|
_server->send(200, "text/json", updated.toJSONString().c_str());
|
|
}
|
|
void WebConsole::_createUser()
|
|
{
|
|
_sendCORS();
|
|
if (!_isAuth())
|
|
return;
|
|
userdb::User created;
|
|
String body = _server->arg("plain");
|
|
const int capacity = 1024;
|
|
StaticJsonDocument<capacity> doc;
|
|
DeserializationError err = deserializeJson(doc, body);
|
|
if (err.code() != err.Ok)
|
|
{
|
|
Serial.println(err.c_str());
|
|
Serial.println(body);
|
|
String response = "{\"error\":\"";
|
|
response += err.c_str();
|
|
response += "\"}";
|
|
_server->send(500, "text/json", response);
|
|
return;
|
|
}
|
|
if (!_server->pathArg(0).isEmpty())
|
|
created.uid = _server->pathArg(0).toInt();
|
|
else if (!doc["uid"].isNull())
|
|
created.uid = doc["uid"].as<unsigned long>();
|
|
else
|
|
{
|
|
_server->send(500, "text/json", "{\"error\":\"UserId not provided.\"}");
|
|
return;
|
|
}
|
|
created.first_name = doc["first_name"].as<String>();
|
|
created.last_name = doc["last_name"].as<String>();
|
|
created.rfid_uid = doc["rfid_uid"].as<String>();
|
|
created.user_pin = doc["user_pin"].as<String>();
|
|
created.enabled = doc["enabled"].as<bool>();
|
|
userdb->add_user(created);
|
|
_server->send(200, "text/json", created.toJSONString());
|
|
}
|
|
void WebConsole::_dropUserDb()
|
|
{
|
|
_sendCORS();
|
|
if (!_isAuth())
|
|
return;
|
|
if (userdb->drop())
|
|
_server->send(500, "text/json", "{\"ok\":\"UserDb dropped.\"}");
|
|
else
|
|
_server->send(500, "text/json", "{\"error\":\"UserDb could not be dropped.\"}");
|
|
}
|
|
void WebConsole::_catchRFID()
|
|
{
|
|
_sendCORS();
|
|
if (!_isAuth())
|
|
return;
|
|
if (rfid == nullptr)
|
|
{
|
|
_server->send(500, "text/json", "{\"error\":\"RFID not attached.\",\"state\":\"" + String(catch_rfid) + "\"}");
|
|
return;
|
|
}
|
|
if (catch_rfid == 1)
|
|
{
|
|
String response = "{\"rfid_uid\":\"" + rfid_buffer + "\",\"state\":\"" + String(catch_rfid) + "\"}";
|
|
_server->send(200, "text/json", response);
|
|
catch_rfid = 0;
|
|
}
|
|
else
|
|
{
|
|
catch_rfid = 3; // 3 - Start listening
|
|
catch_rfid_millis = millis();
|
|
_server->send(200, "text/json", "{\"ok\":\"listening\",\"state\":\"" + String(catch_rfid) + "\"}");
|
|
}
|
|
}
|
|
void WebConsole::_updateAdmin()
|
|
{
|
|
} |