Add configuration system
This commit is contained in:
parent
e178b93ffb
commit
446c576b4d
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
/target
|
/target
|
||||||
|
config.toml
|
||||||
|
|
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -1780,6 +1780,7 @@ dependencies = [
|
||||||
"tera",
|
"tera",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"toml",
|
||||||
"tower",
|
"tower",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1837,6 +1838,15 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.4.13"
|
version = "0.4.13"
|
||||||
|
|
|
@ -15,6 +15,7 @@ sqlx = { version = "0.6.1", features = ["runtime-tokio-rustls", "postgres"] }
|
||||||
tera = "1.16.0"
|
tera = "1.16.0"
|
||||||
thiserror = "1.0.32"
|
thiserror = "1.0.32"
|
||||||
tokio = { version = "1.20.1", features = ["full"] }
|
tokio = { version = "1.20.1", features = ["full"] }
|
||||||
|
toml = "0.5.9"
|
||||||
tower = "0.4.13"
|
tower = "0.4.13"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
41
src/main.rs
41
src/main.rs
|
@ -11,6 +11,7 @@ use axum::{
|
||||||
};
|
};
|
||||||
use axum_sessions::extractors::ReadableSession;
|
use axum_sessions::extractors::ReadableSession;
|
||||||
use axum_sessions::{async_session::MemoryStore, SessionLayer};
|
use axum_sessions::{async_session::MemoryStore, SessionLayer};
|
||||||
|
use serde::Deserialize;
|
||||||
use sqlx::postgres::PgPoolOptions;
|
use sqlx::postgres::PgPoolOptions;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tera::Tera;
|
use tera::Tera;
|
||||||
|
@ -24,6 +25,9 @@ pub enum Error {
|
||||||
Tokio(#[from] tokio::task::JoinError),
|
Tokio(#[from] tokio::task::JoinError),
|
||||||
Pbkdf2(pbkdf2::password_hash::Error),
|
Pbkdf2(pbkdf2::password_hash::Error),
|
||||||
Session(#[from] axum_sessions::async_session::serde_json::Error),
|
Session(#[from] axum_sessions::async_session::serde_json::Error),
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
Toml(#[from] toml::de::Error),
|
||||||
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Error {
|
impl std::fmt::Display for Error {
|
||||||
|
@ -36,6 +40,9 @@ impl std::fmt::Display for Error {
|
||||||
Tokio(e) => Display::fmt(e, f),
|
Tokio(e) => Display::fmt(e, f),
|
||||||
Pbkdf2(e) => Display::fmt(e, f),
|
Pbkdf2(e) => Display::fmt(e, f),
|
||||||
Session(e) => Display::fmt(e, f),
|
Session(e) => Display::fmt(e, f),
|
||||||
|
Io(e) => Display::fmt(e, f),
|
||||||
|
Toml(e) => Display::fmt(e, f),
|
||||||
|
Other(e) => write!(f, "Error: {}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,26 +61,44 @@ impl From<pbkdf2::password_hash::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<String> for Error {
|
||||||
|
fn from(e: String) -> Self {
|
||||||
|
Self::Other(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
pub struct Config {
|
||||||
|
secret: String,
|
||||||
|
connection_string: String,
|
||||||
|
template_dir: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Error> {
|
async fn main() -> Result<(), Error> {
|
||||||
|
let filename = std::env::var("TMTD_CONFIG").unwrap_or("config.toml".into());
|
||||||
|
let contents = std::fs::read_to_string(filename)?;
|
||||||
|
let config: Config = toml::from_str(&contents)?;
|
||||||
let pool = Arc::new(
|
let pool = Arc::new(
|
||||||
PgPoolOptions::new()
|
PgPoolOptions::new()
|
||||||
.connect("postgresql://tmtd@192.168.1.133/tmtd")
|
.connect(&config.connection_string)
|
||||||
.await?,
|
.await?,
|
||||||
);
|
);
|
||||||
|
|
||||||
sqlx::query("create table if not exists users(id serial primary key, username text not null unique, password_hash text not null)").execute(&*pool).await?;
|
sqlx::query("create table if not exists users(id serial primary key, username text not null unique, password_hash text not null)").execute(&*pool).await?;
|
||||||
|
|
||||||
let mut tera = Arc::new(Tera::new("templates/**/*.html")?);
|
let tera = Arc::new(Tera::new(&format!(
|
||||||
|
"{}/**/*.html",
|
||||||
{
|
config.template_dir.as_deref().unwrap_or("templates")
|
||||||
Arc::get_mut(&mut tera).unwrap().full_reload()?;
|
))?);
|
||||||
}
|
|
||||||
|
|
||||||
let store = MemoryStore::new();
|
let store = MemoryStore::new();
|
||||||
// TODO: make this configurable
|
// TODO: make this configurable
|
||||||
let secret = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
if config.secret.len() < 64 {
|
||||||
let session_layer = SessionLayer::new(store, secret).with_cookie_name("2m2d_session");
|
return Err("Secret must be at least 64 bytes!".to_string().into());
|
||||||
|
}
|
||||||
|
let session_layer =
|
||||||
|
SessionLayer::new(store, config.secret.as_bytes()).with_cookie_name("2m2d_session");
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(homepage))
|
.route("/", get(homepage))
|
||||||
|
|
Loading…
Reference in a new issue