env vars handling code: slight cleanup
This commit is contained in:
parent
5614796e71
commit
812eee1a5f
4 changed files with 49 additions and 54 deletions
39
README.md
39
README.md
|
@ -14,34 +14,33 @@
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Forgery reads the following environment variables:
|
Forgery reads the following environment variables:
|
||||||
- `FORGE_URL`: url of the forgejo instance (e.g. https://git.deuxfleurs.fr)
|
- `FORGE_URL` (**mandatory**): url of the forgejo instance (e.g.
|
||||||
- `FORGE_API_TOKEN`: Forgejo API token *granting admin access*. Required. You
|
https://git.deuxfleurs.fr)
|
||||||
can generate an API token using the Forgejo web interface in `Settings ->
|
- `FORGE_API_TOKEN` (**mandatory**): Forgejo API token *granting admin access*.
|
||||||
|
You can generate an API token using the Forgejo web interface in `Settings ->
|
||||||
Applications -> Generate New Token`.
|
Applications -> Generate New Token`.
|
||||||
- `ORG_NAME`: organization name (used in the notification email sent when
|
- `ACTUALLY_BAN_USERS` (default: `false`): define it to `true` to actually lock
|
||||||
locking accounts)
|
user accounts, send notification emails and eventually delete user accounts.
|
||||||
- `ADMIN_CONTACT_EMAIL`: email that can be used to contact admins of your
|
Otherwise, no actual action is taken: spammers are only listed in the
|
||||||
instance (included in the notification email sent when locking accounts)
|
database. The variable should be set in production, but probably not for
|
||||||
- `ACTUALLY_BAN_USERS`: define it to `true` to actually lock user accounts, send
|
testing.
|
||||||
notification emails and eventually delete user accounts. If not defined (the
|
- `STORAGE_BACKEND` (default: `local`): either `local` or `s3`. Chose `local` to
|
||||||
default) or set to `false`, no actual action is taken: spammers are only
|
store the application state to local files, or `s3` to store them in
|
||||||
listed in the database. The variable should be set in production, but probably
|
S3-compatible storage (see below for corresponding configuration variables).
|
||||||
not for testing.
|
- `BIND_ADDR` (default: `127.0.0.1:8080`): address on which the webserver listens
|
||||||
- `STORAGE_BACKEND`: either `local` (default) or `s3`. Chose `local` to store
|
|
||||||
the application state to local files, or `s3` to store them in S3-compatible
|
|
||||||
storage (see below for corresponding configuration variables).
|
|
||||||
- `LISTEN_ADDR`: address on which the webserver listens (default: `0.0.0.0`)
|
|
||||||
- `LISTEN_PORT`: port on which the webserver listens (default: `8080`)
|
|
||||||
|
|
||||||
Environment variables read when `ACTUALLY_BAN_USERS=true`:
|
Environment variables read when `ACTUALLY_BAN_USERS=true`:
|
||||||
- `SMTP_ADDRESS`: address of the SMTP relay used to send email notifications
|
- `SMTP_ADDRESS`: address of the SMTP relay used to send email notifications
|
||||||
- `SMTP_USERNAME`: SMTP username
|
- `SMTP_USERNAME`: SMTP username
|
||||||
- `SMTP_PASSWORD`: SMTP password
|
- `SMTP_PASSWORD`: SMTP password
|
||||||
|
- `ADMIN_CONTACT_EMAIL`: email that can be used to contact admins of your
|
||||||
|
instance (included in the notification email sent when locking accounts)
|
||||||
|
- `ORG_NAME`: organization name (used in the notification email sent when
|
||||||
|
locking accounts)
|
||||||
|
|
||||||
Environment variables read when `STORAGE_BACKEND=local`:
|
Environment variables read when `STORAGE_BACKEND=local`:
|
||||||
- `STORAGE_LOCAL_DIR`: path to a local directory where to store the application
|
- `STORAGE_LOCAL_DIR` (default: `.`): path to a local directory where to store
|
||||||
data (as two files `db.json` and `model.json`). Defaults to `.` if not
|
the application data (as two files `db.json` and `model.json`).
|
||||||
defined.
|
|
||||||
|
|
||||||
Environment variables read when `STORAGE_BACKEND=s3`:
|
Environment variables read when `STORAGE_BACKEND=s3`:
|
||||||
- `STORAGE_S3_BUCKET`: name of the bucket where to store the application data
|
- `STORAGE_S3_BUCKET`: name of the bucket where to store the application data
|
||||||
|
|
|
@ -39,13 +39,13 @@ impl SmtpConfig {
|
||||||
pub async fn send_locked_account_notice(
|
pub async fn send_locked_account_notice(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
smtp: &SmtpConfig,
|
smtp: &SmtpConfig,
|
||||||
|
admin_contact_email: &str,
|
||||||
|
org_name: &str,
|
||||||
login: &str,
|
login: &str,
|
||||||
email: &str,
|
email: &str,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let grace_period_days = crate::GRACE_PERIOD.as_secs() / (24 * 3600);
|
let grace_period_days = crate::GRACE_PERIOD.as_secs() / (24 * 3600);
|
||||||
let org_name = &config.org_name;
|
|
||||||
let forge_url = &config.forge_url;
|
let forge_url = &config.forge_url;
|
||||||
let admin_contact_email = &config.admin_contact_email;
|
|
||||||
|
|
||||||
let email = Message::builder()
|
let email = Message::builder()
|
||||||
.from(smtp.username.parse().unwrap())
|
.from(smtp.username.parse().unwrap())
|
||||||
|
|
44
src/main.rs
44
src/main.rs
|
@ -56,23 +56,20 @@ const GUESS_LEGIT_THRESHOLD: f32 = 0.3;
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub forge_url: Url,
|
pub forge_url: Url,
|
||||||
pub forge_api_token: String,
|
pub forge_api_token: String,
|
||||||
pub org_name: String,
|
|
||||||
pub admin_contact_email: String,
|
|
||||||
pub actually_ban: ActuallyBan,
|
pub actually_ban: ActuallyBan,
|
||||||
pub listen_addr: String,
|
pub bind_addr: String,
|
||||||
pub listen_port: u16,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
async fn from_env() -> anyhow::Result<Self> {
|
async fn from_env() -> anyhow::Result<Self> {
|
||||||
let forge_url_s = env_var("FORGE_URL")?;
|
let forge_url_s = env_var("FORGE_URL")?;
|
||||||
let forge_api_token = env_var("FORGE_API_TOKEN")?;
|
let forge_api_token = env_var("FORGE_API_TOKEN")?;
|
||||||
let org_name = env_var("ORG_NAME")?;
|
|
||||||
let admin_contact_email = env_var("ADMIN_CONTACT_EMAIL")?;
|
|
||||||
|
|
||||||
let actually_ban = match env_var("ACTUALLY_BAN_USERS").as_deref() {
|
let actually_ban = match env_var("ACTUALLY_BAN_USERS").as_deref() {
|
||||||
Ok("true") => ActuallyBan::Yes {
|
Ok("true") => ActuallyBan::Yes {
|
||||||
smtp: SmtpConfig::from_env().await?,
|
smtp: SmtpConfig::from_env().await?,
|
||||||
|
admin_contact_email: env_var("ADMIN_CONTACT_EMAIL")?,
|
||||||
|
org_name: env_var("ORG_NAME")?,
|
||||||
},
|
},
|
||||||
Ok("false") => ActuallyBan::No,
|
Ok("false") => ActuallyBan::No,
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
@ -83,21 +80,13 @@ impl Config {
|
||||||
Err(_) => ActuallyBan::No,
|
Err(_) => ActuallyBan::No,
|
||||||
};
|
};
|
||||||
|
|
||||||
let listen_addr = env_var("LISTEN_ADDR").unwrap_or(String::from("0.0.0.0"));
|
let bind_addr = env_var("BIND_ADDR").unwrap_or(String::from("127.0.0.1:8080"));
|
||||||
let listen_port: u16 = match env_var("LISTEN_PORT").map(|s| u16::from_str_radix(&s, 10)) {
|
|
||||||
Ok(Err(e)) => return Err(anyhow!("LISTEN_PORT: invalid value ({})", e)),
|
|
||||||
Ok(Ok(p)) => p,
|
|
||||||
Err(_) => 8080,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Config {
|
Ok(Config {
|
||||||
forge_url: Url::parse(&forge_url_s).context("parsing FORGE_URL")?,
|
forge_url: Url::parse(&forge_url_s).context("parsing FORGE_URL")?,
|
||||||
forge_api_token,
|
forge_api_token,
|
||||||
org_name,
|
|
||||||
admin_contact_email,
|
|
||||||
actually_ban,
|
actually_ban,
|
||||||
listen_addr,
|
bind_addr,
|
||||||
listen_port,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +94,11 @@ impl Config {
|
||||||
// Whether we are actually banning users or are instead in "testing" mode where
|
// Whether we are actually banning users or are instead in "testing" mode where
|
||||||
// we don't do anything. (Defaults to "No".)
|
// we don't do anything. (Defaults to "No".)
|
||||||
pub enum ActuallyBan {
|
pub enum ActuallyBan {
|
||||||
Yes { smtp: SmtpConfig },
|
Yes {
|
||||||
|
smtp: SmtpConfig,
|
||||||
|
admin_contact_email: String,
|
||||||
|
org_name: String,
|
||||||
|
},
|
||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,15 +489,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
.spawn(async move { workers::lock_and_notify_users(config, storage, forge, db).await })
|
.spawn(async move { workers::lock_and_notify_users(config, storage, forge, db).await })
|
||||||
};
|
};
|
||||||
|
|
||||||
println!(
|
println!("Listening on http://{}", &config.bind_addr);
|
||||||
"Listening on http://{}:{}",
|
|
||||||
(if config.listen_addr == "0.0.0.0" {
|
|
||||||
"127.0.0.1"
|
|
||||||
} else {
|
|
||||||
&config.listen_addr
|
|
||||||
}),
|
|
||||||
config.listen_port
|
|
||||||
);
|
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(get_index).post(post_classified_index))
|
.route("/", get(get_index).post(post_classified_index))
|
||||||
|
@ -516,10 +501,9 @@ async fn main() -> anyhow::Result<()> {
|
||||||
.with_state(shared_state);
|
.with_state(shared_state);
|
||||||
|
|
||||||
let webserver = {
|
let webserver = {
|
||||||
let listener =
|
let listener = tokio::net::TcpListener::bind(&config.bind_addr)
|
||||||
tokio::net::TcpListener::bind((config.listen_addr.clone(), config.listen_port))
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
axum::serve(listener, app)
|
axum::serve(listener, app)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -237,9 +237,21 @@ pub async fn try_lock_and_notify_user(
|
||||||
|
|
||||||
if !notified {
|
if !notified {
|
||||||
match &config.actually_ban {
|
match &config.actually_ban {
|
||||||
ActuallyBan::Yes { smtp } => {
|
ActuallyBan::Yes {
|
||||||
|
smtp,
|
||||||
|
admin_contact_email,
|
||||||
|
org_name,
|
||||||
|
} => {
|
||||||
eprintln!("Sending notification email to user {login}");
|
eprintln!("Sending notification email to user {login}");
|
||||||
email::send_locked_account_notice(config, smtp, &login, &email).await?;
|
email::send_locked_account_notice(
|
||||||
|
config,
|
||||||
|
smtp,
|
||||||
|
&admin_contact_email,
|
||||||
|
&org_name,
|
||||||
|
&login,
|
||||||
|
&email,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
eprintln!("Success");
|
eprintln!("Success");
|
||||||
}
|
}
|
||||||
ActuallyBan::No => {
|
ActuallyBan::No => {
|
||||||
|
|
Loading…
Reference in a new issue