This commit is contained in:
naskya 2024-07-01 21:17:20 +09:00
parent ede46dc7a6
commit ee34620d53
Signed by: naskya
GPG key ID: 712D413B3A9FED5C
2 changed files with 199 additions and 121 deletions

View file

@ -469,126 +469,204 @@ fn create_new_server_config(
None => None,
};
let network = server::Network {
protocol: match protocol.as_str() {
"http" => Some(server::HttpProtocol::Http),
_ => None,
},
domain,
port: parsed_server_url.port(),
listen: server::Listen {
host: default_yml
.get("bind")
.and_then(|v| v.as_str())
.map(|v| v.to_string()),
port: default_yml
.get("port")
.and_then(|v| v.as_i64())
.ok_or(Error::InvalidConfig("port"))?
.try_into()
.map_err(|_| Error::InvalidConfig("Invalid `port` number"))?,
},
email,
http_proxy,
media_proxy,
summaly_proxy,
smtp_proxy,
};
let database = server::Database {
host: db
.get(&Yaml::String("host".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("db.host"))?
.to_string(),
port: db
.get(&Yaml::String("port".to_string()))
.and_then(|v| v.as_i64())
.ok_or(Error::InvalidConfig("db.port"))?
.try_into()
.map_err(|_| Error::InvalidConfig("Invalid `db.port` number"))?,
user: db
.get(&Yaml::String("user".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("db.user"))?
.to_string(),
password: db
.get(&Yaml::String("pass".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("db.pass"))?
.to_string(),
name: db
.get(&Yaml::String("db".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("db.db"))?
.to_string(),
};
let cache_server = server::CacheServer {
host: redis
.get(&Yaml::String("host".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("redis.host"))?
.to_string(),
port: redis
.get(&Yaml::String("port".to_string()))
.and_then(|v| v.as_i64())
.ok_or(Error::InvalidConfig("redis.port"))?
.try_into()
.map_err(|_| Error::InvalidConfig("Invalid `redis.port` number"))?,
user: match redis.get(&Yaml::String("user".to_string())) {
Some(user) => Some(
user.as_str()
.ok_or(Error::InvalidConfig("redis.user"))?
.to_string(),
),
None => None,
},
password: match redis.get(&Yaml::String("pass".to_string())) {
Some(pass) => Some(
pass.as_str()
.ok_or(Error::InvalidConfig("redis.pass"))?
.to_string(),
),
None => None,
},
index: match redis.get(&Yaml::String("db".to_string())) {
Some(db) => Some(
db.as_i64()
.ok_or(Error::InvalidConfig("redis.db"))?
.try_into()
.map_err(|_| Error::InvalidConfig("Invalid `redis.db` number"))?,
),
None => None,
},
prefix: match redis.get(&Yaml::String("prefix".to_string())) {
Some(prefix) => Some(
prefix
.as_str()
.ok_or(Error::InvalidConfig("redis.prefix"))?
.to_string(),
),
None => None,
},
};
let server_info = Some(server::ServerInfo {
name: meta.name.to_owned(),
description: meta.description.to_owned(),
maintainer_name: meta.maintainer_name.to_owned(),
contact_info: meta.maintainer_email.to_owned(),
open_registrations: !meta.disable_registration,
repository_url,
default_reaction: Some(meta.default_reaction.to_owned()),
});
let timeline = Some(server::Timeline {
local: !meta.disable_local_timeline,
global: !meta.disable_global_timeline,
recommended: !meta.disable_recommended_timeline,
publish: meta.enable_guest_timeline,
});
if meta.enable_hcaptcha && meta.enable_recaptcha {
return Err(Error::InvalidConfig(
"Both hCaptcha and reCAPTCHA are enabled",
));
}
let captcha = match (meta.enable_hcaptcha, meta.enable_recaptcha) {
(false, false) => None,
(true, true) => {
return Err(Error::InvalidConfig(
"Both hCaptcha and reCAPTCHA are enabled",
))
}
(true, false) => Some(server::Captcha {
enabled: true,
provider: server::CaptchaProvider::HCaptcha,
site_key: meta
.hcaptcha_site_key
.to_owned()
.ok_or(Error::InvalidConfig("hCaptcha site key is not set"))?,
secret_key: meta
.hcaptcha_secret_key
.to_owned()
.ok_or(Error::InvalidConfig("hCaptcha secret key is not set"))?,
}),
(false, true) => Some(server::Captcha {
enabled: true,
provider: server::CaptchaProvider::ReCaptcha,
site_key: meta
.recaptcha_site_key
.to_owned()
.ok_or(Error::InvalidConfig("reCAPTCHA site key is not set"))?,
secret_key: meta
.recaptcha_secret_key
.to_owned()
.ok_or(Error::InvalidConfig("reCAPTCHA secret key is not set"))?,
}),
};
let mut security: Option<server::Security> = None;
if meta.secure_mode
|| meta.private_mode
|| captcha.is_some()
|| meta.enable_active_email_validation
|| meta.enable_ip_logging
{
security = Some(server::Security {
require_authorized_fetch: match meta.secure_mode {
false => None,
true => Some(true),
},
private_mode: match meta.private_mode {
false => None,
true => Some(true),
},
captcha,
enable_strict_email_check: match meta.enable_active_email_validation {
false => None,
true => Some(true),
},
enable_ip_logging: match meta.enable_ip_logging {
false => None,
true => Some(true),
},
});
}
let server_config = server::Config {
config_revision: Revision::V1,
server_info: Some(server::ServerInfo {
name: meta.name.to_owned(),
description: meta.description.to_owned(),
maintainer_name: meta.maintainer_name.to_owned(),
contact_info: meta.maintainer_email.to_owned(),
open_registrations: !meta.disable_registration,
repository_url,
default_reaction: Some(meta.default_reaction.to_owned()),
}),
timeline: Some(server::Timeline {
local: !meta.disable_local_timeline,
global: !meta.disable_global_timeline,
recommended: !meta.disable_recommended_timeline,
publish: meta.enable_guest_timeline,
}),
network: server::Network {
protocol: match protocol.as_str() {
"http" => Some(server::HttpProtocol::Http),
_ => None,
},
domain,
port: parsed_server_url.port(),
listen: server::Listen {
host: default_yml
.get("bind")
.and_then(|v| v.as_str())
.map(|v| v.to_string()),
port: default_yml
.get("port")
.and_then(|v| v.as_i64())
.ok_or(Error::InvalidConfig("port"))?
.try_into()
.map_err(|_| Error::InvalidConfig("Invalid `port` number"))?,
},
email,
http_proxy,
media_proxy,
summaly_proxy,
smtp_proxy,
},
database: server::Database {
host: db
.get(&Yaml::String("host".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("db.host"))?
.to_string(),
port: db
.get(&Yaml::String("port".to_string()))
.and_then(|v| v.as_i64())
.ok_or(Error::InvalidConfig("db.port"))?
.try_into()
.map_err(|_| Error::InvalidConfig("Invalid `db.port` number"))?,
user: db
.get(&Yaml::String("user".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("db.user"))?
.to_string(),
password: db
.get(&Yaml::String("pass".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("db.pass"))?
.to_string(),
name: db
.get(&Yaml::String("db".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("db.db"))?
.to_string(),
},
cache_server: server::CacheServer {
host: redis
.get(&Yaml::String("host".to_string()))
.and_then(|v| v.as_str())
.ok_or(Error::InvalidConfig("redis.host"))?
.to_string(),
port: redis
.get(&Yaml::String("port".to_string()))
.and_then(|v| v.as_i64())
.ok_or(Error::InvalidConfig("redis.port"))?
.try_into()
.map_err(|_| Error::InvalidConfig("Invalid `redis.port` number"))?,
user: match redis.get(&Yaml::String("user".to_string())) {
Some(user) => Some(
user.as_str()
.ok_or(Error::InvalidConfig("redis.user"))?
.to_string(),
),
None => None,
},
password: match redis.get(&Yaml::String("pass".to_string())) {
Some(pass) => Some(
pass.as_str()
.ok_or(Error::InvalidConfig("redis.pass"))?
.to_string(),
),
None => None,
},
index: match redis.get(&Yaml::String("db".to_string())) {
Some(db) => Some(
db.as_i64()
.ok_or(Error::InvalidConfig("redis.db"))?
.try_into()
.map_err(|_| Error::InvalidConfig("Invalid `redis.db` number"))?,
),
None => None,
},
prefix: match redis.get(&Yaml::String("prefix".to_string())) {
Some(prefix) => Some(
prefix
.as_str()
.ok_or(Error::InvalidConfig("redis.prefix"))?
.to_string(),
),
None => None,
},
},
server_info,
timeline,
network,
database,
cache_server,
id,
service_worker,
security: todo!(),
security,
file,
};

View file

@ -164,21 +164,21 @@ pub struct Security {
pub require_authorized_fetch: Option<bool>,
pub private_mode: Option<bool>,
#[validate(nested)]
pub captcha: Option<CaptchaConfig>,
pub captcha: Option<Captcha>,
pub enable_strict_email_check: Option<bool>,
pub log_ip_address: Option<bool>,
pub enable_ip_logging: Option<bool>,
}
#[derive(Deserialize, Serialize, Validate, Debug, Clone)]
pub struct CaptchaConfig {
pub struct Captcha {
pub enabled: bool,
pub kind: Captcha,
pub provider: CaptchaProvider,
pub site_key: String,
pub secret_key: String,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub enum Captcha {
pub enum CaptchaProvider {
#[serde(rename = "hCaptcha")]
HCaptcha,
#[serde(rename = "reCAPTCHA")]