mirror of
https://github.com/telemt/telemt.git
synced 2026-11-03 22:31:59 +03:00
WEB: Base Path: security + reload coverage fixes&tests
This commit is contained in:
@@ -93,12 +93,9 @@ pub(crate) fn print_web_proxy_links(config: &ProxyConfig) {
|
||||
"User: {} ({:?})",
|
||||
profile.user, profile.secret_mode
|
||||
));
|
||||
if let Some(link) = format_web_proxy_link(
|
||||
&profile.host,
|
||||
&vhost.base_path,
|
||||
secret,
|
||||
profile.secret_mode,
|
||||
) {
|
||||
if let Some(link) =
|
||||
format_web_proxy_link(&profile.host, &vhost.base_path, secret, profile.secret_mode)
|
||||
{
|
||||
print_maestro_line(format!("WEB: {link}"));
|
||||
}
|
||||
}
|
||||
@@ -129,9 +126,7 @@ fn format_web_proxy_link(
|
||||
let server = url::form_urlencoded::byte_serialize(format!("{host}/{base_path}").as_bytes())
|
||||
.collect::<String>();
|
||||
let marked = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(marked);
|
||||
Some(format!(
|
||||
"tg://webproxy?server={server}&secret={marked}"
|
||||
))
|
||||
Some(format!("tg://webproxy?server={server}&secret={marked}"))
|
||||
}
|
||||
|
||||
/// Durably replaces one Beobachten snapshot without following Unix symlinks.
|
||||
@@ -451,4 +446,31 @@ mod tests {
|
||||
Some("tg://webproxy?server=proxy.example.com%2Fdobry-cola%2Fsuper_app&secret=cN0AAQIDBAUGBwgJCgsMDQ4P".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_web_proxy_link_round_trips_through_the_tdesktop_grammar() {
|
||||
for (mode, expected_secret) in [
|
||||
(WebSecretMode::Plain, hex::decode(SECRET).unwrap()),
|
||||
(
|
||||
WebSecretMode::Dd,
|
||||
[vec![0xdd], hex::decode(SECRET).unwrap()].concat(),
|
||||
),
|
||||
] {
|
||||
let link = format_web_proxy_link("proxy.example.com", "MixedCase/a_b-9", SECRET, mode)
|
||||
.unwrap();
|
||||
let parsed = url::Url::parse(&link).unwrap();
|
||||
let query = parsed
|
||||
.query_pairs()
|
||||
.collect::<std::collections::BTreeMap<_, _>>();
|
||||
assert_eq!(
|
||||
query["server"].as_ref(),
|
||||
"proxy.example.com/MixedCase/a_b-9"
|
||||
);
|
||||
let marked = base64::engine::general_purpose::URL_SAFE_NO_PAD
|
||||
.decode(query["secret"].as_bytes())
|
||||
.unwrap();
|
||||
assert_eq!(marked.first(), Some(&0x70));
|
||||
assert_eq!(&marked[1..], expected_secret.as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,6 +295,28 @@ fn web_decoy_fasttrack_mode_is_deferred_without_runtime_publication() {
|
||||
assert!(!resolved.runtime_changed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn base_path_change_is_runtime_owned_and_rebuilds_route_identity() {
|
||||
let old = web_config_with_fasttrack("off");
|
||||
let old_runtime = old.web.runtime.as_ref().unwrap();
|
||||
let old_capability = old_runtime.vhosts["proxy.example.com"].capabilities[0];
|
||||
let mut desired = old.clone();
|
||||
desired.web.vhosts[0].base_path = "MixedCase/path".to_string();
|
||||
|
||||
let resolved = resolve_reload_config(&old, &desired).unwrap();
|
||||
|
||||
assert!(resolved.deferred_process_fields.is_empty());
|
||||
assert!(resolved.runtime_changed);
|
||||
assert_eq!(resolved.effective.web.vhosts[0].base_path, "MixedCase/path");
|
||||
let runtime = resolved.effective.web.runtime.as_ref().unwrap();
|
||||
let vhost = &runtime.vhosts["proxy.example.com"];
|
||||
assert_eq!(vhost.base, "/MixedCase/path/");
|
||||
assert_ne!(vhost.capabilities[0], old_capability);
|
||||
assert_eq!(vhost.capabilities[0], vhost.profiles[0].capability);
|
||||
assert_eq!(runtime.capabilities.as_ref(), vhost.capabilities.as_ref());
|
||||
assert!(!runtime.capabilities.contains(&old_capability));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enabling_learning_is_deferred_when_retained_capacity_is_too_small() {
|
||||
let mut old = ProxyConfig::default();
|
||||
|
||||
Reference in New Issue
Block a user