fix: drop Secure Config Only permissions from protocol 2

The socket has two modes, None and Secured (ADR 0006), and ignores the
ConfigOnly bit, so the security section no longer reads or saves it.
The HTTP routes keep it until step 4 removes the mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-25 11:11:19 +01:00
parent 096eef0581
commit 72e99d14c5
5 changed files with 8 additions and 4 deletions

View file

@ -135,7 +135,7 @@ The settings are in five sections. `getSettings` and `saveSettings` name one in
| `general` | `hostname`, `ssdpBroadcast`, `ntpServer`, `posixZone` | `/modulesettings`, `/setgeneral` | | `general` | `hostname`, `ssdpBroadcast`, `ntpServer`, `posixZone` | `/modulesettings`, `/setgeneral` |
| `network` | `connMode`; WiFi: `ssid`, `passphrase`, `roaming`, `hidden`; Ethernet: `boardType`, `phyType`, `CLKMode`, `phyAddress`, `PWRPin`, `MDCPin`, `MDIOPin`; the address: `dhcp`, `ip`, `gateway`, `subnet`, `dns1`, `dns2` | `/networksettings`, `/setNetwork`, `/setIP`, `/connectwifi` | | `network` | `connMode`; WiFi: `ssid`, `passphrase`, `roaming`, `hidden`; Ethernet: `boardType`, `phyType`, `CLKMode`, `phyAddress`, `PWRPin`, `MDCPin`, `MDIOPin`; the address: `dhcp`, `ip`, `gateway`, `subnet`, `dns1`, `dns2` | `/networksettings`, `/setNetwork`, `/setIP`, `/connectwifi` |
| `mqtt` | `enabled`, `pubDisco`, `protocol`, `hostname` (the broker's), `port`, `username`, `password`, `rootTopic`, `discoTopic` | `/mqttsettings`, `/connectmqtt` | | `mqtt` | `enabled`, `pubDisco`, `protocol`, `hostname` (the broker's), `port`, `username`, `password`, `rootTopic`, `discoTopic` | `/mqttsettings`, `/connectmqtt` |
| `security` | `securityType`, `username`, `password`, `pin`, `permissions` | `/getSecurity`, `/saveSecurity` | | `security` | `securityType`, `username`, `password`, `pin` | `/getSecurity`, `/saveSecurity` |
| `radio` | `bitLength`, `proto`, `enabled`, `TXPin`, `RXPin`, `SCKPin`, `MOSIPin`, `MISOPin`, `CSNPin`, `frequency`, `rxBandwidth`, `deviation`, `txPower`, `noiseDetection` | `/getRadio`, `/saveRadio` | | `radio` | `bitLength`, `proto`, `enabled`, `TXPin`, `RXPin`, `SCKPin`, `MOSIPin`, `MISOPin`, `CSNPin`, `frequency`, `rxBandwidth`, `deviation`, `txPower`, `noiseDetection` | `/getRadio`, `/saveRadio` |
- **Reading.** `getSettings` replies with the section's fields. A secret is never sent: `hasPassphrase`, `hasPassword` and `hasPin` say whether one is set. `network` also has `hasEthernet`, and has the Ethernet fields only on a device with Ethernet. `radio` also has `radioInit`. - **Reading.** `getSettings` replies with the section's fields. A secret is never sent: `hasPassphrase`, `hasPassword` and `hasPin` say whether one is set. `network` also has `hasEthernet`, and has the Ethernet fields only on a device with Ethernet. `radio` also has `radioInit`.

View file

@ -91,7 +91,8 @@ static void writeSettings(ProtoWriter &w, settings_section_t section) {
w.add(proto_field_t::username, settings.Security.username); w.add(proto_field_t::username, settings.Security.username);
w.add(proto_field_t::hasPassword, hasSecret(settings.Security.password)); w.add(proto_field_t::hasPassword, hasSecret(settings.Security.password));
w.add(proto_field_t::hasPin, hasSecret(settings.Security.pin)); w.add(proto_field_t::hasPin, hasSecret(settings.Security.pin));
w.add(proto_field_t::permissions, settings.Security.permissions); // Not "Secure Config Only"'s permissions: the socket has two modes, None
// and Secured (docs/adr/0006-two-security-modes-eleven-http-routes.md).
break; break;
case settings_section_t::radio: { case settings_section_t::radio: {
const transceiver_config_t &cfg = somfy.transceiver.config; const transceiver_config_t &cfg = somfy.transceiver.config;

View file

@ -238,7 +238,6 @@
FIELD(securityType, "sy", 'i', 0) \ FIELD(securityType, "sy", 'i', 0) \
FIELD(pin, "pn", 's', 0) \ FIELD(pin, "pn", 's', 0) \
FIELD(hasPin, "hi", 'b', 0) \ FIELD(hasPin, "hi", 'b', 0) \
FIELD(permissions, "pm", 'i', 0) \
/* the radio: bitLength, proto, frequency and enabled as above */ \ /* the radio: bitLength, proto, frequency and enabled as above */ \
FIELD(TXPin, "tx", 'i', 0) \ FIELD(TXPin, "tx", 'i', 0) \
FIELD(RXPin, "rx", 'i', 0) \ FIELD(RXPin, "rx", 'i', 0) \

View file

@ -70,7 +70,6 @@ static const settings_field_t FIELDS[] = {
{settings_part_t::security, proto_field_t::username, nullptr, 0, 32}, {settings_part_t::security, proto_field_t::username, nullptr, 0, 32},
{settings_part_t::security, proto_field_t::password, nullptr, 0, 32}, {settings_part_t::security, proto_field_t::password, nullptr, 0, 32},
{settings_part_t::security, proto_field_t::pin, nullptr, 0, 4}, {settings_part_t::security, proto_field_t::pin, nullptr, 0, 4},
{settings_part_t::security, proto_field_t::permissions, nullptr, 0, 1},
// 56 or 80, checked on its own. // 56 or 80, checked on its own.
{settings_part_t::radio, proto_field_t::bitLength, "type", 56, 80}, {settings_part_t::radio, proto_field_t::bitLength, "type", 56, 80},
// RTS, RTW, RTV, GP Relay or GP Remote (radio_proto), checked on its own. // RTS, RTW, RTV, GP Relay or GP Remote (radio_proto), checked on its own.

View file

@ -161,6 +161,10 @@ static void test_a_field_of_another_section_is_refused() {
TEST_ASSERT_EQUAL_STRING("TXPin can't be saved in mqtt", expand(R"({"se":"mqtt","tx":12})")); TEST_ASSERT_EQUAL_STRING("TXPin can't be saved in mqtt", expand(R"({"se":"mqtt","tx":12})"));
TEST_ASSERT_EQUAL_STRING("shadeId can't be saved in radio", expand(R"({"se":"radio","s":1})")); TEST_ASSERT_EQUAL_STRING("shadeId can't be saved in radio", expand(R"({"se":"radio","s":1})"));
} }
static void test_secure_config_only_is_not_a_field() {
// Two modes, None and Secured (ADR 0006): "Secure Config Only" has no key.
TEST_ASSERT_EQUAL_STRING("Unknown field pm", expand(R"({"se":"security","pm":1})"));
}
static void test_ethernet_needs_a_chip_with_it() { static void test_ethernet_needs_a_chip_with_it() {
TEST_ASSERT_GOOD(expand(R"({"se":"network","bo":1})")); TEST_ASSERT_GOOD(expand(R"({"se":"network","bo":1})"));
TEST_ASSERT_EQUAL_STRING("This device has no Ethernet", expand(R"({"se":"network","bo":1})", false)); TEST_ASSERT_EQUAL_STRING("This device has no Ethernet", expand(R"({"se":"network","bo":1})", false));
@ -211,6 +215,7 @@ int main(int argc, char **argv) {
RUN_TEST(test_an_unknown_key_is_refused); RUN_TEST(test_an_unknown_key_is_refused);
RUN_TEST(test_what_is_only_sent_is_refused); RUN_TEST(test_what_is_only_sent_is_refused);
RUN_TEST(test_a_field_of_another_section_is_refused); RUN_TEST(test_a_field_of_another_section_is_refused);
RUN_TEST(test_secure_config_only_is_not_a_field);
RUN_TEST(test_ethernet_needs_a_chip_with_it); RUN_TEST(test_ethernet_needs_a_chip_with_it);
RUN_TEST(test_a_save_sets_the_parts_it_has_fields_of); RUN_TEST(test_a_save_sets_the_parts_it_has_fields_of);
RUN_TEST(test_a_route_name_belongs_to_its_section); RUN_TEST(test_a_route_name_belongs_to_its_section);