Mirror of espurna firmware for wireless switches and more
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

165 lines
3.3 KiB

/*
Part of the API MODULE
Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
Copyright (C) 2020 by Maxim Prokhorov <prokhorov dot max at outlook dot com>
*/
#include "espurna.h"
#if WEB_SUPPORT
#include "api.h"
#include "web.h"
#include "ws.h"
#endif
// -----------------------------------------------------------------------------
namespace espurna {
namespace api {
namespace {
namespace build {
constexpr bool enabled() {
return 1 == API_ENABLED;
}
constexpr bool restful() {
return 1 == API_RESTFUL;
}
STRING_VIEW_INLINE(Key, API_KEY);
constexpr StringView key() {
return Key;
}
} // namespace build
namespace settings {
namespace keys {
STRING_VIEW_INLINE(Enabled, "apiEnabled");
STRING_VIEW_INLINE(Restful, "apiRestFul");
STRING_VIEW_INLINE(Key, "apiKey");
} // namespace keys
bool enabled() {
return getSetting(keys::Enabled, build::enabled());
}
bool restful() {
return getSetting(keys::Restful, build::restful());
}
String key() {
return getSetting(keys::Key, build::key());
}
} // namespace settings
namespace web {
#if WEB_SUPPORT
bool onKeyCheck(espurna::StringView key, const JsonVariant&) {
return espurna::settings::query::samePrefix(key, STRING_VIEW("api"));
}
void onVisible(JsonObject& root) {
wsPayloadModule(root, PSTR("api"));
}
void onConnected(JsonObject& root) {
root[settings::keys::Enabled] = apiEnabled();
root[settings::keys::Key] = apiKey();
root[settings::keys::Restful] = apiRestFul();
}
void setup() {
wsRegister()
.onVisible(onVisible)
.onConnected(onConnected)
.onKeyCheck(onKeyCheck);
}
bool authenticate_header(AsyncWebServerRequest* request, const String& key) {
STRING_VIEW_INLINE(Header, "Api-Key");
if (settings::enabled() && key.length()) {
auto* header = request->getHeader(Header.toString());
if (header && (key == header->value())) {
return true;
}
}
return false;
}
bool authenticate_param(AsyncWebServerRequest* request, const String& key) {
STRING_VIEW_INLINE(Param, "apikey");
auto* param = request->getParam(Param.toString(), (request->method() == HTTP_PUT));
if (param && (key == param->value())) {
return true;
}
return false;
}
bool authenticate(AsyncWebServerRequest* request) {
const auto key = apiKey();
if (!key.length()) {
return false;
}
if (authenticate_header(request, key)) {
return true;
}
if (authenticate_param(request, key)) {
return true;
}
return false;
}
#endif
} // namespace web
} // namespace
} // namespace api
} // namespace espurna
#if WEB_SUPPORT
bool apiAuthenticateHeader(AsyncWebServerRequest* request, const String& key) {
return espurna::api::web::authenticate_header(request, key);
}
bool apiAuthenticateParam(AsyncWebServerRequest* request, const String& key) {
return espurna::api::web::authenticate_param(request, key);
}
bool apiAuthenticate(AsyncWebServerRequest* request) {
return espurna::api::web::authenticate(request);
}
#endif
String apiKey() {
return espurna::api::settings::key();
}
bool apiEnabled() {
return espurna::api::settings::enabled();
}
bool apiRestFul() {
return espurna::api::settings::restful();
}
void apiCommonSetup() {
#if WEB_SUPPORT
espurna::api::web::setup();
#endif
}