put config into lazy statics from env vars

This commit is contained in:
Joe Ardent 2024-03-08 09:55:45 -08:00
parent ce4c250ba0
commit da6af0d30c
2 changed files with 16 additions and 30 deletions

View file

@ -4,7 +4,6 @@ use axum::{
extract::{Form, Path}, extract::{Form, Path},
response::{IntoResponse, Redirect}, response::{IntoResponse, Redirect},
}; };
use rand::random;
use tower_sessions::Session; use tower_sessions::Session;
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
@ -19,9 +18,14 @@ const USERNAME_LEN: RangeInclusive<usize> = 1..=50;
const DISPLAYNAME_LEN: RangeInclusive<usize> = 0..=100; const DISPLAYNAME_LEN: RangeInclusive<usize> = 0..=100;
const EMAIL_LEN: RangeInclusive<usize> = 4..=50; const EMAIL_LEN: RangeInclusive<usize> = 4..=50;
const CHECKOUT_TIMEOUT: i64 = 12 * 3600; const CHECKOUT_TIMEOUT: i64 = 12 * 3600;
const SIGNUP_KEY: &str = "meow";
lazy_static! { lazy_static! {
static ref SIGNUP_KEY: String = format!("meow-{}", random::<u128>()); static ref ADMIN_TOKEN: String = std::env::var("ADMIN_TOKEN").unwrap();
static ref FORGEJO_URL: String = std::env::var("FORGEJO_URL").unwrap();
static ref STRIPE_TOKEN: String = std::env::var("STRIPE_TOKEN").unwrap();
static ref ANNUAL_LINK: String = std::env::var("ANNUAL_LINK").unwrap();
static ref MONTHLY_LINK: String = std::env::var("MONTHLY_LINK").unwrap();
} }
/// Displays the signup form. /// Displays the signup form.
@ -37,7 +41,7 @@ pub async fn post_signup(
Form(form): Form<SignupForm>, Form(form): Form<SignupForm>,
) -> Result<impl IntoResponse, CreateUserError> { ) -> Result<impl IntoResponse, CreateUserError> {
let user = validate_signup(&form).await?; let user = validate_signup(&form).await?;
match session.insert(&SIGNUP_KEY, user).await { match session.insert(SIGNUP_KEY, user).await {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
log::error!( log::error!(
@ -50,9 +54,7 @@ pub async fn post_signup(
match session.save().await { match session.save().await {
// TODO: pass in as env var/into a state object that the handlers can read from // TODO: pass in as env var/into a state object that the handlers can read from
Ok(_) => Ok(Redirect::to( Ok(_) => Ok(Redirect::to(&MONTHLY_LINK)),
"https://buy.stripe.com/test_eVa6rrb7ygjNbwk000",
)),
Err(e) => { Err(e) => {
log::error!("Could not save session, got {}", e); log::error!("Could not save session, got {}", e);
Err(CreateUserErrorKind::UnknownEorr.into()) Err(CreateUserErrorKind::UnknownEorr.into())
@ -66,7 +68,7 @@ pub async fn payment_success(session: Session, receipt: Option<Path<String>>) ->
log::error!("Could not load the session, got {}", e); log::error!("Could not load the session, got {}", e);
}); });
log::debug!("loaded the session"); log::debug!("loaded the session");
let user = if let Some(user) = session.get::<User>(&SIGNUP_KEY).await.unwrap_or(None) { let user = if let Some(user) = session.get::<User>(SIGNUP_KEY).await.unwrap_or(None) {
user user
} else { } else {
log::warn!("Could not find user in session; got receipt {:?}", receipt); log::warn!("Could not find user in session; got receipt {:?}", receipt);
@ -106,11 +108,10 @@ pub async fn payment_success(session: Session, receipt: Option<Path<String>>) ->
// helpers // helpers
//-************************************************************************ //-************************************************************************
fn create_user(user: &User) -> bool { fn create_user(user: &User) -> bool {
let token = std::env::var("ADMIN_TOKEN").expect("Could not find $ADMIN_TOKEN in environment."); let token = &*ADMIN_TOKEN;
let url = std::env::var("ADD_USER_ENDPOINT")
.expect("Could not find $ADD_USER_ENDPOINT in environment");
let auth_header = format!("token {token}"); let auth_header = format!("token {token}");
let user: ForgejoUser = user.into(); let user: ForgejoUser = user.into();
let url = &*FORGEJO_URL;
let resp = ureq::post(&format!("{url}/api/v1/admin/users")) let resp = ureq::post(&format!("{url}/api/v1/admin/users"))
.set("Authorization", &auth_header) .set("Authorization", &auth_header)
.set("Content-Type", "application/json") .set("Content-Type", "application/json")
@ -127,7 +128,7 @@ fn create_user(user: &User) -> bool {
} }
fn confirm_payment(stripe_checkout_session_id: &str) -> bool { fn confirm_payment(stripe_checkout_session_id: &str) -> bool {
let token = std::env::var("STRIPE_TOKEN").expect("Could not find $STRIPE_TOKEN in environment"); let token = &*STRIPE_TOKEN;
let url = format!("https://api.stripe.com/v1/checkout/sessions/{stripe_checkout_session_id}"); let url = format!("https://api.stripe.com/v1/checkout/sessions/{stripe_checkout_session_id}");
let json: serde_json::Value = ureq::get(&url) let json: serde_json::Value = ureq::get(&url)
.set("Authorization", &format!("Bearer {token}")) .set("Authorization", &format!("Bearer {token}"))

View file

@ -24,14 +24,6 @@ mod handlers;
mod templates; mod templates;
mod user; mod user;
struct Config {
pub admin_token: String,
pub forgejo_url: String,
pub stripe_token: String,
pub annual_link: String,
pub monthly_link: String,
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
use handlers::handlers::{get_signup, payment_success, post_signup}; use handlers::handlers::{get_signup, payment_success, post_signup};
@ -47,6 +39,7 @@ async fn main() {
let session_store = SqliteStore::new(pool.clone()); let session_store = SqliteStore::new(pool.clone());
session_store.migrate().await.unwrap(); session_store.migrate().await.unwrap();
session_store.migrate().await.unwrap();
let session_layer = SessionManagerLayer::new(session_store) let session_layer = SessionManagerLayer::new(session_store)
.with_secure(false) .with_secure(false)
.with_same_site(tower_sessions::cookie::SameSite::Lax) .with_same_site(tower_sessions::cookie::SameSite::Lax)
@ -68,8 +61,7 @@ async fn main() {
//-************************************************************************ //-************************************************************************
// li'l helpers // li'l helpers
//-************************************************************************ //-************************************************************************
fn init() -> Config { fn init() {
use std::env::var;
dotenvy::dotenv().expect("Could not read .env file."); dotenvy::dotenv().expect("Could not read .env file.");
env_logger::builder() env_logger::builder()
.format(|buf, record| { .format(|buf, record| {
@ -77,21 +69,14 @@ fn init() -> Config {
writeln!(buf, "{}: {}", ts, record.args()) writeln!(buf, "{}: {}", ts, record.args())
}) })
.init(); .init();
Config {
admin_token: var("ADMIN_TOKEN").unwrap(),
forgejo_url: var("FORGEJO_URL").unwrap(),
stripe_token: var("STRIPE_TOKEN").unwrap(),
annual_link: var("ANNUAL_LINK").unwrap(),
monthly_link: var("MONTHLY_LINK").unwrap(),
}
} }
async fn db() -> SqlitePool { async fn db() -> SqlitePool {
let dbfile = std::env::var("DATABASE_URL").unwrap(); //let dbfile = std::env::var("DATABASE_URL").unwrap();
let opts = SqliteConnectOptions::new() let opts = SqliteConnectOptions::new()
.foreign_keys(true) .foreign_keys(true)
.filename(dbfile)
.create_if_missing(true) .create_if_missing(true)
.journal_mode(sqlx::sqlite::SqliteJournalMode::Persist)
.optimize_on_close(true, None); .optimize_on_close(true, None);
SqlitePoolOptions::new().connect_with(opts).await.unwrap() SqlitePoolOptions::new().connect_with(opts).await.unwrap()
} }