1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-24 06:02:21 +01:00

Merge pull request from GHSA-48mj-p7x2-5jfm

* Move web_server auth to web_server_base

* Fix

* Fix

* Add middleware system
This commit is contained in:
Otto Winter
2021-09-28 02:53:38 +02:00
committed by GitHub
parent 5596751c2c
commit be965a60eb
5 changed files with 81 additions and 25 deletions

View File

@@ -17,6 +17,17 @@ namespace 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() {
StreamString ss;
Update.printError(ss);

View File

@@ -10,6 +10,68 @@
namespace esphome {
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 {
public:
void init() {
@@ -34,13 +96,10 @@ class WebServerBase : public Component {
std::shared_ptr<AsyncWebServer> get_server() const { return server_; }
float get_setup_priority() const override;
void add_handler(AsyncWebHandler *handler) {
// remove all handlers
void set_auth_username(std::string auth_username) { credentials_.username = auth_username; }
void set_auth_password(std::string auth_password) { credentials_.password = auth_password; }
this->handlers_.push_back(handler);
if (this->server_ != nullptr)
this->server_->addHandler(handler);
}
void add_handler(AsyncWebHandler *handler);
void add_ota_handler();
@@ -54,6 +113,7 @@ class WebServerBase : public Component {
uint16_t port_{80};
std::shared_ptr<AsyncWebServer> server_{nullptr};
std::vector<AsyncWebHandler *> handlers_;
internal::Credentials credentials_;
};
class OTARequestHandler : public AsyncWebHandler {