Spiegel von
https://github.com/dani-garcia/vaultwarden.git
synchronisiert 2024-11-05 02:28:00 +01:00
add configuration support for multiple domains
Dieser Commit ist enthalten in:
Ursprung
79ce5b49bc
Commit
80d3c61cc2
1 geänderte Dateien mit 81 neuen und 11 gelöschten Zeilen
|
@ -1,6 +1,7 @@
|
|||
use std::env::consts::EXE_SUFFIX;
|
||||
use std::{env::consts::EXE_SUFFIX, collections::HashMap};
|
||||
use std::process::exit;
|
||||
use std::sync::RwLock;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use job_scheduler_ng::Schedule;
|
||||
use once_cell::sync::Lazy;
|
||||
|
@ -47,6 +48,10 @@ macro_rules! make_config {
|
|||
_usr: ConfigBuilder,
|
||||
|
||||
_overrides: Vec<String>,
|
||||
|
||||
domain_hostmap: OnceLock<HostHashMap>,
|
||||
domain_origins: OnceLock<HostHashMap>,
|
||||
domain_paths: OnceLock<HostHashMap>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Deserialize, Serialize)]
|
||||
|
@ -135,13 +140,20 @@ macro_rules! make_config {
|
|||
|
||||
fn build(&self) -> ConfigItems {
|
||||
let mut config = ConfigItems::default();
|
||||
let _domain_set = self.domain.is_some();
|
||||
let _domain_set = self.domain_change_back.is_some();
|
||||
$($(
|
||||
config.$name = make_config!{ @build self.$name.clone(), &config, $none_action, $($default)? };
|
||||
)+)+
|
||||
config.domain_set = _domain_set;
|
||||
|
||||
config.domain = config.domain.trim_end_matches('/').to_string();
|
||||
config.domain_change_back = config.domain_change_back.split(',').map(|d| d.trim_end_matches('/')).fold(String::new(), |acc, d| {
|
||||
acc.push_str(d);
|
||||
acc.push(',');
|
||||
acc
|
||||
});
|
||||
|
||||
// Remove trailing comma
|
||||
config.domain_change_back.pop();
|
||||
|
||||
config.signups_domains_whitelist = config.signups_domains_whitelist.trim().to_lowercase();
|
||||
config.org_creation_users = config.org_creation_users.trim().to_lowercase();
|
||||
|
@ -335,6 +347,8 @@ macro_rules! make_config {
|
|||
|
||||
}
|
||||
|
||||
type HostHashMap = HashMap<String, String>;
|
||||
|
||||
//STRUCTURE:
|
||||
// /// Short description (without this they won't appear on the list)
|
||||
// group {
|
||||
|
@ -414,15 +428,15 @@ make_config! {
|
|||
|
||||
/// General settings
|
||||
settings {
|
||||
/// Domain URL |> This needs to be set to the URL used to access the server, including 'http[s]://'
|
||||
/// and port, if it's different than the default. Some server functions don't work correctly without this value
|
||||
domain: String, true, def, "http://localhost".to_string();
|
||||
/// Comma seperated list of Domain URLs |> This needs to be set to the URL used to access the server, including
|
||||
/// 'http[s]://' and port, if it's different than the default. Some server functions don't work correctly without this value
|
||||
// TODO: Change back, this is only done to break existing references
|
||||
domain_change_back: String, true, def, "http://localhost".to_string();
|
||||
/// Domain Set |> Indicates if the domain is set by the admin. Otherwise the default will be used.
|
||||
domain_set: bool, false, def, false;
|
||||
/// Domain origin |> Domain URL origin (in https://example.com:8443/path, https://example.com:8443 is the origin)
|
||||
domain_origin: String, false, auto, |c| extract_url_origin(&c.domain);
|
||||
/// Domain path |> Domain URL path (in https://example.com:8443/path, /path is the path)
|
||||
domain_path: String, false, auto, |c| extract_url_path(&c.domain);
|
||||
/// MUST be the same for all domains.
|
||||
domain_path: String, false, auto, |c| extract_url_path(&c.domain_change_back.split(',').nth(0).expect("Missing domain"));
|
||||
/// Enable web vault
|
||||
web_vault_enabled: bool, false, def, true;
|
||||
|
||||
|
@ -667,7 +681,7 @@ make_config! {
|
|||
/// Embed images as email attachments.
|
||||
smtp_embed_images: bool, true, def, true;
|
||||
/// _smtp_img_src
|
||||
_smtp_img_src: String, false, gen, |c| generate_smtp_img_src(c.smtp_embed_images, &c.domain);
|
||||
_smtp_img_src: String, false, gen, |c| generate_smtp_img_src(c.smtp_embed_images, &c.domain_change_back);
|
||||
/// Enable SMTP debugging (Know the risks!) |> DANGEROUS: Enabling this will output very detailed SMTP messages. This could contain sensitive information like passwords and usernames! Only enable this during troubleshooting!
|
||||
smtp_debug: bool, false, def, false;
|
||||
/// Accept Invalid Certs (Know the risks!) |> DANGEROUS: Allow invalid certificates. This option introduces significant vulnerabilities to man-in-the-middle attacks!
|
||||
|
@ -1010,10 +1024,33 @@ fn extract_url_path(url: &str) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn generate_smtp_img_src(embed_images: bool, domain: &str) -> String {
|
||||
/// Extracts host part from a URL.
|
||||
pub fn extract_url_host(url: &str) -> String {
|
||||
match Url::parse(url) {
|
||||
Ok(u) => {
|
||||
let Some(mut host) = u.host_str().map(|s| s.to_string()) else {
|
||||
println!("Domain does not contain host!");
|
||||
return String::new();
|
||||
};
|
||||
|
||||
if let Some(port) = u.port().map(|p| p.to_string()) {
|
||||
host.push_str(&port);
|
||||
}
|
||||
|
||||
host
|
||||
}
|
||||
Err(_) => {
|
||||
// we already print it in the method above, no need to do it again
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_smtp_img_src(embed_images: bool, domains: &str) -> String {
|
||||
if embed_images {
|
||||
"cid:".to_string()
|
||||
} else {
|
||||
let domain = domains.split(',').nth(0).expect("Domain missing");
|
||||
format!("{domain}/vw_static/")
|
||||
}
|
||||
}
|
||||
|
@ -1082,6 +1119,9 @@ impl Config {
|
|||
_env,
|
||||
_usr,
|
||||
_overrides,
|
||||
domain_origins: OnceLock::new(),
|
||||
domain_paths: OnceLock::new(),
|
||||
domain_hostmap: OnceLock::new(),
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
@ -1249,6 +1289,36 @@ impl Config {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn domain_origin(&self, host: &str) -> Option<String> {
|
||||
// This is done to prevent deadlock, when read-locking an rwlock twice
|
||||
let domains = self.domain_change_back();
|
||||
|
||||
self.inner.read().unwrap().domain_origins.get_or_init(|| {
|
||||
domains.split(',')
|
||||
.map(|d| {
|
||||
(extract_url_host(d), extract_url_origin(d))
|
||||
})
|
||||
.collect()
|
||||
}).get(host).map(|h| h.clone())
|
||||
}
|
||||
|
||||
pub fn host_to_domain(&self, host: &str) -> Option<String> {
|
||||
// This is done to prevent deadlock, when read-locking an rwlock twice
|
||||
let domains = self.domain_change_back();
|
||||
|
||||
self.inner.read().unwrap().domain_hostmap.get_or_init(|| {
|
||||
domains.split(',')
|
||||
.map(|d| {
|
||||
(extract_url_host(d), extract_url_path(d))
|
||||
})
|
||||
.collect()
|
||||
}).get(host).map(|h| h.clone())
|
||||
}
|
||||
|
||||
pub fn main_domain(&self) -> String {
|
||||
self.domain_change_back().split(',').nth(0).expect("Missing domain").to_string()
|
||||
}
|
||||
}
|
||||
|
||||
use handlebars::{
|
||||
|
|
Laden …
In neuem Issue referenzieren