mlock: cache valid tokens
This commit is contained in:
parent
8007a86bbf
commit
ce18b83ece
|
@ -0,0 +1,9 @@
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
int decode_token(std::string token) {
|
||||||
|
// strip dashes from token
|
||||||
|
token.erase(std::remove(token.begin(), token.end(), '-'), token.end());
|
||||||
|
// parse token from hex to unsigned int
|
||||||
|
return static_cast<unsigned int>(std::stoll(token, nullptr, 16));
|
||||||
|
}
|
|
@ -13,8 +13,8 @@ substitutions:
|
||||||
###### nothing to change below this line ######
|
###### nothing to change below this line ######
|
||||||
esphome:
|
esphome:
|
||||||
name: mlock-${name_of_board}
|
name: mlock-${name_of_board}
|
||||||
platform: ESP8266
|
includes:
|
||||||
board: d1_mini
|
- mlock-common.h
|
||||||
on_boot:
|
on_boot:
|
||||||
- priority: 300
|
- priority: 300
|
||||||
then:
|
then:
|
||||||
|
@ -29,6 +29,10 @@ esphome:
|
||||||
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% }
|
||||||
|
|
||||||
|
esp8266:
|
||||||
|
board: d1_mini
|
||||||
|
restore_from_flash: true # max 96 bytes
|
||||||
|
|
||||||
# Enable logging
|
# Enable logging
|
||||||
logger:
|
logger:
|
||||||
|
|
||||||
|
@ -67,27 +71,48 @@ http_request:
|
||||||
id: http_request_data
|
id: http_request_data
|
||||||
|
|
||||||
globals:
|
globals:
|
||||||
- id: my_token
|
- id: vault_api_token
|
||||||
type: std::string
|
type: std::string
|
||||||
restore_value: no
|
restore_value: no
|
||||||
- id: my_tag
|
- id: rfid_tag
|
||||||
type: std::string
|
type: std::string
|
||||||
restore_value: no
|
restore_value: no
|
||||||
- id: may_switch_output
|
- id: access_allowed
|
||||||
type: int
|
type: bool
|
||||||
restore_value: no
|
restore_value: no
|
||||||
|
initial_value: 'false'
|
||||||
|
- id: access_cache
|
||||||
|
type: unsigned int[24]
|
||||||
|
restore_value: yes
|
||||||
|
initial_value: '{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}'
|
||||||
|
|
||||||
rc522_spi:
|
script:
|
||||||
cs_pin: GPIO15
|
- id: check_access
|
||||||
on_tag:
|
then:
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: |-
|
||||||
|
int rfid_value = decode_token(id(rfid_tag));
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
if (id(access_cache)[i] == rfid_value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
then:
|
||||||
|
- script.execute: toggle_switch
|
||||||
|
- script.wait: toggle_switch
|
||||||
|
- if: # return LED to switch state before
|
||||||
|
condition:
|
||||||
|
switch.is_on: mlock_${name_of_board}_switch
|
||||||
|
then:
|
||||||
|
- light.addressable_set: { id: status_led, red: 0%, green: 100%, blue: 0% }
|
||||||
|
else:
|
||||||
|
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
||||||
|
else:
|
||||||
|
- script.execute: fetch_token_vault
|
||||||
|
- id: fetch_token_vault
|
||||||
then:
|
then:
|
||||||
- light.addressable_set: { id: status_led, red: 100%, green: 60%, blue: 0% }
|
|
||||||
# small delay so the light can update its color
|
|
||||||
- delay: 15ms
|
|
||||||
# store the tag id into global variable
|
|
||||||
- lambda: |-
|
|
||||||
id(my_tag) = x;
|
|
||||||
id(may_switch_output) = 0;
|
|
||||||
# login to vault with role_id to fetch short lived token
|
# login to vault with role_id to fetch short lived token
|
||||||
- http_request.post:
|
- http_request.post:
|
||||||
url: https://vault.ctdo.de/v1/auth/approle/login
|
url: https://vault.ctdo.de/v1/auth/approle/login
|
||||||
|
@ -98,79 +123,118 @@ rc522_spi:
|
||||||
role_id: $vault_role_id
|
role_id: $vault_role_id
|
||||||
secret_id: $vault_secret_id
|
secret_id: $vault_secret_id
|
||||||
on_response:
|
on_response:
|
||||||
# fetch token from response, store into my_token
|
# fetch token from response, store into vault_api_token
|
||||||
then:
|
then:
|
||||||
- lambda: |-
|
- lambda: |-
|
||||||
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
|
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
|
||||||
id(my_token) = (const char*) root["auth"]["client_token"];
|
id(vault_api_token) = (const char*) root["auth"]["client_token"];
|
||||||
});
|
});
|
||||||
# use the token to get json of scanned tag from vault
|
- script.execute: check_access_vault
|
||||||
- http_request.get:
|
- id: check_access_vault
|
||||||
url: !lambda |-
|
then:
|
||||||
return ((std::string) "https://vault.ctdo.de/v1/maschinenlock/" + id(my_tag));
|
- lambda: |-
|
||||||
verify_ssl: false
|
id(access_allowed) = false;
|
||||||
headers:
|
- http_request.get:
|
||||||
X-Vault-Token: !lambda return id(my_token).c_str();
|
url: !lambda |-
|
||||||
on_response:
|
return ((std::string) "https://vault.ctdo.de/v1/maschinenlock/" + id(rfid_tag));
|
||||||
then:
|
verify_ssl: false
|
||||||
- if:
|
headers:
|
||||||
condition:
|
X-Vault-Token: !lambda return id(vault_api_token).c_str();
|
||||||
lambda: 'return status_code == 200;'
|
on_response:
|
||||||
then: # when found, check if machine is allowed, turn on output or blink LED red
|
then:
|
||||||
- lambda: |-
|
- if:
|
||||||
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
|
condition:
|
||||||
id(may_switch_output) = root["data"]["mlock-$name_of_board"];
|
lambda: 'return status_code == 200;'
|
||||||
});
|
then: # when found, check if machine is allowed, turn on output or blink LED red
|
||||||
- if:
|
- lambda: |-
|
||||||
condition:
|
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
|
||||||
lambda: 'return id(may_switch_output);'
|
id(access_allowed) = (root["data"]["mlock-$name_of_board"] == "1");
|
||||||
then:
|
});
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
switch.is_on: mlock_${name_of_board}_switch
|
lambda: 'return id(access_allowed);'
|
||||||
then:
|
then:
|
||||||
- switch.turn_off: mlock_${name_of_board}_switch
|
- script.execute: toggle_switch
|
||||||
- homeassistant.event:
|
- script.execute: cache_token
|
||||||
event: esphome.mlock_locked
|
- script.wait: toggle_switch
|
||||||
data:
|
else:
|
||||||
tag: !lambda return id(my_tag);
|
- repeat:
|
||||||
machine: ${name_of_board}
|
count: 3
|
||||||
else:
|
then:
|
||||||
- switch.turn_on: mlock_${name_of_board}_switch
|
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
||||||
- homeassistant.event:
|
- delay: 0.1s
|
||||||
event: esphome.mlock_unlocked
|
- light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% }
|
||||||
data:
|
- delay: 0.1s
|
||||||
tag: !lambda return id(my_tag);
|
else: # vault returns 404 on missing/unknown Tag so blink LED
|
||||||
machine: ${name_of_board}
|
- repeat:
|
||||||
- text.set:
|
count: 3
|
||||||
id: ${name_of_board}_letzte_entsperrung
|
then:
|
||||||
value: !lambda return id(my_tag);
|
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
||||||
else:
|
- delay: 0.5s
|
||||||
- repeat:
|
- light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% }
|
||||||
count: 3
|
- delay: 0.5s
|
||||||
then:
|
- if: # return LED to switch state before
|
||||||
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
condition:
|
||||||
- delay: 0.1s
|
switch.is_on: mlock_${name_of_board}_switch
|
||||||
- light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% }
|
then:
|
||||||
- delay: 0.1s
|
- light.addressable_set: { id: status_led, red: 0%, green: 100%, blue: 0% }
|
||||||
else: # vault returns 404 on missing/unknown Tag so blink LED
|
else:
|
||||||
- repeat:
|
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
||||||
count: 3
|
- id: toggle_switch
|
||||||
then:
|
then:
|
||||||
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
- if:
|
||||||
- delay: 0.5s
|
condition:
|
||||||
- light.addressable_set: { id: status_led, red: 0%, green: 0%, blue: 0% }
|
switch.is_on: mlock_${name_of_board}_switch
|
||||||
- delay: 0.5s
|
then:
|
||||||
- if: # return LED to switch state before
|
- switch.turn_off: mlock_${name_of_board}_switch
|
||||||
condition:
|
- homeassistant.event:
|
||||||
switch.is_on: mlock_${name_of_board}_switch
|
event: esphome.mlock_locked
|
||||||
then:
|
data:
|
||||||
- light.addressable_set: { id: status_led, red: 0%, green: 100%, blue: 0% }
|
tag: !lambda return id(rfid_tag);
|
||||||
else:
|
machine: ${name_of_board}
|
||||||
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
else:
|
||||||
|
- switch.turn_on: mlock_${name_of_board}_switch
|
||||||
|
- homeassistant.event:
|
||||||
|
event: esphome.mlock_unlocked
|
||||||
|
data:
|
||||||
|
tag: !lambda return id(rfid_tag);
|
||||||
|
machine: ${name_of_board}
|
||||||
|
- text.set:
|
||||||
|
id: ${name_of_board}_letzte_entsperrung
|
||||||
|
value: !lambda return id(rfid_tag);
|
||||||
|
- id: cache_token
|
||||||
|
then:
|
||||||
|
- lambda: |-
|
||||||
|
int rfid_value = decode_token(id(rfid_tag));
|
||||||
|
int rfid_value_pos = 23;
|
||||||
|
// search the token in the list to keep the access_cache unique
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
if (id(access_cache)[i] == rfid_value) {
|
||||||
|
rfid_value_pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// shift the existing entries down
|
||||||
|
for (int i = rfid_value_pos; i >= 1; i--) {
|
||||||
|
id(access_cache)[i] = id(access_cache)[i - 1];
|
||||||
|
}
|
||||||
|
// write the new token to the start
|
||||||
|
id(access_cache)[0] = rfid_value;
|
||||||
|
|
||||||
|
rc522_spi:
|
||||||
|
cs_pin: GPIO15
|
||||||
|
on_tag:
|
||||||
|
then:
|
||||||
|
- light.addressable_set: { id: status_led, red: 100%, green: 60%, blue: 0% }
|
||||||
|
# small delay so the light can update its color
|
||||||
|
- delay: 15ms
|
||||||
|
# store the tag id into global variable
|
||||||
|
- lambda: |-
|
||||||
|
id(rfid_tag) = x;
|
||||||
|
- script.execute: check_access
|
||||||
- text.set:
|
- text.set:
|
||||||
id: ${name_of_board}_letzter_token
|
id: ${name_of_board}_letzter_token
|
||||||
value: !lambda return id(my_tag);
|
value: !lambda return id(rfid_tag);
|
||||||
|
|
||||||
# switch component for the output state
|
# switch component for the output state
|
||||||
switch:
|
switch:
|
||||||
|
@ -208,6 +272,14 @@ button:
|
||||||
on_press:
|
on_press:
|
||||||
- switch.turn_off: mlock_${name_of_board}_switch
|
- switch.turn_off: mlock_${name_of_board}_switch
|
||||||
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
- light.addressable_set: { id: status_led, red: 100%, green: 0%, blue: 0% }
|
||||||
|
- platform: template
|
||||||
|
name: "${name_of_board} Tokencache leeren"
|
||||||
|
id: ${name_of_board}_btn_tokencache_leeren
|
||||||
|
on_press:
|
||||||
|
- lambda: |-
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
id(access_cache)[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
light:
|
light:
|
||||||
- platform: neopixelbus
|
- platform: neopixelbus
|
||||||
|
|
Loading…
Reference in New Issue