docs+tests: architecture diagram, security docs, 75 new edge-case tests
README: - Add ASCII architecture flow diagram showing all layers - Add Security Architecture section (Layer 1: Channel Auth, Layer 2: Rate Limiting, Layer 3: Tool Sandbox) - Update test count to 629 New edge-case tests (75 new): - SecurityPolicy: command injection (semicolon, backtick, dollar-paren, env prefix, newline), path traversal (encoded dots, double-dot in filename, null byte, symlink, tilde-ssh, /var/run), rate limiter boundaries (exactly-at, zero, high), autonomy+command combos, from_config fresh tracker - Discord: exact match not substring, empty user ID, wildcard+specific, case sensitivity, base64 edge cases - Slack: exact match, empty user ID, case sensitivity, wildcard combo - Telegram: exact match, empty string, case sensitivity, wildcard combo - Gateway: first-match-wins, empty value, colon in value, different headers, empty request, newline-only request - Config schema: backward compat (Discord/Slack without allowed_users), TOML roundtrip, webhook secret presence/absence 629 tests passing, 0 clippy warnings
This commit is contained in:
parent
542bb80743
commit
a5887ad2dc
7 changed files with 460 additions and 6 deletions
|
|
@ -227,6 +227,42 @@ mod tests {
|
|||
let req = "POST /webhook HTTP/1.1\r\nX-Webhook-Secret: spaced \r\n\r\n{}";
|
||||
assert_eq!(extract_header(req, "X-Webhook-Secret"), Some("spaced"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_header_first_match_wins() {
|
||||
let req = "POST /webhook HTTP/1.1\r\nX-Webhook-Secret: first\r\nX-Webhook-Secret: second\r\n\r\n{}";
|
||||
assert_eq!(extract_header(req, "X-Webhook-Secret"), Some("first"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_header_empty_value() {
|
||||
let req = "POST /webhook HTTP/1.1\r\nX-Webhook-Secret:\r\n\r\n{}";
|
||||
assert_eq!(extract_header(req, "X-Webhook-Secret"), Some(""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_header_colon_in_value() {
|
||||
let req = "POST /webhook HTTP/1.1\r\nAuthorization: Bearer sk-abc:123\r\n\r\n{}";
|
||||
// split_once on ':' means only the first colon splits key/value
|
||||
assert_eq!(extract_header(req, "Authorization"), Some("Bearer sk-abc:123"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_header_different_header() {
|
||||
let req = "POST /webhook HTTP/1.1\r\nContent-Type: application/json\r\nX-Webhook-Secret: mysecret\r\n\r\n{}";
|
||||
assert_eq!(extract_header(req, "Content-Type"), Some("application/json"));
|
||||
assert_eq!(extract_header(req, "X-Webhook-Secret"), Some("mysecret"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_header_from_empty_request() {
|
||||
assert_eq!(extract_header("", "X-Webhook-Secret"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn extract_header_newline_only_request() {
|
||||
assert_eq!(extract_header("\r\n\r\n", "X-Webhook-Secret"), None);
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_json(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue