story-kit: enforce cryptographic identity verification for Matrix commands (story 246)

Remove the require_verified_devices config toggle. The bot now always requires
encrypted rooms and cross-signing-verified devices before executing any command.
Messages from unencrypted rooms or unverified devices are rejected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dave
2026-03-14 19:56:38 +00:00
parent 568207687d
commit ec652a6fe8
2 changed files with 65 additions and 85 deletions

View File

@@ -35,12 +35,6 @@ pub struct BotConfig {
/// dropped. Defaults to 20.
#[serde(default = "default_history_size")]
pub history_size: usize,
/// When `true`, the bot rejects messages from users whose devices have not
/// been verified via cross-signing in encrypted rooms. When `false`
/// (default), messages are accepted regardless of device verification
/// status, preserving existing plaintext-room behaviour.
#[serde(default)]
pub require_verified_devices: bool,
/// Previously used to select an Anthropic model. Now ignored — the bot
/// uses Claude Code which manages its own model selection. Kept for
/// backwards compatibility so existing bot.toml files still parse.
@@ -241,47 +235,6 @@ enabled = true
assert_eq!(config.history_size, 20);
}
#[test]
fn load_defaults_require_verified_devices_to_false() {
let tmp = tempfile::tempdir().unwrap();
let sk = tmp.path().join(".story_kit");
fs::create_dir_all(&sk).unwrap();
fs::write(
sk.join("bot.toml"),
r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
room_ids = ["!abc:example.com"]
enabled = true
"#,
)
.unwrap();
let config = BotConfig::load(tmp.path()).unwrap();
assert!(!config.require_verified_devices);
}
#[test]
fn load_respects_require_verified_devices_true() {
let tmp = tempfile::tempdir().unwrap();
let sk = tmp.path().join(".story_kit");
fs::create_dir_all(&sk).unwrap();
fs::write(
sk.join("bot.toml"),
r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
room_ids = ["!abc:example.com"]
enabled = true
require_verified_devices = true
"#,
)
.unwrap();
let config = BotConfig::load(tmp.path()).unwrap();
assert!(config.require_verified_devices);
}
#[test]
fn load_respects_custom_history_size() {
let tmp = tempfile::tempdir().unwrap();
@@ -302,4 +255,32 @@ history_size = 50
let config = BotConfig::load(tmp.path()).unwrap();
assert_eq!(config.history_size, 50);
}
#[test]
fn load_ignores_legacy_require_verified_devices_key() {
// Old bot.toml files that still have `require_verified_devices = true`
// must parse successfully — the field is simply ignored now that
// verification is always enforced unconditionally.
let tmp = tempfile::tempdir().unwrap();
let sk = tmp.path().join(".story_kit");
fs::create_dir_all(&sk).unwrap();
fs::write(
sk.join("bot.toml"),
r#"
homeserver = "https://matrix.example.com"
username = "@bot:example.com"
password = "secret"
room_ids = ["!abc:example.com"]
enabled = true
require_verified_devices = true
"#,
)
.unwrap();
// Should still load successfully despite the unknown field.
let config = BotConfig::load(tmp.path());
assert!(
config.is_some(),
"bot.toml with legacy require_verified_devices key must still load"
);
}
}