mirror of
https://github.com/telemt/telemt.git
synced 2026-04-30 17:04:11 +03:00
Expose tls_domains links as domain-link pairs
Co-Authored-By: brekotis <93345790+brekotis@users.noreply.github.com> Signed-off-by: Alexey <247128645+axkurcom@users.noreply.github.com>
This commit is contained in:
@@ -456,6 +456,13 @@ pub(super) struct UserLinks {
|
|||||||
pub(super) classic: Vec<String>,
|
pub(super) classic: Vec<String>,
|
||||||
pub(super) secure: Vec<String>,
|
pub(super) secure: Vec<String>,
|
||||||
pub(super) tls: Vec<String>,
|
pub(super) tls: Vec<String>,
|
||||||
|
pub(super) tls_domains: Vec<TlsDomainLink>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub(super) struct TlsDomainLink {
|
||||||
|
pub(super) domain: String,
|
||||||
|
pub(super) link: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
|||||||
106
src/api/users.rs
106
src/api/users.rs
@@ -13,7 +13,7 @@ use super::config_store::{
|
|||||||
};
|
};
|
||||||
use super::model::{
|
use super::model::{
|
||||||
ApiFailure, CreateUserRequest, CreateUserResponse, PatchUserRequest, RotateSecretRequest,
|
ApiFailure, CreateUserRequest, CreateUserResponse, PatchUserRequest, RotateSecretRequest,
|
||||||
UserInfo, UserLinks, is_valid_ad_tag, is_valid_user_secret, is_valid_username,
|
TlsDomainLink, UserInfo, UserLinks, is_valid_ad_tag, is_valid_user_secret, is_valid_username,
|
||||||
parse_optional_expiration, parse_patch_expiration, random_user_secret,
|
parse_optional_expiration, parse_patch_expiration, random_user_secret,
|
||||||
};
|
};
|
||||||
use super::patch::Patch;
|
use super::patch::Patch;
|
||||||
@@ -469,6 +469,7 @@ pub(super) async fn users_from_config(
|
|||||||
classic: Vec::new(),
|
classic: Vec::new(),
|
||||||
secure: Vec::new(),
|
secure: Vec::new(),
|
||||||
tls: Vec::new(),
|
tls: Vec::new(),
|
||||||
|
tls_domains: Vec::new(),
|
||||||
});
|
});
|
||||||
users.push(UserInfo {
|
users.push(UserInfo {
|
||||||
in_runtime: runtime_cfg
|
in_runtime: runtime_cfg
|
||||||
@@ -523,10 +524,12 @@ fn build_user_links(
|
|||||||
.public_port
|
.public_port
|
||||||
.unwrap_or(resolve_default_link_port(cfg));
|
.unwrap_or(resolve_default_link_port(cfg));
|
||||||
let tls_domains = resolve_tls_domains(cfg);
|
let tls_domains = resolve_tls_domains(cfg);
|
||||||
|
let extra_tls_domains = resolve_extra_tls_domains(cfg);
|
||||||
|
|
||||||
let mut classic = Vec::new();
|
let mut classic = Vec::new();
|
||||||
let mut secure = Vec::new();
|
let mut secure = Vec::new();
|
||||||
let mut tls = Vec::new();
|
let mut tls = Vec::new();
|
||||||
|
let mut tls_domain_links = Vec::new();
|
||||||
|
|
||||||
for host in &hosts {
|
for host in &hosts {
|
||||||
if cfg.general.modes.classic {
|
if cfg.general.modes.classic {
|
||||||
@@ -549,6 +552,17 @@ fn build_user_links(
|
|||||||
host, port, secret, domain_hex
|
host, port, secret, domain_hex
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
for domain in &extra_tls_domains {
|
||||||
|
let domain_hex = hex::encode(domain);
|
||||||
|
let link = format!(
|
||||||
|
"tg://proxy?server={}&port={}&secret=ee{}{}",
|
||||||
|
host, port, secret, domain_hex
|
||||||
|
);
|
||||||
|
tls_domain_links.push(TlsDomainLink {
|
||||||
|
domain: (*domain).to_string(),
|
||||||
|
link,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,6 +570,7 @@ fn build_user_links(
|
|||||||
classic,
|
classic,
|
||||||
secure,
|
secure,
|
||||||
tls,
|
tls,
|
||||||
|
tls_domains: tls_domain_links,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,6 +687,19 @@ fn resolve_tls_domains(cfg: &ProxyConfig) -> Vec<&str> {
|
|||||||
domains
|
domains
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_extra_tls_domains(cfg: &ProxyConfig) -> Vec<&str> {
|
||||||
|
let mut domains = Vec::with_capacity(cfg.censorship.tls_domains.len());
|
||||||
|
let primary = cfg.censorship.tls_domain.as_str();
|
||||||
|
for domain in &cfg.censorship.tls_domains {
|
||||||
|
let value = domain.as_str();
|
||||||
|
if value.is_empty() || value == primary || domains.contains(&value) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
domains.push(value);
|
||||||
|
}
|
||||||
|
domains
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -761,4 +789,80 @@ mod tests {
|
|||||||
assert!(alice.in_runtime);
|
assert!(alice.in_runtime);
|
||||||
assert!(!bob.in_runtime);
|
assert!(!bob.in_runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn users_from_config_returns_tls_link_for_each_tls_domain() {
|
||||||
|
let mut cfg = ProxyConfig::default();
|
||||||
|
cfg.access.users.insert(
|
||||||
|
"alice".to_string(),
|
||||||
|
"0123456789abcdef0123456789abcdef".to_string(),
|
||||||
|
);
|
||||||
|
cfg.general.modes.classic = false;
|
||||||
|
cfg.general.modes.secure = false;
|
||||||
|
cfg.general.modes.tls = true;
|
||||||
|
cfg.general.links.public_host = Some("proxy.example.net".to_string());
|
||||||
|
cfg.general.links.public_port = Some(443);
|
||||||
|
cfg.censorship.tls_domain = "front-a.example.com".to_string();
|
||||||
|
cfg.censorship.tls_domains = vec![
|
||||||
|
"front-b.example.com".to_string(),
|
||||||
|
"front-c.example.com".to_string(),
|
||||||
|
"front-b.example.com".to_string(),
|
||||||
|
"front-a.example.com".to_string(),
|
||||||
|
];
|
||||||
|
|
||||||
|
let stats = Stats::new();
|
||||||
|
let tracker = UserIpTracker::new();
|
||||||
|
let users = users_from_config(&cfg, &stats, &tracker, None, None, None).await;
|
||||||
|
let alice = users
|
||||||
|
.iter()
|
||||||
|
.find(|entry| entry.username == "alice")
|
||||||
|
.expect("alice must be present");
|
||||||
|
|
||||||
|
assert_eq!(alice.links.tls.len(), 3);
|
||||||
|
assert!(
|
||||||
|
alice
|
||||||
|
.links
|
||||||
|
.tls
|
||||||
|
.iter()
|
||||||
|
.any(|link| link.ends_with(&hex::encode("front-a.example.com")))
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
alice
|
||||||
|
.links
|
||||||
|
.tls
|
||||||
|
.iter()
|
||||||
|
.any(|link| link.ends_with(&hex::encode("front-b.example.com")))
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
alice
|
||||||
|
.links
|
||||||
|
.tls
|
||||||
|
.iter()
|
||||||
|
.any(|link| link.ends_with(&hex::encode("front-c.example.com")))
|
||||||
|
);
|
||||||
|
assert_eq!(alice.links.tls_domains.len(), 2);
|
||||||
|
assert!(
|
||||||
|
alice
|
||||||
|
.links
|
||||||
|
.tls_domains
|
||||||
|
.iter()
|
||||||
|
.any(|entry| entry.domain == "front-b.example.com"
|
||||||
|
&& entry.link.ends_with(&hex::encode("front-b.example.com")))
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
alice
|
||||||
|
.links
|
||||||
|
.tls_domains
|
||||||
|
.iter()
|
||||||
|
.any(|entry| entry.domain == "front-c.example.com"
|
||||||
|
&& entry.link.ends_with(&hex::encode("front-c.example.com")))
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
!alice
|
||||||
|
.links
|
||||||
|
.tls_domains
|
||||||
|
.iter()
|
||||||
|
.any(|entry| entry.domain == "front-a.example.com")
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user