/*
|
|
|
|
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
|
|
}
|