mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-09 17:29:50 +03:00
Merge branch 'dev' into ft_https
This commit is contained in:
@@ -9,6 +9,7 @@ SecuritySettingsService::SecuritySettingsService(AsyncWebServer * server, FS * f
|
||||
, _fsPersistence(SecuritySettings::read, SecuritySettings::update, this, fs, SECURITY_SETTINGS_FILE)
|
||||
, _jwtHandler(FACTORY_JWT_SECRET) {
|
||||
addUpdateHandler([&](const String & originId) { configureJWTHandler(); }, false);
|
||||
server->on(GENERATE_TOKEN_PATH, HTTP_GET, wrapRequest(std::bind(&SecuritySettingsService::generateToken, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN));
|
||||
}
|
||||
|
||||
void SecuritySettingsService::begin() {
|
||||
@@ -109,6 +110,21 @@ ArJsonRequestHandlerFunction SecuritySettingsService::wrapCallback(ArJsonRequest
|
||||
};
|
||||
}
|
||||
|
||||
void SecuritySettingsService::generateToken(AsyncWebServerRequest* request) {
|
||||
AsyncWebParameter* usernameParam = request->getParam("username");
|
||||
for (User _user : _state.users) {
|
||||
if (_user.username == usernameParam->value()) {
|
||||
AsyncJsonResponse* response = new AsyncJsonResponse(false, GENERATE_TOKEN_SIZE);
|
||||
JsonObject root = response->getRoot();
|
||||
root["token"] = generateJWT(&_user);
|
||||
response->setLength();
|
||||
request->send(response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
request->send(401);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
User ADMIN_USER = User(FACTORY_ADMIN_USERNAME, FACTORY_ADMIN_PASSWORD, true);
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#define SECURITY_SETTINGS_FILE "/config/securitySettings.json"
|
||||
#define SECURITY_SETTINGS_PATH "/rest/securitySettings"
|
||||
|
||||
#define GENERATE_TOKEN_SIZE 512
|
||||
#define GENERATE_TOKEN_PATH "/rest/generateToken"
|
||||
|
||||
#if FT_ENABLED(FT_SECURITY)
|
||||
|
||||
class SecuritySettings {
|
||||
@@ -83,6 +86,8 @@ class SecuritySettingsService : public StatefulService<SecuritySettings>, public
|
||||
FSPersistence<SecuritySettings> _fsPersistence;
|
||||
ArduinoJsonJWT _jwtHandler;
|
||||
|
||||
void generateToken(AsyncWebServerRequest * request);
|
||||
|
||||
void configureJWTHandler();
|
||||
|
||||
/*
|
||||
|
||||
@@ -50,10 +50,7 @@ void Commands::add_command(const flash_string_vector & name, const flash_string_
|
||||
add_command(0, 0, name, arguments, function, nullptr);
|
||||
}
|
||||
|
||||
void Commands::add_command(const flash_string_vector & name,
|
||||
const flash_string_vector & arguments,
|
||||
command_function function,
|
||||
argument_completion_function arg_function) {
|
||||
void Commands::add_command(const flash_string_vector & name, const flash_string_vector & arguments, command_function function, argument_completion_function arg_function) {
|
||||
add_command(0, 0, name, arguments, function, arg_function);
|
||||
}
|
||||
|
||||
@@ -61,20 +58,11 @@ void Commands::add_command(unsigned int context, unsigned int flags, const flash
|
||||
add_command(context, flags, name, flash_string_vector{}, function, nullptr);
|
||||
}
|
||||
|
||||
void Commands::add_command(unsigned int context,
|
||||
unsigned int flags,
|
||||
const flash_string_vector & name,
|
||||
const flash_string_vector & arguments,
|
||||
command_function function) {
|
||||
void Commands::add_command(unsigned int context, unsigned int flags, const flash_string_vector & name, const flash_string_vector & arguments, command_function function) {
|
||||
add_command(context, flags, name, arguments, function, nullptr);
|
||||
}
|
||||
|
||||
void Commands::add_command(unsigned int context,
|
||||
unsigned int flags,
|
||||
const flash_string_vector & name,
|
||||
const flash_string_vector & arguments,
|
||||
command_function function,
|
||||
argument_completion_function arg_function) {
|
||||
void Commands::add_command(unsigned int context, unsigned int flags, const flash_string_vector & name, const flash_string_vector & arguments, command_function function, argument_completion_function arg_function) {
|
||||
commands_.emplace(std::piecewise_construct, std::forward_as_tuple(context), std::forward_as_tuple(flags, name, arguments, function, arg_function));
|
||||
}
|
||||
|
||||
@@ -179,8 +167,7 @@ bool Commands::find_longest_common_prefix(const std::multimap<size_t, const Comm
|
||||
for (auto command_it = std::next(commands.begin()); command_it != commands.end(); command_it++) {
|
||||
// This relies on the null terminator character limiting the
|
||||
// length before it becomes longer than any of the strings
|
||||
if (pgm_read_byte(reinterpret_cast<PGM_P>(first) + length)
|
||||
!= pgm_read_byte(reinterpret_cast<PGM_P>(*std::next(command_it->second->name_.begin(), component_prefix)) + length)) {
|
||||
if (pgm_read_byte(reinterpret_cast<PGM_P>(first) + length) != pgm_read_byte(reinterpret_cast<PGM_P>(*std::next(command_it->second->name_.begin(), component_prefix)) + length)) {
|
||||
all_match = false;
|
||||
break;
|
||||
}
|
||||
@@ -275,8 +262,7 @@ Commands::Completion Commands::complete_command(Shell & shell, const CommandLine
|
||||
result.replacement->push_back(std::move(read_flash_string(name)));
|
||||
}
|
||||
|
||||
if (command_line.total_size() > result.replacement->size()
|
||||
&& command_line.total_size() <= matching_command->name_.size() + matching_command->maximum_arguments()) {
|
||||
if (command_line.total_size() > result.replacement->size() && command_line.total_size() <= matching_command->name_.size() + matching_command->maximum_arguments()) {
|
||||
// Try to auto-complete arguments
|
||||
std::vector<std::string> arguments{std::next(command_line->cbegin(), result.replacement->size()), command_line->cend()};
|
||||
|
||||
@@ -526,11 +512,7 @@ void Commands::for_each_available_command(Shell & shell, apply_function f) const
|
||||
}
|
||||
}
|
||||
|
||||
Commands::Command::Command(unsigned int flags,
|
||||
const flash_string_vector name,
|
||||
const flash_string_vector arguments,
|
||||
command_function function,
|
||||
argument_completion_function arg_function)
|
||||
Commands::Command::Command(unsigned int flags, const flash_string_vector name, const flash_string_vector arguments, command_function function, argument_completion_function arg_function)
|
||||
: flags_(flags)
|
||||
, name_(name)
|
||||
, arguments_(arguments)
|
||||
|
||||
@@ -65,8 +65,10 @@ void Shell::start() {
|
||||
#endif
|
||||
|
||||
line_buffer_.reserve(maximum_command_line_length_);
|
||||
line_old_.reserve(maximum_command_line_length_);
|
||||
line_old_.clear();
|
||||
for (uint8_t i = 0; i < MAX_LINES; i++) {
|
||||
line_old_[i].reserve(maximum_command_line_length_);
|
||||
line_old_[i].clear();
|
||||
}
|
||||
display_banner();
|
||||
display_prompt();
|
||||
shells_.insert(shared_from_this());
|
||||
@@ -156,7 +158,8 @@ void Shell::loop_normal() {
|
||||
// Interrupt (^C)
|
||||
line_buffer_.clear();
|
||||
println();
|
||||
cursor_ = 0;
|
||||
cursor_ = 0;
|
||||
line_no_ = 0;
|
||||
break;
|
||||
|
||||
case '\x04':
|
||||
@@ -172,13 +175,15 @@ void Shell::loop_normal() {
|
||||
// Del/Backspace (^?)
|
||||
if (line_buffer_.length() > cursor_) {
|
||||
line_buffer_.erase(line_buffer_.length() - cursor_ - 1, 1);
|
||||
line_no_ = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\x09':
|
||||
// Tab (^I)
|
||||
process_completion();
|
||||
cursor_ = 0;
|
||||
cursor_ = 0;
|
||||
line_no_ = 0;
|
||||
break;
|
||||
|
||||
case '\x0A':
|
||||
@@ -198,12 +203,14 @@ void Shell::loop_normal() {
|
||||
case '\x15':
|
||||
// Delete line (^U)
|
||||
line_buffer_.clear();
|
||||
cursor_ = 0;
|
||||
cursor_ = 0;
|
||||
line_no_ = 0;
|
||||
break;
|
||||
|
||||
case '\x17':
|
||||
// Delete word (^W)
|
||||
delete_buffer_word(true);
|
||||
line_no_ = 0;
|
||||
break;
|
||||
|
||||
case '\033':
|
||||
@@ -214,10 +221,20 @@ void Shell::loop_normal() {
|
||||
default:
|
||||
if (esc_) {
|
||||
if (c == 'A') { // cursor up
|
||||
line_buffer_ = line_old_;
|
||||
cursor_ = 0;
|
||||
line_buffer_ = line_old_[line_no_];
|
||||
if (line_no_ < MAX_LINES - 1) {
|
||||
line_no_++;
|
||||
}
|
||||
cursor_ = 0;
|
||||
} else if (c == 'B') { // cursor down
|
||||
line_buffer_.clear();
|
||||
if (line_no_) {
|
||||
line_no_--;
|
||||
}
|
||||
if (line_no_) {
|
||||
line_buffer_ = line_old_[line_no_ - 1];
|
||||
} else {
|
||||
line_buffer_.clear();
|
||||
}
|
||||
cursor_ = 0;
|
||||
} else if (c == 'C') { // cursor right
|
||||
if (cursor_) {
|
||||
@@ -239,6 +256,7 @@ void Shell::loop_normal() {
|
||||
if ((esc_ == 3) && cursor_) { // del
|
||||
cursor_--;
|
||||
line_buffer_.erase(line_buffer_.length() - cursor_ - 1, 1);
|
||||
line_no_ = 0;
|
||||
} else if (esc_ == 4) { // end
|
||||
cursor_ = 0;
|
||||
} else if (esc_ == 1) { // pos1
|
||||
@@ -279,6 +297,7 @@ void Shell::loop_normal() {
|
||||
} else if (c >= '\x20' && c <= '\x7E') {
|
||||
if (line_buffer_.length() < maximum_command_line_length_) {
|
||||
line_buffer_.insert(line_buffer_.length() - cursor_, 1, c);
|
||||
line_no_ = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -498,7 +517,12 @@ void Shell::process_command() {
|
||||
println();
|
||||
return;
|
||||
}
|
||||
line_old_ = line_buffer_;
|
||||
uint8_t no = line_no_ ? line_no_ : MAX_LINES;
|
||||
while (--no) {
|
||||
line_old_[no] = line_old_[no - 1];
|
||||
}
|
||||
line_no_ = 0;
|
||||
line_old_[0] = line_buffer_;
|
||||
while (!line_buffer_.empty()) {
|
||||
size_t pos = line_buffer_.find(';');
|
||||
std::string line1;
|
||||
|
||||
@@ -96,7 +96,6 @@ void Shell::output_logs() {
|
||||
}
|
||||
|
||||
::yield();
|
||||
|
||||
}
|
||||
display_prompt();
|
||||
}
|
||||
|
||||
@@ -61,8 +61,9 @@ class Commands;
|
||||
*/
|
||||
class Shell : public std::enable_shared_from_this<Shell>, public uuid::log::Handler, public ::Stream {
|
||||
public:
|
||||
static constexpr size_t MAX_COMMAND_LINE_LENGTH = 80; /*!< Maximum length of a command line. @since 0.1.0 */
|
||||
static constexpr size_t MAX_LOG_MESSAGES = 20; /*!< Maximum number of log messages to buffer before they are output. @since 0.1.0 */
|
||||
static constexpr size_t MAX_COMMAND_LINE_LENGTH = 80; /*!< Maximum length of a command line. @since 0.1.0 */
|
||||
static constexpr size_t MAX_LOG_MESSAGES = 20; /*!< Maximum number of log messages to buffer before they are output. @since 0.1.0 */
|
||||
static constexpr uint8_t MAX_LINES = 5; /*!< Maximum lines in buffer */
|
||||
|
||||
/**
|
||||
* Function to handle the response to a password entry prompt.
|
||||
@@ -903,8 +904,9 @@ class Shell : public std::enable_shared_from_this<Shell>, public uuid::log::Hand
|
||||
unsigned long log_message_id_ = 0; /*!< The next identifier to use for queued log messages. @since 0.1.0 */
|
||||
std::list<QueuedLogMessage> log_messages_; /*!< Queued log messages, in the order they were received. @since 0.1.0 */
|
||||
size_t maximum_log_messages_ = MAX_LOG_MESSAGES; /*!< Maximum command line length in bytes. @since 0.6.0 */
|
||||
std::string line_buffer_; /*!< Command line buffer. Limited to maximum_command_line_length() bytes. @since 0.1.0 */
|
||||
std::string line_old_; /*!< old Command line buffer.*/
|
||||
std::string line_buffer_; /*!< Command line buffer. Limited to maximum_command_line_length() bytes. @since 0.1.0 */
|
||||
std::string line_old_[MAX_LINES]; /*!< old Command line buffer.*/
|
||||
uint8_t line_no_ = 0;
|
||||
size_t maximum_command_line_length_ = MAX_COMMAND_LINE_LENGTH; /*!< Maximum command line length in bytes. @since 0.6.0 */
|
||||
unsigned char previous_ = 0; /*!< Previous character that was entered on the command line. Used to detect CRLF line endings. @since 0.1.0 */
|
||||
uint8_t cursor_ = 0; /*!< cursor position from end of line */
|
||||
|
||||
@@ -199,7 +199,6 @@ SyslogService::QueuedLogMessage::QueuedLogMessage(unsigned long id, std::shared_
|
||||
time_.tv_sec = time(nullptr);
|
||||
time_.tv_usec = 0;
|
||||
#endif
|
||||
|
||||
if (time_.tv_sec >= 0 && time_.tv_sec < 18140 * 86400) {
|
||||
time_.tv_sec = (time_t)-1;
|
||||
}
|
||||
@@ -386,15 +385,20 @@ bool SyslogService::can_transmit() {
|
||||
}
|
||||
|
||||
bool SyslogService::transmit(const QueuedLogMessage & message) {
|
||||
/*
|
||||
// modifications by Proddy. From https://github.com/emsesp/EMS-ESP/issues/395#issuecomment-640053528
|
||||
struct tm tm;
|
||||
int8_t tzh = 0;
|
||||
int8_t tzm = 0;
|
||||
|
||||
tm.tm_year = 0;
|
||||
if (message.time_.tv_sec != (time_t)-1) {
|
||||
gmtime_r(&message.time_.tv_sec, &tm);
|
||||
struct tm utc;
|
||||
gmtime_r(&message.time_.tv_sec, &utc);
|
||||
localtime_r(&message.time_.tv_sec, &tm);
|
||||
int16_t diff = 60 * (tm.tm_hour - utc.tm_hour) + tm.tm_min - utc.tm_min;
|
||||
diff = diff > 720 ? diff - 1440 : diff < -720 ? diff + 1440 : diff;
|
||||
tzh = diff / 60;
|
||||
tzm = diff < 0 ? (0 - diff) % 60 : diff % 60;
|
||||
}
|
||||
*/
|
||||
|
||||
if (udp_.beginPacket(host_, port_) != 1) {
|
||||
last_transmit_ = uuid::get_uptime_ms();
|
||||
@@ -402,30 +406,16 @@ bool SyslogService::transmit(const QueuedLogMessage & message) {
|
||||
}
|
||||
|
||||
udp_.printf_P(PSTR("<%u>1 "), ((unsigned int)message.content_->facility * 8) + std::min(7U, (unsigned int)message.content_->level));
|
||||
|
||||
/*
|
||||
if (tm.tm_year != 0) {
|
||||
udp_.printf_P(PSTR("%04u-%02u-%02uT%02u:%02u:%02u.%06luZ"),
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec,
|
||||
(uint32_t)message.time_.tv_usec);
|
||||
udp_.printf_P(PSTR("%04u-%02u-%02uT%02u:%02u:%02u.%06u%+02d:%02d"), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (uint32_t)message.time_.tv_usec, tzh, tzm);
|
||||
} else {
|
||||
udp_.print('-');
|
||||
}
|
||||
*/
|
||||
|
||||
udp_.print('-');
|
||||
udp_.printf_P(PSTR(" %s - - - - \xEF\xBB\xBF"), hostname_.c_str());
|
||||
udp_.printf_P(PSTR(" %s %s - - - \xEF\xBB\xBF"), hostname_.c_str(), uuid::read_flash_string(message.content_->name).c_str());
|
||||
|
||||
udp_.print(uuid::log::format_timestamp_ms(message.content_->uptime_ms, 3).c_str());
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
udp_.printf_P(PSTR(" %c %lu: [%S] "), uuid::log::format_level_char(message.content_->level), message.id_, message.content_->name);
|
||||
#pragma GCC diagnostic pop
|
||||
udp_.printf_P(PSTR(" %c %lu: "), uuid::log::format_level_char(message.content_->level), message.id_);
|
||||
udp_.print(message.content_->text.c_str());
|
||||
bool ok = (udp_.endPacket() == 1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user