mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-01 02:01:38 +02:00
0.8.77
* merge PR: BugFix: ACK #1414 * fix suspicious if condition #1416 * prepared API token for access, not functional #1415
This commit is contained in:
parent
d4a4f9cfb6
commit
15349520d2
9 changed files with 98 additions and 23 deletions
|
@ -1,5 +1,10 @@
|
|||
# Development Changes
|
||||
|
||||
## 0.8.77 - 2024-02-08
|
||||
* merge PR: BugFix: ACK #1414
|
||||
* fix suspicious if condition #1416
|
||||
* prepared API token for access, not functional #1415
|
||||
|
||||
## 0.8.76 - 2024-02-07
|
||||
* revert changes from yesterday regarding snprintf and its size #1410, #1411
|
||||
* reduced cppcheck linter warnings significantly
|
||||
|
|
|
@ -239,7 +239,7 @@ void app::updateNtp(void) {
|
|||
}
|
||||
}
|
||||
|
||||
if ((mSunrise == 0) && (mConfig->sun.lat) && (mConfig->sun.lon)) {
|
||||
if ((0 == mSunrise) && (0.0 != mConfig->sun.lat) && (0.0 != mConfig->sun.lon)) {
|
||||
mCalculatedTimezoneOffset = (int8_t)((mConfig->sun.lon >= 0 ? mConfig->sun.lon + 7.5 : mConfig->sun.lon - 7.5) / 15) * 3600;
|
||||
tickCalcSunrise();
|
||||
}
|
||||
|
|
|
@ -251,8 +251,8 @@ class app : public IApp, public ah::Scheduler {
|
|||
mProtection->lock();
|
||||
}
|
||||
|
||||
void unlock(const char *clientIp) override {
|
||||
mProtection->unlock(clientIp);
|
||||
char *unlock(const char *clientIp) override {
|
||||
return mProtection->unlock(clientIp);
|
||||
}
|
||||
|
||||
void resetLockTimeout(void) override {
|
||||
|
@ -267,6 +267,10 @@ class app : public IApp, public ah::Scheduler {
|
|||
return mProtection->isProtected(clientIp);
|
||||
}
|
||||
|
||||
bool isProtected(const char *clientIp, const char *token) const override {
|
||||
return mProtection->isProtected(clientIp, token);
|
||||
}
|
||||
|
||||
bool getNrfEnabled(void) override {
|
||||
return mConfig->nrf.enabled;
|
||||
}
|
||||
|
|
|
@ -62,10 +62,11 @@ class IApp {
|
|||
virtual uint32_t getMqttTxCnt() = 0;
|
||||
|
||||
virtual void lock(void) = 0;
|
||||
virtual void unlock(const char *clientIp) = 0;
|
||||
virtual char *unlock(const char *clientIp) = 0;
|
||||
virtual void resetLockTimeout(void) = 0;
|
||||
virtual bool isProtected(void) const = 0;
|
||||
virtual bool isProtected(const char *clientIp) const = 0;
|
||||
virtual bool isProtected(const char *clientIp, const char *token) const = 0;
|
||||
|
||||
virtual uint16_t getHistoryValue(uint8_t type, uint16_t i) = 0;
|
||||
virtual uint16_t getHistoryMaxDay() = 0;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 8
|
||||
#define VERSION_PATCH 76
|
||||
#define VERSION_PATCH 77
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -19,6 +19,7 @@ class Protection {
|
|||
mPwd = pwd;
|
||||
mLogoutTimeout = 0;
|
||||
mLoginIp.fill(0);
|
||||
mToken.fill(0);
|
||||
|
||||
// no password set - unlock
|
||||
if(pwd[0] == '\0')
|
||||
|
@ -50,13 +51,17 @@ class Protection {
|
|||
mLoginIp.fill(0);
|
||||
}
|
||||
|
||||
void unlock(const char *clientIp) {
|
||||
char *unlock(const char *clientIp) {
|
||||
mLogoutTimeout = LOGOUT_TIMEOUT;
|
||||
mProtected = false;
|
||||
ah::ip2Arr(static_cast<uint8_t*>(mLoginIp.data()), clientIp);
|
||||
genToken();
|
||||
|
||||
return reinterpret_cast<char*>(mToken.data());
|
||||
}
|
||||
|
||||
void resetLockTimeout(void) {
|
||||
if(0 != mLogoutTimeout)
|
||||
mLogoutTimeout = LOGOUT_TIMEOUT;
|
||||
}
|
||||
|
||||
|
@ -64,6 +69,16 @@ class Protection {
|
|||
return mProtected;
|
||||
}
|
||||
|
||||
bool isProtected(const char *clientIp, const char *token) const {
|
||||
if(isProtected(clientIp))
|
||||
return true;
|
||||
|
||||
if(0 == mToken[0]) // token is zero
|
||||
return true;
|
||||
|
||||
return (0 != strncmp(token, mToken.data(), 16));
|
||||
}
|
||||
|
||||
bool isProtected(const char *clientIp) const {
|
||||
if(mProtected)
|
||||
return true;
|
||||
|
@ -81,14 +96,27 @@ class Protection {
|
|||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
void genToken() {
|
||||
mToken.fill(0);
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
mToken[i] = random(1, 35);
|
||||
if(mToken[i] < 10)
|
||||
mToken[i] += 0x30; // convert to ascii number 1-9 (zero isn't allowed)
|
||||
else
|
||||
mToken[i] += 0x37; // convert to ascii upper case character
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
static Protection *mInstance;
|
||||
|
||||
private:
|
||||
const char *mPwd;
|
||||
bool mProtected = true;
|
||||
uint16_t mLogoutTimeout = LOGOUT_TIMEOUT;
|
||||
uint16_t mLogoutTimeout = 0;
|
||||
std::array<uint8_t, 4> mLoginIp;
|
||||
std::array<char, 17> mToken;
|
||||
};
|
||||
|
||||
#endif /*__PROTECTION_H__*/
|
||||
|
|
|
@ -70,7 +70,7 @@ class RestApi {
|
|||
if(obj[F("path")] == "ctrl")
|
||||
setCtrl(obj, dummy, "*");
|
||||
else if(obj[F("path")] == "setup")
|
||||
setSetup(obj, dummy);
|
||||
setSetup(obj, dummy, "*");
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -169,7 +169,7 @@ class RestApi {
|
|||
if(path == "ctrl")
|
||||
root[F("success")] = setCtrl(obj, root, request->client()->remoteIP().toString().c_str());
|
||||
else if(path == "setup")
|
||||
root[F("success")] = setSetup(obj, root);
|
||||
root[F("success")] = setSetup(obj, root, request->client()->remoteIP().toString().c_str());
|
||||
else {
|
||||
root[F("success")] = false;
|
||||
root[F("error")] = F(PATH_NOT_FOUND) + path;
|
||||
|
@ -831,6 +831,36 @@ class RestApi {
|
|||
}
|
||||
|
||||
bool setCtrl(JsonObject jsonIn, JsonObject jsonOut, const char *clientIP) {
|
||||
if(F("auth") == jsonIn[F("cmd")]) {
|
||||
if(String(jsonIn["val"]) == String(mConfig->sys.adminPwd))
|
||||
jsonOut["token"] = mApp->unlock(clientIP);
|
||||
else {
|
||||
jsonOut[F("error")] = F(AUTH_ERROR);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*if(mConfig->sys.adminPwd[0] != '\0') { // check if admin password is set
|
||||
if(strncmp("*", clientIP, 1) != 0) { // no call from MqTT
|
||||
const char* token = jsonIn["token"];
|
||||
if(mApp->isProtected(clientIP, token)) {
|
||||
jsonOut[F("error")] = F(IS_PROTECTED);
|
||||
jsonOut[F("bla")] = String(token);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if(mConfig->sys.adminPwd[0] != '\0') { // check if admin password is set
|
||||
if(strncmp("*", clientIP, 1) != 0) { // no call from MqTT
|
||||
if(mApp->isProtected(clientIP)) {
|
||||
jsonOut[F("error")] = F(IS_PROTECTED);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Inverter<> *iv = mSys->getInverterByPos(jsonIn[F("id")]);
|
||||
bool accepted = true;
|
||||
if(NULL == iv) {
|
||||
|
@ -839,15 +869,6 @@ class RestApi {
|
|||
}
|
||||
jsonOut[F("id")] = jsonIn[F("id")];
|
||||
|
||||
if(mConfig->sys.adminPwd[0] != '\0') {
|
||||
if(strncmp("*", clientIP, 1) != 0) { // no call from API (MqTT)
|
||||
if(mApp->isProtected(clientIP)) {
|
||||
jsonOut[F("error")] = F(INV_IS_PROTECTED);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(F("power") == jsonIn[F("cmd")])
|
||||
accepted = iv->setDevControlRequest((jsonIn[F("val")] == 1) ? TurnOn : TurnOff);
|
||||
else if(F("restart") == jsonIn[F("cmd")])
|
||||
|
@ -882,7 +903,17 @@ class RestApi {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool setSetup(JsonObject jsonIn, JsonObject jsonOut) {
|
||||
bool setSetup(JsonObject jsonIn, JsonObject jsonOut, const char *clientIP) {
|
||||
/*if(mConfig->sys.adminPwd[0] != '\0') { // check if admin password is set
|
||||
if(strncmp("*", clientIP, 1) != 0) { // no call from MqTT
|
||||
const char* token = jsonIn["token"];
|
||||
if(mApp->isProtected(clientIP, token)) {
|
||||
jsonOut[F("error")] = F(IS_PROTECTED);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
#if !defined(ETHERNET)
|
||||
if(F("scan_wifi") == jsonIn[F("cmd")])
|
||||
mApp->scanAvailNetworks();
|
||||
|
|
|
@ -30,6 +30,12 @@
|
|||
#define INV_INDEX_INVALID "inverter index invalid: "
|
||||
#endif
|
||||
|
||||
#ifdef LANG_DE
|
||||
#define AUTH_ERROR "Authentifizierungsfehler"
|
||||
#else /*LANG_EN*/
|
||||
#define AUTH_ERROR "authentication error"
|
||||
#endif
|
||||
|
||||
#ifdef LANG_DE
|
||||
#define UNKNOWN_CMD "unbekanntes Kommando: '"
|
||||
#else /*LANG_EN*/
|
||||
|
@ -37,9 +43,9 @@
|
|||
#endif
|
||||
|
||||
#ifdef LANG_DE
|
||||
#define INV_IS_PROTECTED "nicht angemeldet, Kommando nicht möglich!"
|
||||
#define IS_PROTECTED "nicht angemeldet, Kommando nicht möglich!"
|
||||
#else /*LANG_EN*/
|
||||
#define INV_IS_PROTECTED "not logged in, command not possible!"
|
||||
#define IS_PROTECTED "not logged in, command not possible!"
|
||||
#endif
|
||||
|
||||
#ifdef LANG_DE
|
||||
|
|
|
@ -782,7 +782,7 @@ class Web {
|
|||
// report value
|
||||
if (0 == channel) {
|
||||
// Report a _total value if also channel values were reported. Otherwise report without _total
|
||||
char total[7];
|
||||
char total[7] = {0};
|
||||
if (metricDeclared) {
|
||||
// A declaration and value for channels have been delivered. So declare and deliver a _total metric
|
||||
snprintf(total, sizeof(total), "_total");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue