feat: mlock nicht mehr gegen vault
This commit is contained in:
parent
ce18b83ece
commit
a34e80113c
2 changed files with 119 additions and 44 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,4 +1,6 @@
|
||||||
.idea/
|
.idea/
|
||||||
venv/
|
venv/
|
||||||
|
.venv/
|
||||||
.esphome/
|
.esphome/
|
||||||
secrets.yaml
|
secrets.yaml
|
||||||
|
.envrc
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
# todos:
|
|
||||||
# - move code into packages to make this re-useable
|
|
||||||
# - testing
|
|
||||||
|
|
||||||
substitutions:
|
substitutions:
|
||||||
ota_password: ""
|
name_of_board: lasercutter
|
||||||
api_enckey: ""
|
ip_addr: "172.23.23.26"
|
||||||
wifi_ssid: ""
|
machines_token: !secret mlock_machines_token
|
||||||
wifi_password: ""
|
wifi_ssid: !secret wifi_ssid
|
||||||
vault_role_id: ""
|
wifi_password: !secret wifi_password
|
||||||
vault_secret_id: ""
|
ota_password: !secret ota_password
|
||||||
|
api_enckey: !secret api_enckey
|
||||||
|
|
||||||
###### nothing to change below this line ######
|
###### nothing to change below this line ######
|
||||||
esphome:
|
esphome:
|
||||||
|
@ -35,6 +32,7 @@ esp8266:
|
||||||
|
|
||||||
# Enable logging
|
# Enable logging
|
||||||
logger:
|
logger:
|
||||||
|
level: DEBUG
|
||||||
|
|
||||||
api:
|
api:
|
||||||
encryption:
|
encryption:
|
||||||
|
@ -58,6 +56,9 @@ wifi:
|
||||||
dns1: 172.23.23.1
|
dns1: 172.23.23.1
|
||||||
subnet: 255.255.255.0
|
subnet: 255.255.255.0
|
||||||
|
|
||||||
|
on_connect:
|
||||||
|
- script.execute: refresh_access_machines
|
||||||
|
|
||||||
captive_portal:
|
captive_portal:
|
||||||
|
|
||||||
spi:
|
spi:
|
||||||
|
@ -102,7 +103,7 @@ script:
|
||||||
then:
|
then:
|
||||||
- script.execute: toggle_switch
|
- script.execute: toggle_switch
|
||||||
- script.wait: toggle_switch
|
- script.wait: toggle_switch
|
||||||
- if: # return LED to switch state before
|
- if: # set LED to new switch state
|
||||||
condition:
|
condition:
|
||||||
switch.is_on: mlock_${name_of_board}_switch
|
switch.is_on: mlock_${name_of_board}_switch
|
||||||
then:
|
then:
|
||||||
|
@ -110,36 +111,18 @@ script:
|
||||||
else:
|
else:
|
||||||
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
||||||
else:
|
else:
|
||||||
- script.execute: fetch_token_vault
|
- script.execute: check_access_machines
|
||||||
- id: fetch_token_vault
|
- id: check_access_machines
|
||||||
then:
|
mode: queued
|
||||||
# login to vault with role_id to fetch short lived token
|
|
||||||
- http_request.post:
|
|
||||||
url: https://vault.ctdo.de/v1/auth/approle/login
|
|
||||||
verify_ssl: false
|
|
||||||
headers:
|
|
||||||
Content-Type: application/json
|
|
||||||
json:
|
|
||||||
role_id: $vault_role_id
|
|
||||||
secret_id: $vault_secret_id
|
|
||||||
on_response:
|
|
||||||
# fetch token from response, store into vault_api_token
|
|
||||||
then:
|
|
||||||
- lambda: |-
|
|
||||||
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
|
|
||||||
id(vault_api_token) = (const char*) root["auth"]["client_token"];
|
|
||||||
});
|
|
||||||
- script.execute: check_access_vault
|
|
||||||
- id: check_access_vault
|
|
||||||
then:
|
then:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
id(access_allowed) = false;
|
id(access_allowed) = false;
|
||||||
- http_request.get:
|
- http_request.get:
|
||||||
url: !lambda |-
|
url: !lambda |-
|
||||||
return ((std::string) "https://vault.ctdo.de/v1/maschinenlock/" + id(rfid_tag));
|
return ((std::string) "https://machines.ctdo.de/machine/mlock-$name_of_board");
|
||||||
verify_ssl: false
|
verify_ssl: false
|
||||||
headers:
|
headers:
|
||||||
X-Vault-Token: !lambda return id(vault_api_token).c_str();
|
Authorization: !lambda return "Bearer $machines_token";
|
||||||
on_response:
|
on_response:
|
||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
|
@ -147,15 +130,27 @@ script:
|
||||||
lambda: 'return status_code == 200;'
|
lambda: 'return status_code == 200;'
|
||||||
then: # when found, check if machine is allowed, turn on output or blink LED red
|
then: # when found, check if machine is allowed, turn on output or blink LED red
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
|
std::string response = id(http_request_data).get_string();
|
||||||
id(access_allowed) = (root["data"]["mlock-$name_of_board"] == "1");
|
id(process_machines_response)->execute(response);
|
||||||
});
|
DynamicJsonDocument doc(2048);
|
||||||
|
deserializeJson(doc, response);
|
||||||
|
unsigned int rfid_value = decode_token(id(rfid_tag));
|
||||||
|
for (JsonVariant elem : doc.as<JsonArray>()) {
|
||||||
|
std::string received_token = elem.as<std::string>();
|
||||||
|
int received_value = decode_token(received_token);
|
||||||
|
if (rfid_value == received_value) {
|
||||||
|
id(access_allowed) = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(access_allowed);'
|
lambda: 'return id(access_allowed);'
|
||||||
then:
|
then:
|
||||||
- script.execute: toggle_switch
|
- script.execute: toggle_switch
|
||||||
- script.execute: cache_token
|
- script.execute:
|
||||||
|
id: cache_token
|
||||||
|
token: !lambda return id(rfid_tag);
|
||||||
- script.wait: toggle_switch
|
- script.wait: toggle_switch
|
||||||
else:
|
else:
|
||||||
- repeat:
|
- repeat:
|
||||||
|
@ -165,15 +160,15 @@ script:
|
||||||
- delay: 0.1s
|
- delay: 0.1s
|
||||||
- light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% }
|
- light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% }
|
||||||
- delay: 0.1s
|
- delay: 0.1s
|
||||||
else: # vault returns 404 on missing/unknown Tag so blink LED
|
else: # could not fetch machine config, so blink LED
|
||||||
- repeat:
|
- repeat:
|
||||||
count: 3
|
count: 5
|
||||||
then:
|
then:
|
||||||
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
||||||
- delay: 0.5s
|
- delay: 0.8s
|
||||||
- light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% }
|
- light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% }
|
||||||
- delay: 0.5s
|
- delay: 0.8s
|
||||||
- if: # return LED to switch state before
|
- if: # return LED to switch state
|
||||||
condition:
|
condition:
|
||||||
switch.is_on: mlock_${name_of_board}_switch
|
switch.is_on: mlock_${name_of_board}_switch
|
||||||
then:
|
then:
|
||||||
|
@ -181,6 +176,7 @@ script:
|
||||||
else:
|
else:
|
||||||
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
||||||
- id: toggle_switch
|
- id: toggle_switch
|
||||||
|
mode: queued
|
||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
|
@ -203,9 +199,13 @@ script:
|
||||||
id: ${name_of_board}_letzte_entsperrung
|
id: ${name_of_board}_letzte_entsperrung
|
||||||
value: !lambda return id(rfid_tag);
|
value: !lambda return id(rfid_tag);
|
||||||
- id: cache_token
|
- id: cache_token
|
||||||
|
mode: queued
|
||||||
|
parameters:
|
||||||
|
token: string
|
||||||
then:
|
then:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
int rfid_value = decode_token(id(rfid_tag));
|
ESP_LOGI("mlock", "Caching token: %s", token.c_str());
|
||||||
|
int rfid_value = decode_token(token);
|
||||||
int rfid_value_pos = 23;
|
int rfid_value_pos = 23;
|
||||||
// search the token in the list to keep the access_cache unique
|
// search the token in the list to keep the access_cache unique
|
||||||
for (int i = 0; i < 24; i++) {
|
for (int i = 0; i < 24; i++) {
|
||||||
|
@ -220,6 +220,79 @@ script:
|
||||||
}
|
}
|
||||||
// write the new token to the start
|
// write the new token to the start
|
||||||
id(access_cache)[0] = rfid_value;
|
id(access_cache)[0] = rfid_value;
|
||||||
|
- id: refresh_access_machines
|
||||||
|
mode: queued
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
tag: mlock
|
||||||
|
level: info
|
||||||
|
format: "Fetching config"
|
||||||
|
- http_request.get:
|
||||||
|
url: !lambda |-
|
||||||
|
return ((std::string) "https://machines.ctdo.de/machine/mlock-$name_of_board");
|
||||||
|
verify_ssl: false
|
||||||
|
headers:
|
||||||
|
Authorization: !lambda return "Bearer $machines_token";
|
||||||
|
on_response:
|
||||||
|
then:
|
||||||
|
- script.execute:
|
||||||
|
id: process_machines_response
|
||||||
|
response: !lambda return id(http_request_data).get_string();
|
||||||
|
- id: process_machines_response
|
||||||
|
mode: queued
|
||||||
|
parameters:
|
||||||
|
response: string
|
||||||
|
then:
|
||||||
|
- logger.log:
|
||||||
|
tag: mlock
|
||||||
|
level: info
|
||||||
|
format: "Allowed tokens: %s"
|
||||||
|
args: [ 'response.c_str()' ]
|
||||||
|
- lambda: |-
|
||||||
|
DynamicJsonDocument doc(2048);
|
||||||
|
deserializeJson(doc, response);
|
||||||
|
JsonArray array = doc.as<JsonArray>();
|
||||||
|
// invalidate cached tokens that are not allowed anymore
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
unsigned int cached_token = id(access_cache)[i];
|
||||||
|
if (cached_token == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bool token_valid = false;
|
||||||
|
// search for cached token in the allowed list
|
||||||
|
for (JsonVariant elem : array) {
|
||||||
|
std::string received_token = elem.as<std::string>();
|
||||||
|
int received_value = decode_token(received_token);
|
||||||
|
if (cached_token == received_value) {
|
||||||
|
token_valid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!token_valid) {
|
||||||
|
ESP_LOGI("mlock", "Purging removed token: %08X", id(access_cache)[i]);
|
||||||
|
// move remaining tokens up in the cache
|
||||||
|
for (int j = i; j < 23; j++) {
|
||||||
|
id(access_cache)[j] = id(access_cache)[j + 1];
|
||||||
|
}
|
||||||
|
id(access_cache)[23] = 0;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (JsonVariant elem : array) {
|
||||||
|
std::string received_token = elem.as<std::string>();
|
||||||
|
int received_value = decode_token(received_token);
|
||||||
|
// append the token at the end of the cache in an empty slot if it is not in there yet
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
if (id(access_cache)[i] == received_value) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (id(access_cache)[i] == 0) {
|
||||||
|
ESP_LOGI("mlock", "Pre-caching token: %X", received_value);
|
||||||
|
id(access_cache)[i] = received_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rc522_spi:
|
rc522_spi:
|
||||||
cs_pin: GPIO15
|
cs_pin: GPIO15
|
||||||
|
|
Loading…
Reference in a new issue