mirror of
https://github.com/esphome/esphome.git
synced 2026-09-29 16:00:23 +00:00
[ota] Add allow_plaintext_upload for devices that never migrated to encryption (#19396)
This commit is contained in:
@@ -12,10 +12,11 @@ from esphome import config_validation as cv
|
||||
from esphome.components.esphome.ota import (
|
||||
AUTO_LOAD,
|
||||
FILTER_SOURCE_FILES,
|
||||
_encryption_schema,
|
||||
_validate_no_password_with_encryption,
|
||||
ota_esphome_final_validate,
|
||||
)
|
||||
from esphome.components.noise import static_encryption_key
|
||||
from esphome.components.noise import encryption_schema, static_encryption_key
|
||||
from esphome.const import (
|
||||
CONF_API,
|
||||
CONF_ENCRYPTION,
|
||||
@@ -29,6 +30,7 @@ from esphome.const import (
|
||||
CONF_VERSION,
|
||||
)
|
||||
from esphome.core import CORE, ID
|
||||
from esphome.espota2 import CONF_ALLOW_PLAINTEXT_UPLOAD
|
||||
import esphome.final_validate as fv
|
||||
|
||||
|
||||
@@ -198,6 +200,21 @@ def test_encryption_without_any_key_rejected() -> None:
|
||||
fv.full_config.reset(token)
|
||||
|
||||
|
||||
def test_encryption_schema_allow_plaintext_upload() -> None:
|
||||
"""The opt in is an ota only option with no default, so a merged block
|
||||
that does not mention it cannot clear it; the shared api schema does not
|
||||
know it."""
|
||||
assert _encryption_schema(None) == {}
|
||||
assert _encryption_schema({CONF_ALLOW_PLAINTEXT_UPLOAD: True}) == {
|
||||
CONF_ALLOW_PLAINTEXT_UPLOAD: True
|
||||
}
|
||||
assert _encryption_schema({CONF_KEY: API_KEY}) == {CONF_KEY: API_KEY}
|
||||
with pytest.raises(cv.Invalid):
|
||||
_encryption_schema(False)
|
||||
with pytest.raises(cv.Invalid):
|
||||
encryption_schema({CONF_ALLOW_PLAINTEXT_UPLOAD: True})
|
||||
|
||||
|
||||
def test_encryption_key_mismatch_between_merged_configs_rejected() -> None:
|
||||
"""Same-port configs with different encryption keys raise."""
|
||||
full_conf = {
|
||||
@@ -489,6 +506,13 @@ def test_static_encryption_key() -> None:
|
||||
{"USE_OTA_ENCRYPTION", "USE_OTA_PASSWORD"},
|
||||
{"USE_OTA_ENCRYPTION_REQUIRED", "USE_OTA_ENCRYPTION_PROVISIONED"},
|
||||
),
|
||||
# The migration install keeps the password for the old firmware's
|
||||
# prompt but the build it sends is authenticated by the key alone
|
||||
(
|
||||
"migration_password",
|
||||
{"USE_OTA_ENCRYPTION", "USE_OTA_ENCRYPTION_REQUIRED"},
|
||||
{"USE_OTA_PASSWORD", "USE_OTA_ENCRYPTION_PROVISIONED"},
|
||||
),
|
||||
# The ota encryption block is what makes the device refuse plaintext
|
||||
(
|
||||
"encryption_required",
|
||||
@@ -549,6 +573,16 @@ def test_password_with_encryption_rejected() -> None:
|
||||
_validate_no_password_with_encryption(config)
|
||||
|
||||
|
||||
def test_password_with_migration_install_accepted() -> None:
|
||||
"""The old firmware may still ask for the password on the plaintext
|
||||
leg of the migration install."""
|
||||
config = {
|
||||
CONF_PASSWORD: "pw",
|
||||
CONF_ENCRYPTION: {CONF_KEY: API_KEY, CONF_ALLOW_PLAINTEXT_UPLOAD: True},
|
||||
}
|
||||
assert _validate_no_password_with_encryption(config) is config
|
||||
|
||||
|
||||
def test_password_alone_accepted() -> None:
|
||||
"""A password without encryption still validates."""
|
||||
config = {CONF_PASSWORD: "pw"}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
esphome:
|
||||
name: ota-migration-password
|
||||
|
||||
host:
|
||||
|
||||
api:
|
||||
encryption:
|
||||
key: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="
|
||||
|
||||
ota:
|
||||
- platform: esphome
|
||||
password: "superlongpasswordthatnoonewillknow"
|
||||
encryption:
|
||||
allow_plaintext_upload: true
|
||||
Reference in New Issue
Block a user