mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	| @@ -281,4 +281,4 @@ async def to_code(config): | |||||||
|     if CONF_HUMIDITY_SETPOINT in config: |     if CONF_HUMIDITY_SETPOINT in config: | ||||||
|         sens = await sensor.new_sensor(config[CONF_HUMIDITY_SETPOINT]) |         sens = await sensor.new_sensor(config[CONF_HUMIDITY_SETPOINT]) | ||||||
|         cg.add(var.set_humidity_setpoint_sensor(sens)) |         cg.add(var.set_humidity_setpoint_sensor(sens)) | ||||||
|     cg.add_library("dudanov/MideaUART", "1.1.5") |     cg.add_library("dudanov/MideaUART", "1.1.8") | ||||||
|   | |||||||
| @@ -34,8 +34,8 @@ CONFIG_SCHEMA = cv.Schema( | |||||||
|         cv.Optional(CONF_JS_INCLUDE): cv.file_, |         cv.Optional(CONF_JS_INCLUDE): cv.file_, | ||||||
|         cv.Optional(CONF_AUTH): cv.Schema( |         cv.Optional(CONF_AUTH): cv.Schema( | ||||||
|             { |             { | ||||||
|                 cv.Required(CONF_USERNAME): cv.string_strict, |                 cv.Required(CONF_USERNAME): cv.All(cv.string_strict, cv.Length(min=1)), | ||||||
|                 cv.Required(CONF_PASSWORD): cv.string_strict, |                 cv.Required(CONF_PASSWORD): cv.All(cv.string_strict, cv.Length(min=1)), | ||||||
|             } |             } | ||||||
|         ), |         ), | ||||||
|         cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id( |         cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id( | ||||||
| @@ -57,8 +57,8 @@ async def to_code(config): | |||||||
|     cg.add(var.set_css_url(config[CONF_CSS_URL])) |     cg.add(var.set_css_url(config[CONF_CSS_URL])) | ||||||
|     cg.add(var.set_js_url(config[CONF_JS_URL])) |     cg.add(var.set_js_url(config[CONF_JS_URL])) | ||||||
|     if CONF_AUTH in config: |     if CONF_AUTH in config: | ||||||
|         cg.add(var.set_username(config[CONF_AUTH][CONF_USERNAME])) |         cg.add(paren.set_auth_username(config[CONF_AUTH][CONF_USERNAME])) | ||||||
|         cg.add(var.set_password(config[CONF_AUTH][CONF_PASSWORD])) |         cg.add(paren.set_auth_password(config[CONF_AUTH][CONF_PASSWORD])) | ||||||
|     if CONF_CSS_INCLUDE in config: |     if CONF_CSS_INCLUDE in config: | ||||||
|         cg.add_define("WEBSERVER_CSS_INCLUDE") |         cg.add_define("WEBSERVER_CSS_INCLUDE") | ||||||
|         path = CORE.relative_config_path(config[CONF_CSS_INCLUDE]) |         path = CORE.relative_config_path(config[CONF_CSS_INCLUDE]) | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| #include "web_server.h" | #include "web_server.h" | ||||||
| #include "esphome/core/log.h" |  | ||||||
| #include "esphome/core/application.h" |  | ||||||
| #include "esphome/core/util.h" |  | ||||||
| #include "esphome/components/json/json_util.h" | #include "esphome/components/json/json_util.h" | ||||||
|  | #include "esphome/core/application.h" | ||||||
|  | #include "esphome/core/log.h" | ||||||
|  | #include "esphome/core/util.h" | ||||||
|  |  | ||||||
| #include "StreamString.h" | #include "StreamString.h" | ||||||
|  |  | ||||||
| @@ -151,9 +151,6 @@ void WebServer::setup() { | |||||||
| void WebServer::dump_config() { | void WebServer::dump_config() { | ||||||
|   ESP_LOGCONFIG(TAG, "Web Server:"); |   ESP_LOGCONFIG(TAG, "Web Server:"); | ||||||
|   ESP_LOGCONFIG(TAG, "  Address: %s:%u", network_get_address().c_str(), this->base_->get_port()); |   ESP_LOGCONFIG(TAG, "  Address: %s:%u", network_get_address().c_str(), this->base_->get_port()); | ||||||
|   if (this->using_auth()) { |  | ||||||
|     ESP_LOGCONFIG(TAG, "  Basic authentication enabled"); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| float WebServer::get_setup_priority() const { return setup_priority::WIFI - 1.0f; } | float WebServer::get_setup_priority() const { return setup_priority::WIFI - 1.0f; } | ||||||
|  |  | ||||||
| @@ -728,10 +725,6 @@ bool WebServer::canHandle(AsyncWebServerRequest *request) { | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
| void WebServer::handleRequest(AsyncWebServerRequest *request) { | void WebServer::handleRequest(AsyncWebServerRequest *request) { | ||||||
|   if (this->using_auth() && !request->authenticate(this->username_, this->password_)) { |  | ||||||
|     return request->requestAuthentication(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (request->url() == "/") { |   if (request->url() == "/") { | ||||||
|     this->handle_index_request(request); |     this->handle_index_request(request); | ||||||
|     return; |     return; | ||||||
|   | |||||||
| @@ -30,10 +30,6 @@ class WebServer : public Controller, public Component, public AsyncWebHandler { | |||||||
|  public: |  public: | ||||||
|   WebServer(web_server_base::WebServerBase *base) : base_(base) {} |   WebServer(web_server_base::WebServerBase *base) : base_(base) {} | ||||||
|  |  | ||||||
|   void set_username(const char *username) { username_ = username; } |  | ||||||
|  |  | ||||||
|   void set_password(const char *password) { password_ = password; } |  | ||||||
|  |  | ||||||
|   /** Set the URL to the CSS <link> that's sent to each client. Defaults to |   /** Set the URL to the CSS <link> that's sent to each client. Defaults to | ||||||
|    * https://esphome.io/_static/webserver-v1.min.css |    * https://esphome.io/_static/webserver-v1.min.css | ||||||
|    * |    * | ||||||
| @@ -83,8 +79,6 @@ class WebServer : public Controller, public Component, public AsyncWebHandler { | |||||||
|   void handle_js_request(AsyncWebServerRequest *request); |   void handle_js_request(AsyncWebServerRequest *request); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   bool using_auth() { return username_ != nullptr && password_ != nullptr; } |  | ||||||
|  |  | ||||||
| #ifdef USE_SENSOR | #ifdef USE_SENSOR | ||||||
|   void on_sensor_update(sensor::Sensor *obj, float state) override; |   void on_sensor_update(sensor::Sensor *obj, float state) override; | ||||||
|   /// Handle a sensor request under '/sensor/<id>'. |   /// Handle a sensor request under '/sensor/<id>'. | ||||||
| @@ -182,8 +176,6 @@ class WebServer : public Controller, public Component, public AsyncWebHandler { | |||||||
|  protected: |  protected: | ||||||
|   web_server_base::WebServerBase *base_; |   web_server_base::WebServerBase *base_; | ||||||
|   AsyncEventSource events_{"/events"}; |   AsyncEventSource events_{"/events"}; | ||||||
|   const char *username_{nullptr}; |  | ||||||
|   const char *password_{nullptr}; |  | ||||||
|   const char *css_url_{nullptr}; |   const char *css_url_{nullptr}; | ||||||
|   const char *css_include_{nullptr}; |   const char *css_include_{nullptr}; | ||||||
|   const char *js_url_{nullptr}; |   const char *js_url_{nullptr}; | ||||||
|   | |||||||
| @@ -15,6 +15,17 @@ namespace web_server_base { | |||||||
|  |  | ||||||
| static const char *const TAG = "web_server_base"; | static const char *const TAG = "web_server_base"; | ||||||
|  |  | ||||||
|  | void WebServerBase::add_handler(AsyncWebHandler *handler) { | ||||||
|  |   // remove all handlers | ||||||
|  |  | ||||||
|  |   if (!credentials_.username.empty()) { | ||||||
|  |     handler = new internal::AuthMiddlewareHandler(handler, &credentials_); | ||||||
|  |   } | ||||||
|  |   this->handlers_.push_back(handler); | ||||||
|  |   if (this->server_ != nullptr) | ||||||
|  |     this->server_->addHandler(handler); | ||||||
|  | } | ||||||
|  |  | ||||||
| void report_ota_error() { | void report_ota_error() { | ||||||
|   StreamString ss; |   StreamString ss; | ||||||
|   Update.printError(ss); |   Update.printError(ss); | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
|  | #include <memory> | ||||||
|  | #include <utility> | ||||||
| #include "esphome/core/component.h" | #include "esphome/core/component.h" | ||||||
|  |  | ||||||
| #include <ESPAsyncWebServer.h> | #include <ESPAsyncWebServer.h> | ||||||
| @@ -7,6 +9,68 @@ | |||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace web_server_base { | namespace web_server_base { | ||||||
|  |  | ||||||
|  | namespace internal { | ||||||
|  |  | ||||||
|  | class MiddlewareHandler : public AsyncWebHandler { | ||||||
|  |  public: | ||||||
|  |   MiddlewareHandler(AsyncWebHandler *next) : next_(next) {} | ||||||
|  |  | ||||||
|  |   bool canHandle(AsyncWebServerRequest *request) override { return next_->canHandle(request); } | ||||||
|  |   void handleRequest(AsyncWebServerRequest *request) override { next_->handleRequest(request); } | ||||||
|  |   void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, | ||||||
|  |                     bool final) override { | ||||||
|  |     next_->handleUpload(request, filename, index, data, len, final); | ||||||
|  |   } | ||||||
|  |   void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override { | ||||||
|  |     next_->handleBody(request, data, len, index, total); | ||||||
|  |   } | ||||||
|  |   bool isRequestHandlerTrivial() override { return next_->isRequestHandlerTrivial(); } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   AsyncWebHandler *next_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | struct Credentials { | ||||||
|  |   std::string username; | ||||||
|  |   std::string password; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | class AuthMiddlewareHandler : public MiddlewareHandler { | ||||||
|  |  public: | ||||||
|  |   AuthMiddlewareHandler(AsyncWebHandler *next, Credentials *credentials) | ||||||
|  |       : MiddlewareHandler(next), credentials_(credentials) {} | ||||||
|  |  | ||||||
|  |   bool check_auth(AsyncWebServerRequest *request) { | ||||||
|  |     bool success = request->authenticate(credentials_->username.c_str(), credentials_->password.c_str()); | ||||||
|  |     if (!success) { | ||||||
|  |       request->requestAuthentication(); | ||||||
|  |     } | ||||||
|  |     return success; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void handleRequest(AsyncWebServerRequest *request) override { | ||||||
|  |     if (!check_auth(request)) | ||||||
|  |       return; | ||||||
|  |     MiddlewareHandler::handleRequest(request); | ||||||
|  |   } | ||||||
|  |   void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, | ||||||
|  |                     bool final) override { | ||||||
|  |     if (!check_auth(request)) | ||||||
|  |       return; | ||||||
|  |     MiddlewareHandler::handleUpload(request, filename, index, data, len, final); | ||||||
|  |   } | ||||||
|  |   void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override { | ||||||
|  |     if (!check_auth(request)) | ||||||
|  |       return; | ||||||
|  |     MiddlewareHandler::handleBody(request, data, len, index, total); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   Credentials *credentials_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace internal | ||||||
|  |  | ||||||
| class WebServerBase : public Component { | class WebServerBase : public Component { | ||||||
|  public: |  public: | ||||||
|   void init() { |   void init() { | ||||||
| @@ -32,13 +96,10 @@ class WebServerBase : public Component { | |||||||
|   AsyncWebServer *get_server() const { return server_; } |   AsyncWebServer *get_server() const { return server_; } | ||||||
|   float get_setup_priority() const override; |   float get_setup_priority() const override; | ||||||
|  |  | ||||||
|   void add_handler(AsyncWebHandler *handler) { |   void set_auth_username(std::string auth_username) { credentials_.username = std::move(auth_username); } | ||||||
|     // remove all handlers |   void set_auth_password(std::string auth_password) { credentials_.password = std::move(auth_password); } | ||||||
|  |  | ||||||
|     this->handlers_.push_back(handler); |   void add_handler(AsyncWebHandler *handler); | ||||||
|     if (this->server_ != nullptr) |  | ||||||
|       this->server_->addHandler(handler); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   void add_ota_handler(); |   void add_ota_handler(); | ||||||
|  |  | ||||||
| @@ -52,6 +113,7 @@ class WebServerBase : public Component { | |||||||
|   uint16_t port_{80}; |   uint16_t port_{80}; | ||||||
|   AsyncWebServer *server_{nullptr}; |   AsyncWebServer *server_{nullptr}; | ||||||
|   std::vector<AsyncWebHandler *> handlers_; |   std::vector<AsyncWebHandler *> handlers_; | ||||||
|  |   internal::Credentials credentials_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class OTARequestHandler : public AsyncWebHandler { | class OTARequestHandler : public AsyncWebHandler { | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| """Constants used by esphome.""" | """Constants used by esphome.""" | ||||||
|  |  | ||||||
| __version__ = "2021.9.1" | __version__ = "2021.9.2" | ||||||
|  |  | ||||||
| ESP_PLATFORM_ESP32 = "ESP32" | ESP_PLATFORM_ESP32 = "ESP32" | ||||||
| ESP_PLATFORM_ESP8266 = "ESP8266" | ESP_PLATFORM_ESP8266 = "ESP8266" | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ lib_deps = | |||||||
|     glmnet/Dsmr@0.3        ; used by dsmr |     glmnet/Dsmr@0.3        ; used by dsmr | ||||||
|     rweather/Crypto@0.2.0  ; used by dsmr |     rweather/Crypto@0.2.0  ; used by dsmr | ||||||
|     esphome/noise-c@0.1.1  ; used by api |     esphome/noise-c@0.1.1  ; used by api | ||||||
|     dudanov/MideaUART@1.1.0  ; used by midea |     dudanov/MideaUART@1.1.8  ; used by midea | ||||||
|  |  | ||||||
| build_flags = | build_flags = | ||||||
|     -DESPHOME_LOG_LEVEL=ESPHOME_LOG_LEVEL_VERY_VERBOSE |     -DESPHOME_LOG_LEVEL=ESPHOME_LOG_LEVEL_VERY_VERBOSE | ||||||
|   | |||||||
| @@ -10,4 +10,4 @@ platformio==5.2.0 | |||||||
| esptool==3.1 | esptool==3.1 | ||||||
| click==7.1.2 | click==7.1.2 | ||||||
| esphome-dashboard==20210908.0 | esphome-dashboard==20210908.0 | ||||||
| aioesphomeapi==9.0.0 | aioesphomeapi==9.1.1 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user