Introduce configuration option to decide wether the web ui is accessable without password or not
This commit is contained in:
parent
a06a8fec3d
commit
4bdbcbccc5
@ -87,6 +87,7 @@ struct CONFIG_T {
|
|||||||
bool Mqtt_Hass_Expire;
|
bool Mqtt_Hass_Expire;
|
||||||
|
|
||||||
char Security_Password[WIFI_MAX_PASSWORD_STRLEN + 1];
|
char Security_Password[WIFI_MAX_PASSWORD_STRLEN + 1];
|
||||||
|
bool Security_AllowReadonly;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigurationClass {
|
class ConfigurationClass {
|
||||||
|
|||||||
@ -9,8 +9,8 @@ public:
|
|||||||
void loop();
|
void loop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onPasswordGet(AsyncWebServerRequest* request);
|
void onSecurityGet(AsyncWebServerRequest* request);
|
||||||
void onPasswordPost(AsyncWebServerRequest* request);
|
void onSecurityPost(AsyncWebServerRequest* request);
|
||||||
|
|
||||||
void onAuthenticateGet(AsyncWebServerRequest* request);
|
void onAuthenticateGet(AsyncWebServerRequest* request);
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#define ACCESS_POINT_NAME "OpenDTU-"
|
#define ACCESS_POINT_NAME "OpenDTU-"
|
||||||
#define ACCESS_POINT_PASSWORD "openDTU42"
|
#define ACCESS_POINT_PASSWORD "openDTU42"
|
||||||
#define AUTH_USERNAME "admin"
|
#define AUTH_USERNAME "admin"
|
||||||
|
#define SECURITY_ALLOW_READONLY true
|
||||||
|
|
||||||
#define ADMIN_TIMEOUT 180
|
#define ADMIN_TIMEOUT 180
|
||||||
#define WIFI_RECONNECT_TIMEOUT 15
|
#define WIFI_RECONNECT_TIMEOUT 15
|
||||||
|
|||||||
@ -77,6 +77,7 @@ bool ConfigurationClass::write()
|
|||||||
|
|
||||||
JsonObject security = doc.createNestedObject("security");
|
JsonObject security = doc.createNestedObject("security");
|
||||||
security["password"] = config.Security_Password;
|
security["password"] = config.Security_Password;
|
||||||
|
security["allow_readonly"] = config.Security_AllowReadonly;
|
||||||
|
|
||||||
JsonArray inverters = doc.createNestedArray("inverters");
|
JsonArray inverters = doc.createNestedArray("inverters");
|
||||||
for (uint8_t i = 0; i < INV_MAX_COUNT; i++) {
|
for (uint8_t i = 0; i < INV_MAX_COUNT; i++) {
|
||||||
@ -197,6 +198,7 @@ bool ConfigurationClass::read()
|
|||||||
|
|
||||||
JsonObject security = doc["security"];
|
JsonObject security = doc["security"];
|
||||||
strlcpy(config.Security_Password, security["password"] | ACCESS_POINT_PASSWORD, sizeof(config.Security_Password));
|
strlcpy(config.Security_Password, security["password"] | ACCESS_POINT_PASSWORD, sizeof(config.Security_Password));
|
||||||
|
config.Security_AllowReadonly = security["allow_readonly"] | SECURITY_ALLOW_READONLY;
|
||||||
|
|
||||||
JsonArray inverters = doc["inverters"];
|
JsonArray inverters = doc["inverters"];
|
||||||
for (uint8_t i = 0; i < INV_MAX_COUNT; i++) {
|
for (uint8_t i = 0; i < INV_MAX_COUNT; i++) {
|
||||||
|
|||||||
@ -15,8 +15,8 @@ void WebApiSecurityClass::init(AsyncWebServer* server)
|
|||||||
|
|
||||||
_server = server;
|
_server = server;
|
||||||
|
|
||||||
_server->on("/api/security/password", HTTP_GET, std::bind(&WebApiSecurityClass::onPasswordGet, this, _1));
|
_server->on("/api/security/config", HTTP_GET, std::bind(&WebApiSecurityClass::onSecurityGet, this, _1));
|
||||||
_server->on("/api/security/password", HTTP_POST, std::bind(&WebApiSecurityClass::onPasswordPost, this, _1));
|
_server->on("/api/security/config", HTTP_POST, std::bind(&WebApiSecurityClass::onSecurityPost, this, _1));
|
||||||
_server->on("/api/security/authenticate", HTTP_GET, std::bind(&WebApiSecurityClass::onAuthenticateGet, this, _1));
|
_server->on("/api/security/authenticate", HTTP_GET, std::bind(&WebApiSecurityClass::onAuthenticateGet, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ void WebApiSecurityClass::loop()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiSecurityClass::onPasswordGet(AsyncWebServerRequest* request)
|
void WebApiSecurityClass::onSecurityGet(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentials(request)) {
|
if (!WebApi.checkCredentials(request)) {
|
||||||
return;
|
return;
|
||||||
@ -35,12 +35,13 @@ void WebApiSecurityClass::onPasswordGet(AsyncWebServerRequest* request)
|
|||||||
const CONFIG_T& config = Configuration.get();
|
const CONFIG_T& config = Configuration.get();
|
||||||
|
|
||||||
root[F("password")] = config.Security_Password;
|
root[F("password")] = config.Security_Password;
|
||||||
|
root[F("allow_readonly")] = config.Security_AllowReadonly;
|
||||||
|
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebApiSecurityClass::onPasswordPost(AsyncWebServerRequest* request)
|
void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (!WebApi.checkCredentials(request)) {
|
if (!WebApi.checkCredentials(request)) {
|
||||||
return;
|
return;
|
||||||
@ -76,7 +77,8 @@ void WebApiSecurityClass::onPasswordPost(AsyncWebServerRequest* request)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!root.containsKey("password")) {
|
if (!root.containsKey("password")
|
||||||
|
&& root.containsKey("allow_readonly")) {
|
||||||
retMsg[F("message")] = F("Values are missing!");
|
retMsg[F("message")] = F("Values are missing!");
|
||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
@ -92,6 +94,7 @@ void WebApiSecurityClass::onPasswordPost(AsyncWebServerRequest* request)
|
|||||||
|
|
||||||
CONFIG_T& config = Configuration.get();
|
CONFIG_T& config = Configuration.get();
|
||||||
strlcpy(config.Security_Password, root[F("password")].as<String>().c_str(), sizeof(config.Security_Password));
|
strlcpy(config.Security_Password, root[F("password")].as<String>().c_str(), sizeof(config.Security_Password));
|
||||||
|
config.Security_AllowReadonly = root[F("allow_readonly")].as<bool>();
|
||||||
Configuration.write();
|
Configuration.write();
|
||||||
|
|
||||||
retMsg[F("type")] = F("success");
|
retMsg[F("type")] = F("success");
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
export interface SecurityConfig {
|
export interface SecurityConfig {
|
||||||
password: string;
|
password: string;
|
||||||
|
allow_readonly: boolean;
|
||||||
}
|
}
|
||||||
@ -32,6 +32,22 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="card mt-5">
|
||||||
|
<div class="card-header text-bg-primary">Permissions</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row mb-3">
|
||||||
|
<label class="col-sm-6 form-check-label" for="inputReadonly">Allow readonly access to web interface</label>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
<input class="form-check-input" type="checkbox" id="inputReadonly"
|
||||||
|
v-model="securityConfigList.allow_readonly" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
<button type="submit" class="btn btn-primary mb-3">Save</button>
|
||||||
</form>
|
</form>
|
||||||
</BasePage>
|
</BasePage>
|
||||||
@ -66,7 +82,7 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
getPasswordConfig() {
|
getPasswordConfig() {
|
||||||
this.dataLoading = true;
|
this.dataLoading = true;
|
||||||
fetch("/api/security/password", { headers: authHeader() })
|
fetch("/api/security/config", { headers: authHeader() })
|
||||||
.then((response) => handleResponse(response, this.$emitter, this.$router))
|
.then((response) => handleResponse(response, this.$emitter, this.$router))
|
||||||
.then(
|
.then(
|
||||||
(data) => {
|
(data) => {
|
||||||
@ -89,7 +105,7 @@ export default defineComponent({
|
|||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("data", JSON.stringify(this.securityConfigList));
|
formData.append("data", JSON.stringify(this.securityConfigList));
|
||||||
|
|
||||||
fetch("/api/security/password", {
|
fetch("/api/security/config", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: authHeader(),
|
headers: authHeader(),
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user