mirror of
https://github.com/thegeneralist01/archivr
synced 2026-07-22 03:05:32 +02:00
feat(server): configurable bind address with loopback default and non-loopback warning
- Add optional `bind` field to ServerRegistry (TOML + ARCHIVR_BIND env var) - Default bind address remains 127.0.0.1:8080; non-loopback prints a warning - Add route security classification comment block (READ/ADMIN/WRITE/STATIC) - Add Security and Deployment section to docs/README.md - Replace vague auth note in ARCHIVR-MENTAL-MODEL.md with concrete model description - Add three registry tests covering bind field round-trip and defaults
This commit is contained in:
parent
10c41ef84f
commit
2d7a4f1766
5 changed files with 118 additions and 4 deletions
|
|
@ -14,7 +14,12 @@ pub struct MountedArchive {
|
|||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
|
||||
pub struct ServerRegistry {
|
||||
#[serde(default)]
|
||||
pub archives: Vec<MountedArchive>,
|
||||
/// Optional bind address for the server. Defaults to `127.0.0.1:8080`.
|
||||
/// Set this to `0.0.0.0:8080` only on trusted networks — the server has no authentication.
|
||||
#[serde(default)]
|
||||
pub bind: Option<String>,
|
||||
}
|
||||
|
||||
pub fn load_registry(path: &Path) -> Result<ServerRegistry> {
|
||||
|
|
@ -78,6 +83,7 @@ mod tests {
|
|||
label: "Personal".to_string(),
|
||||
archive_path: archive_path.clone(),
|
||||
}],
|
||||
bind: None,
|
||||
};
|
||||
let path = temp.path().join("server.toml");
|
||||
save_registry(&path, ®istry).unwrap();
|
||||
|
|
@ -102,10 +108,36 @@ mod tests {
|
|||
archive_path: PathBuf::from("/tmp/b/.archivr"),
|
||||
},
|
||||
],
|
||||
bind: None,
|
||||
};
|
||||
|
||||
let err = validate_registry(®istry).unwrap_err().to_string();
|
||||
|
||||
assert!(err.contains("duplicate archive id"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn registry_bind_field_round_trips() {
|
||||
let toml = r#"bind = "127.0.0.1:9090""#;
|
||||
let registry: ServerRegistry = toml::from_str(toml).unwrap();
|
||||
assert_eq!(registry.bind.as_deref(), Some("127.0.0.1:9090"));
|
||||
assert!(registry.archives.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn registry_bind_field_defaults_to_none_when_absent() {
|
||||
let toml = r#""#;
|
||||
let registry: ServerRegistry = toml::from_str(toml).unwrap();
|
||||
assert!(registry.bind.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn registry_bind_field_does_not_affect_archive_validation() {
|
||||
let registry = ServerRegistry {
|
||||
archives: vec![],
|
||||
bind: Some("0.0.0.0:8080".to_string()),
|
||||
};
|
||||
// validate_registry does not reject non-loopback bind — that's main's concern.
|
||||
assert!(validate_registry(®istry).is_ok());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue