Merge pull request #3760 from TD-er/bugfix/access_rules_passwd

[Web Login] Fix file access with password set (#3759 )
This commit is contained in:
TD-er
2021-08-12 22:29:22 +02:00
committed by GitHub
12 changed files with 99 additions and 134 deletions
-3
View File
@@ -25,9 +25,6 @@ unsigned long timerAwakeFromDeepSleep = 0;
float vcc = -1.0f;
#endif
boolean WebLoggedIn = false;
int WebLoggedInTimer = 300;
String dummyString; // FIXME @TD-er This may take a lot of memory over time, since long-lived Strings only tend to grow.
-3
View File
@@ -92,9 +92,6 @@ extern unsigned long timerAwakeFromDeepSleep;
extern float vcc;
#endif
extern boolean WebLoggedIn;
extern int WebLoggedInTimer;
extern String dummyString; // FIXME @TD-er This may take a lot of memory over time, since long-lived Strings only tend to grow.
-8
View File
@@ -172,14 +172,6 @@ void runOncePerSecond()
// unsigned long elapsed = micros() - start;
if (SecuritySettings.Password[0] != 0)
{
if (WebLoggedIn)
WebLoggedInTimer++;
if (WebLoggedInTimer > 300)
WebLoggedIn = false;
}
// I2C Watchdog feed
if (Settings.WDI2CAddress != 0)
{
-2
View File
@@ -49,8 +49,6 @@ boolean handle_custom(String path) {
return false; // unknown file that does not exist...
}
if (!isLoggedIn()) { return false; }
if (dashboardPage) // for the dashboard page, create a default unit dropdown selector
{
// handle page redirects to other unit's as requested by the unit dropdown selector
+1
View File
@@ -272,6 +272,7 @@ void html_add_form() {
void html_add_autosubmit_form() {
addHtml(F("<script><!--\n"
"function dept_onchange(frmselect) {frmselect.submit();}"
"function rules_set_onchange(rulesselect) {document.getElementById('rules').disabled = true; rulesselect.submit();}"
"\n//--></script>"));
}
+9
View File
@@ -29,10 +29,16 @@ bool loadFromFS(boolean spiffs, String path) {
String dataType = F("text/plain");
bool mustCheckCredentials = false;
const int questionmarkPos = path.indexOf('?');
if (questionmarkPos >= 0) {
path = path.substring(0, questionmarkPos);
}
if (!path.startsWith(F("/"))) {
path = String(F("/")) + path;
}
if (path.endsWith(F("/"))) { path += F("index.htm"); }
if (path.endsWith(F(".src"))) { path = path.substring(0, path.lastIndexOf(".")); }
@@ -55,6 +61,9 @@ bool loadFromFS(boolean spiffs, String path) {
return handle_custom(path);
}
#endif
else {
mustCheckCredentials = true;
}
if (mustCheckCredentials) {
if (!isLoggedIn()) { return false; }
-13
View File
@@ -1,13 +0,0 @@
#ifndef WEBSERVER_WEBSERVER_LOGIN_H
#define WEBSERVER_WEBSERVER_LOGIN_H
#include "../WebServer/common.h"
// ********************************************************************************
// Web Interface login page
// ********************************************************************************
void handle_login();
#endif
+27
View File
@@ -90,6 +90,33 @@ void addSelector(const String & id,
addSelector_Foot();
}
void addSelector_reloadOnChange(
const String& id,
int optionCount,
const String options[],
const int indices[],
const String attr[],
int selectedIndex,
const String& onChangeCall,
bool enabled,
const String& classname
#ifdef ENABLE_TOOLTIPS
,
const String& tooltip
#endif // ifdef ENABLE_TOOLTIPS
)
{
// FIXME TD-er Change boolean to disabled
do_addSelector_Head(id, classname, onChangeCall, !enabled
#ifdef ENABLE_TOOLTIPS
, tooltip
#endif // ifdef ENABLE_TOOLTIPS
);
addSelector_options(optionCount, options, indices, attr, selectedIndex);
addSelector_Foot();
}
void addSelector(const String & id,
int optionCount,
const String options[],
+17
View File
@@ -71,6 +71,23 @@ void addSelector(const String& id,
#endif // ifdef ENABLE_TOOLTIPS
);
void addSelector_reloadOnChange(
const String& id,
int optionCount,
const String options[],
const int indices[],
const String attr[],
int selectedIndex,
const String& onChangeCall,
bool enabled,
const String& classname
#ifdef ENABLE_TOOLTIPS
,
const String& tooltip = EMPTY_STRING
#endif // ifdef ENABLE_TOOLTIPS
);
void addSelector_options(int optionCount,
const __FlashStringHelper *options[],
const int indices[],
+14 -2
View File
@@ -66,7 +66,10 @@ void handle_rules() {
html_table_header(F("Rules"));
html_TR_TD();
addHtml(F("<form name = 'frmselect'>"));
// Need a separate script to only include the 'set' attribute and not also
// send the 'rules' as that will need a lot of memory on the ESP to process.
addHtml(F("<form id='rulesselect' name='rulesselect' method='get'>"));
{
// Place combo box in its own scope to release these arrays as soon as possible
uint8_t choice = rulesSet;
@@ -80,7 +83,16 @@ void handle_rules() {
optionValues[x] = x + 1;
}
addSelector(F("set"), RULESETS_MAX, options, optionValues, NULL, choice, true, true);
addSelector_reloadOnChange(
F("set"),
RULESETS_MAX,
options,
optionValues,
NULL,
choice,
F("return rules_set_onchange(rulesselect)"),
true,
F("wide"));
addHelpButton(F("Tutorial_Rules"));
addRTDHelpButton(F("Rules/Rules.html"));
}
+31 -25
View File
@@ -19,7 +19,6 @@
#include "../WebServer/JSON.h"
#include "../WebServer/LoadFromFS.h"
#include "../WebServer/Log.h"
#include "../WebServer/Login.h"
#include "../WebServer/Markup.h"
#include "../WebServer/Markup_Buttons.h"
#include "../WebServer/Markup_Forms.h"
@@ -47,6 +46,7 @@
#include "../DataTypes/SettingsType.h"
#include "../ESPEasyCore/ESPEasyNetwork.h"
#include "../ESPEasyCore/ESPEasyRules.h"
#include "../ESPEasyCore/ESPEasyWifi.h"
#include "../Globals/CPlugins.h"
@@ -347,7 +347,6 @@ void WebServerInit()
web_server.on(F("/json"), handle_json); // Also part of WEBSERVER_NEW_UI
web_server.on(F("/csv"), handle_csvval);
web_server.on(F("/log"), handle_log);
web_server.on(F("/login"), handle_login);
web_server.on(F("/logjson"), handle_log_JSON); // Also part of WEBSERVER_NEW_UI
#ifdef USES_NOTIFIER
web_server.on(F("/notifications"), handle_notifications);
@@ -969,42 +968,49 @@ void addTaskValueSelect(const String& name, int choice, taskIndex_t TaskIndex)
}
}
// ********************************************************************************
// Login state check
// ********************************************************************************
bool isLoggedIn(bool mustProvideLogin)
{
String www_username = F(DEFAULT_ADMIN_USERNAME);
if (!clientIPallowed()) { return false; }
if (SecuritySettings.Password[0] == 0) { return true; }
if (!mustProvideLogin) {
return false;
}
if (!web_server.authenticate(www_username.c_str(), SecuritySettings.Password))
// Basic Auth Method with Custom realm and Failure Response
// return server.requestAuthentication(BASIC_AUTH, www_realm, authFailResponse);
// Digest Auth Method with realm="Login Required" and empty Failure Response
// return server.requestAuthentication(DIGEST_AUTH);
// Digest Auth Method with Custom realm and empty Failure Response
// return server.requestAuthentication(DIGEST_AUTH, www_realm);
// Digest Auth Method with Custom realm and Failure Response
{
String www_username = F(DEFAULT_ADMIN_USERNAME);
if (!web_server.authenticate(www_username.c_str(), SecuritySettings.Password))
// Basic Auth Method with Custom realm and Failure Response
// return server.requestAuthentication(BASIC_AUTH, www_realm, authFailResponse);
// Digest Auth Method with realm="Login Required" and empty Failure Response
// return server.requestAuthentication(DIGEST_AUTH);
// Digest Auth Method with Custom realm and empty Failure Response
// return server.requestAuthentication(DIGEST_AUTH, www_realm);
// Digest Auth Method with Custom realm and Failure Response
{
#ifdef CORE_PRE_2_5_0
// See https://github.com/esp8266/Arduino/issues/4717
HTTPAuthMethod mode = BASIC_AUTH;
// See https://github.com/esp8266/Arduino/issues/4717
HTTPAuthMethod mode = BASIC_AUTH;
#else // ifdef CORE_PRE_2_5_0
HTTPAuthMethod mode = DIGEST_AUTH;
HTTPAuthMethod mode = DIGEST_AUTH;
#endif // ifdef CORE_PRE_2_5_0
String message = F("Login Required (default user: ");
message += www_username;
message += ')';
web_server.requestAuthentication(mode, message.c_str());
return false;
String message = F("Login Required (default user: ");
message += www_username;
message += ')';
web_server.requestAuthentication(mode, message.c_str());
if (Settings.UseRules)
{
String event = F("Login#Failed");
// TD-er: Do not add to the eventQueue, but execute right now.
rulesProcessing(event);
}
return false;
}
}
return true;
}
-78
View File
@@ -1,78 +0,0 @@
#include "../WebServer/Login.h"
#include "../WebServer/WebServer.h"
#include "../WebServer/AccessControl.h"
#include "../WebServer/HTML_wrappers.h"
#include "../WebServer/Markup.h"
#include "../WebServer/Markup_Buttons.h"
#include "../ESPEasyCore/ESPEasyRules.h"
#include "../Globals/SecuritySettings.h"
#include "../Globals/Settings.h"
#include "../../ESPEasy-Globals.h"
// ********************************************************************************
// Web Interface login page
// ********************************************************************************
void handle_login() {
#ifndef BUILD_NO_RAM_TRACKER
checkRAM(F("handle_login"));
#endif // ifndef BUILD_NO_RAM_TRACKER
if (!clientIPallowed()) { return; }
TXBuffer.startStream();
sendHeadandTail_stdtemplate(_HEAD);
String webrequest = webArg(F("password"));
addHtml(F("<form method='post'>"));
html_table_class_normal();
addHtml(F("<TR><TD>Password<TD>"));
addHtml(F("<input "));
addHtmlAttribute(F("class"), F("wide"));
addHtmlAttribute(F("type"), F("password"));
addHtmlAttribute(F("name"), F("password"));
addHtmlAttribute(F("value"), webrequest);
addHtml('>');
html_TR_TD();
html_TD();
addSubmitButton();
html_TR_TD();
html_end_table();
html_end_form();
if (!webrequest.isEmpty())
{
char command[80];
command[0] = 0;
webrequest.toCharArray(command, 80);
// compare with stored password and set timer if there's a match
if ((strcasecmp(command, SecuritySettings.Password) == 0) || (SecuritySettings.Password[0] == 0))
{
WebLoggedIn = true;
WebLoggedInTimer = 0;
addHtml(F("<script>window.location = '.'</script>"));
}
else
{
addHtml(F("Invalid password!"));
if (Settings.UseRules)
{
String event = F("Login#Failed");
// TD-er: Do not add to the eventQueue, but execute right now.
rulesProcessing(event);
}
}
}
sendHeadandTail_stdtemplate(_TAIL);
TXBuffer.endStream();
printWebString = "";
printToWeb = false;
}