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
|
||||
|
||||
Forgery reads the following environment variables:
|
||||
- `FORGE_URL`: url of the forgejo instance (e.g. https://git.deuxfleurs.fr)
|
||||
- `FORGE_API_TOKEN`: Forgejo API token *granting admin access*. Required. You
|
||||
can generate an API token using the Forgejo web interface in `Settings ->
|
||||
- `FORGE_URL` (**mandatory**): url of the forgejo instance (e.g.
|
||||
https://git.deuxfleurs.fr)
|
||||
- `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`.
|
||||
- `ORG_NAME`: organization name (used in the notification email sent when
|
||||
locking accounts)
|
||||
- `ADMIN_CONTACT_EMAIL`: email that can be used to contact admins of your
|
||||
instance (included in the notification email sent when locking accounts)
|
||||
- `ACTUALLY_BAN_USERS`: define it to `true` to actually lock user accounts, send
|
||||
notification emails and eventually delete user accounts. If not defined (the
|
||||
default) or set to `false`, no actual action is taken: spammers are only
|
||||
listed in the database. The variable should be set in production, but probably
|
||||
not for testing.
|
||||
- `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`)
|
||||
- `ACTUALLY_BAN_USERS` (default: `false`): define it to `true` to actually lock
|
||||
user accounts, send notification emails and eventually delete user accounts.
|
||||
Otherwise, no actual action is taken: spammers are only listed in the
|
||||
database. The variable should be set in production, but probably not for
|
||||
testing.
|
||||
- `STORAGE_BACKEND` (default: `local`): either `local` 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).
|
||||
- `BIND_ADDR` (default: `127.0.0.1:8080`): address on which the webserver listens
|
||||
|
||||
Environment variables read when `ACTUALLY_BAN_USERS=true`:
|
||||
- `SMTP_ADDRESS`: address of the SMTP relay used to send email notifications
|
||||
- `SMTP_USERNAME`: SMTP username
|
||||
- `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`:
|
||||
- `STORAGE_LOCAL_DIR`: path to a local directory where to store the application
|
||||
data (as two files `db.json` and `model.json`). Defaults to `.` if not
|
||||
defined.
|
||||
- `STORAGE_LOCAL_DIR` (default: `.`): path to a local directory where to store
|
||||
the application data (as two files `db.json` and `model.json`).
|
||||
|
||||
Environment variables read when `STORAGE_BACKEND=s3`:
|
||||
- `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(
|
||||
config: &Config,
|
||||
smtp: &SmtpConfig,
|
||||
admin_contact_email: &str,
|
||||
org_name: &str,
|
||||
login: &str,
|
||||
email: &str,
|
||||
) -> anyhow::Result<()> {
|
||||
let grace_period_days = crate::GRACE_PERIOD.as_secs() / (24 * 3600);
|
||||
let org_name = &config.org_name;
|
||||
let forge_url = &config.forge_url;
|
||||
let admin_contact_email = &config.admin_contact_email;
|
||||
|
||||
let email = Message::builder()
|
||||
.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 forge_url: Url,
|
||||
pub forge_api_token: String,
|
||||
pub org_name: String,
|
||||
pub admin_contact_email: String,
|
||||
pub actually_ban: ActuallyBan,
|
||||
pub listen_addr: String,
|
||||
pub listen_port: u16,
|
||||
pub bind_addr: String,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
async fn from_env() -> anyhow::Result<Self> {
|
||||
let forge_url_s = env_var("FORGE_URL")?;
|
||||
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() {
|
||||
Ok("true") => ActuallyBan::Yes {
|
||||
smtp: SmtpConfig::from_env().await?,
|
||||
admin_contact_email: env_var("ADMIN_CONTACT_EMAIL")?,
|
||||
org_name: env_var("ORG_NAME")?,
|
||||
},
|
||||
Ok("false") => ActuallyBan::No,
|
||||
Ok(_) => {
|
||||
|
@ -83,21 +80,13 @@ impl Config {
|
|||
Err(_) => ActuallyBan::No,
|
||||
};
|
||||
|
||||
let listen_addr = env_var("LISTEN_ADDR").unwrap_or(String::from("0.0.0.0"));
|
||||
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,
|
||||
};
|
||||
let bind_addr = env_var("BIND_ADDR").unwrap_or(String::from("127.0.0.1:8080"));
|
||||
|
||||
Ok(Config {
|
||||
forge_url: Url::parse(&forge_url_s).context("parsing FORGE_URL")?,
|
||||
forge_api_token,
|
||||
org_name,
|
||||
admin_contact_email,
|
||||
actually_ban,
|
||||
listen_addr,
|
||||
listen_port,
|
||||
bind_addr,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +94,11 @@ impl Config {
|
|||
// Whether we are actually banning users or are instead in "testing" mode where
|
||||
// we don't do anything. (Defaults to "No".)
|
||||
pub enum ActuallyBan {
|
||||
Yes { smtp: SmtpConfig },
|
||||
Yes {
|
||||
smtp: SmtpConfig,
|
||||
admin_contact_email: String,
|
||||
org_name: String,
|
||||
},
|
||||
No,
|
||||
}
|
||||
|
||||
|
@ -496,15 +489,7 @@ async fn main() -> anyhow::Result<()> {
|
|||
.spawn(async move { workers::lock_and_notify_users(config, storage, forge, db).await })
|
||||
};
|
||||
|
||||
println!(
|
||||
"Listening on http://{}:{}",
|
||||
(if config.listen_addr == "0.0.0.0" {
|
||||
"127.0.0.1"
|
||||
} else {
|
||||
&config.listen_addr
|
||||
}),
|
||||
config.listen_port
|
||||
);
|
||||
println!("Listening on http://{}", &config.bind_addr);
|
||||
|
||||
let app = Router::new()
|
||||
.route("/", get(get_index).post(post_classified_index))
|
||||
|
@ -516,10 +501,9 @@ async fn main() -> anyhow::Result<()> {
|
|||
.with_state(shared_state);
|
||||
|
||||
let webserver = {
|
||||
let listener =
|
||||
tokio::net::TcpListener::bind((config.listen_addr.clone(), config.listen_port))
|
||||
.await
|
||||
.unwrap();
|
||||
let listener = tokio::net::TcpListener::bind(&config.bind_addr)
|
||||
.await
|
||||
.unwrap();
|
||||
axum::serve(listener, app)
|
||||
};
|
||||
|
||||
|
|
|
@ -237,9 +237,21 @@ pub async fn try_lock_and_notify_user(
|
|||
|
||||
if !notified {
|
||||
match &config.actually_ban {
|
||||
ActuallyBan::Yes { smtp } => {
|
||||
ActuallyBan::Yes {
|
||||
smtp,
|
||||
admin_contact_email,
|
||||
org_name,
|
||||
} => {
|
||||
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");
|
||||
}
|
||||
ActuallyBan::No => {
|
||||
|
|
Loading…
Reference in a new issue