added login / logout

prepared static IP storage and disable inverter
IMPORTANT: new memory layout, your inverter settings will be lost
This commit is contained in:
lumapu 2022-11-02 22:41:31 +01:00
parent 56b8096bed
commit 6a6d522d3b
11 changed files with 290 additions and 31 deletions

View file

@ -11,6 +11,7 @@
#include "web.h"
#include "html/h/index_html.h"
#include "html/h/login_html.h"
#include "html/h/style_css.h"
#include "html/h/api_js.h"
#include "html/h/favicon_ico_gz.h"
@ -33,6 +34,9 @@ web::web(app *main, sysConfig_t *sysCfg, config_t *config, statistics_t *stat, c
mEvts = new AsyncEventSource("/events");
mApi = new webApi(mWeb, main, sysCfg, config, stat, version);
mProtected = true;
mLogoutTimeout = 0;
memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE);
mSerialBufFill = 0;
mWebSerialTicker = 0;
@ -47,6 +51,8 @@ void web::setup(void) {
mWeb->begin();
DPRINTLN(DBG_VERBOSE, F("app::setup-on"));
mWeb->on("/", HTTP_GET, std::bind(&web::onIndex, this, std::placeholders::_1));
mWeb->on("/login", HTTP_ANY, std::bind(&web::onLogin, this, std::placeholders::_1));
mWeb->on("/logout", HTTP_GET, std::bind(&web::onLogout, this, std::placeholders::_1));
mWeb->on("/style.css", HTTP_GET, std::bind(&web::onCss, this, std::placeholders::_1));
mWeb->on("/api.js", HTTP_GET, std::bind(&web::onApiJs, this, std::placeholders::_1));
mWeb->on("/favicon.ico", HTTP_GET, std::bind(&web::onFavicon, this, std::placeholders::_1));
@ -77,7 +83,6 @@ void web::setup(void) {
registerDebugCb(std::bind(&web::serialCb, this, std::placeholders::_1));
}
//-----------------------------------------------------------------------------
void web::loop(void) {
mApi->loop();
@ -91,6 +96,21 @@ void web::loop(void) {
}
}
//-----------------------------------------------------------------------------
void web::tickSecond(void) {
if(0 != mLogoutTimeout) {
mLogoutTimeout -= 1;
if(0 == mLogoutTimeout)
mProtected = true;
DPRINTLN(DBG_DEBUG, "auto logout in " + String(mLogoutTimeout));
}
}
//-----------------------------------------------------------------------------
void web::setProtection(bool protect) {
mProtected = protect;
}
//-----------------------------------------------------------------------------
void web::onConnect(AsyncEventSourceClient *client) {
@ -107,14 +127,37 @@ void web::onConnect(AsyncEventSourceClient *client) {
void web::onIndex(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onIndex"));
if(mProtected) {
request->redirect("/login");
return;
}
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), index_html, index_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
}
//-----------------------------------------------------------------------------
void web::onLogin(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onLogin"));
if(request->args() > 0) {
if(String(request->arg("pwd")) == String(mConfig->password)) {
mProtected = false;
request->redirect("/");
}
}
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), login_html, login_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
}
//-----------------------------------------------------------------------------
void web::onCss(AsyncWebServerRequest *request) {
mLogoutTimeout = LOGOUT_TIMEOUT;
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/css"), style_css, style_css_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
@ -163,7 +206,9 @@ void web::showNotFound(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void web::onReboot(AsyncWebServerRequest *request) {
mMain->mShouldReboot = true;
request->send(200, F("text/html"), F("<!doctype html><html><head><title>Reboot</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta http-equiv=\"refresh\" content=\"10; URL=/\"></head><body>reboot. Autoreload after 10 seconds</body></html>"));
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), system_html, system_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
}
@ -171,6 +216,28 @@ void web::onReboot(AsyncWebServerRequest *request) {
void web::onSystem(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onSystem"));
if(mProtected) {
request->redirect("/login");
return;
}
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), system_html, system_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
}
//-----------------------------------------------------------------------------
void web::onLogout(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onLogout"));
if(mProtected) {
request->redirect("/login");
return;
}
mProtected = true;
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), system_html, system_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
@ -179,6 +246,11 @@ void web::onSystem(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void web::showErase(AsyncWebServerRequest *request) {
if(mProtected) {
request->redirect("/login");
return;
}
DPRINTLN(DBG_VERBOSE, F("showErase"));
mMain->eraseSettings();
onReboot(request);
@ -187,6 +259,11 @@ void web::showErase(AsyncWebServerRequest *request) {
//-----------------------------------------------------------------------------
void web::showFactoryRst(AsyncWebServerRequest *request) {
if(mProtected) {
request->redirect("/login");
return;
}
DPRINTLN(DBG_VERBOSE, F("showFactoryRst"));
String content = "";
int refresh = 3;
@ -218,6 +295,11 @@ void web::showFactoryRst(AsyncWebServerRequest *request) {
void web::onSetup(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onSetup"));
if(mProtected) {
request->redirect("/login");
return;
}
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), setup_html, setup_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
@ -228,6 +310,11 @@ void web::onSetup(AsyncWebServerRequest *request) {
void web::showSave(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("showSave"));
if(mProtected) {
request->redirect("/login");
return;
}
if(request->args() > 0) {
char buf[20] = {0};
@ -238,6 +325,10 @@ void web::showSave(AsyncWebServerRequest *request) {
request->arg("pwd").toCharArray(mSysCfg->stationPwd, PWD_LEN);
if(request->arg("device") != "")
request->arg("device").toCharArray(mSysCfg->deviceName, DEVNAME_LEN);
if(request->arg("adminpwd") != "{PWD}") {
request->arg("adminpwd").toCharArray(mConfig->password, PWD_LEN);
mProtected = true;
}
// inverter
Inverter<> *iv;
@ -272,7 +363,7 @@ void web::showSave(AsyncWebServerRequest *request) {
// Disclaimer
if(request->arg("disclaimer") != "")
mConfig->disclaimer = strcmp("true", request->arg("disclaimer").c_str()) == 0 ? true : false;
mConfig->disclaimer = strcmp("true", request->arg("disclaimer").c_str()) == 0 ? true : false;
DPRINTLN(DBG_INFO, request->arg("disclaimer").c_str());
// pinout
@ -305,7 +396,7 @@ void web::showSave(AsyncWebServerRequest *request) {
mConfig->sunLon = request->arg("sunLon").toFloat();
mConfig->sunDisNightCom = (request->arg("sunDisNightCom") == "on");
}
// mqtt
if(request->arg("mqttAddr") != "") {
@ -333,9 +424,11 @@ void web::showSave(AsyncWebServerRequest *request) {
if(request->arg("reboot") == "on")
onReboot(request);
else
request->send(200, F("text/html"), F("<!doctype html><html><head><title>Setup saved</title><meta http-equiv=\"refresh\" content=\"0; URL=/setup\"></head><body>"
"<p>saved</p></body></html>"));
else {
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), system_html, system_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
}
}
}
@ -344,6 +437,11 @@ void web::showSave(AsyncWebServerRequest *request) {
void web::onLive(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onLive"));
if(mProtected) {
request->redirect("/login");
return;
}
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), visualization_html, visualization_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
@ -368,13 +466,13 @@ void web::showWebApi(AsyncWebServerRequest *request) {
// if the AlarmData is requested set the Alarm Index to the requested one
if (cmd == AlarmData || cmd == AlarmUpdate) {
// set the AlarmMesIndex for the request from user input
iv->alarmMesIndex = response["payload"];
iv->alarmMesIndex = response["payload"];
}
DPRINTLN(DBG_INFO, F("Will make tx-request 0x15 with subcmd ") + String(cmd) + F(" and payload ") + String((uint16_t) response["payload"]));
// process payload from web request corresponding to the cmd
iv->enqueCommand<InfoCommand>(cmd);
}
if (response["tx_request"] == (uint8_t)TX_REQ_DEVCONTROL) {
if (response["cmd"] == (uint8_t)ActivePowerContr) {
@ -409,7 +507,7 @@ void web::showWebApi(AsyncWebServerRequest *request) {
if (response["cmd"] == (uint8_t)Restart) {
iv->devControlCmd = Restart;
iv->devControlRequest = true; // queue it in the request loop
}
}
}
}
request->send(200, "text/json", "{success:true}");
@ -420,6 +518,10 @@ void web::showWebApi(AsyncWebServerRequest *request) {
void web::onUpdate(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onUpdate"));
/*if(mProtected) {
request->redirect("/login");
return;
}*/
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), update_html, update_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
@ -449,7 +551,7 @@ void web::showUpdate(AsyncWebServerRequest *request) {
void web::showUpdate2(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
if(!index) {
Serial.printf("Update Start: %s\n", filename.c_str());
#ifndef ESP32
#ifndef ESP32
Update.runAsync(true);
#endif
if(!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)) {
@ -475,6 +577,11 @@ void web::showUpdate2(AsyncWebServerRequest *request, String filename, size_t in
void web::onSerial(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("onSerial"));
if(mProtected) {
request->redirect("/login");
return;
}
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), serial_html, serial_html_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);