add sanity check, fix config default
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Hamcha 2023-07-06 10:43:33 +02:00
parent b03a7a165b
commit cce6272373
Signed by: hamcha
GPG key ID: 1669C533B8CF6D89
8 changed files with 176 additions and 32 deletions

85
Cargo.lock generated
View file

@ -358,12 +358,42 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "errno"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "2.5.3" version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
[[package]] [[package]]
name = "figment" name = "figment"
version = "0.10.10" version = "0.10.10"
@ -371,8 +401,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4547e226f4c9ab860571e070a9034192b3175580ecea38da34fcdb53a018c9a5" checksum = "4547e226f4c9ab860571e070a9034192b3175580ecea38da34fcdb53a018c9a5"
dependencies = [ dependencies = [
"atomic", "atomic",
"parking_lot 0.12.1",
"pear", "pear",
"serde", "serde",
"tempfile",
"toml", "toml",
"uncased", "uncased",
"version_check", "version_check",
@ -509,6 +541,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "hermit-abi"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
[[package]] [[package]]
name = "hex" name = "hex"
version = "0.4.3" version = "0.4.3"
@ -648,6 +686,17 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "io-lifetimes"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
dependencies = [
"hermit-abi 0.3.2",
"libc",
"windows-sys",
]
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.10.5" version = "0.10.5"
@ -684,6 +733,12 @@ version = "0.2.146"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
[[package]]
name = "linux-raw-sys"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.4.10" version = "0.4.10"
@ -800,7 +855,7 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi 0.2.6",
"libc", "libc",
] ]
@ -1053,6 +1108,20 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "rustix"
version = "0.37.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.20.8" version = "0.20.8"
@ -1378,6 +1447,20 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "tempfile"
version = "3.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
dependencies = [
"autocfg",
"cfg-if",
"fastrand",
"redox_syscall 0.3.5",
"rustix",
"windows-sys",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.40" version = "1.0.40"

View file

@ -14,7 +14,7 @@ sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "postgres", "uuid
uuid = { version = "1.3", features = ["v4", "fast-rng", "serde"] } uuid = { version = "1.3", features = ["v4", "fast-rng", "serde"] }
serde = { version = "1" } serde = { version = "1" }
serde_json = { version = "1", features = ["raw_value"] } serde_json = { version = "1", features = ["raw_value"] }
figment = { version = "0.10", features = ["toml", "env"] } figment = { version = "0.10", features = ["toml", "env", "test"] }
chrono = { version = "0.4", features = ["serde", "clock"] } chrono = { version = "0.4", features = ["serde", "clock"] }
anyhow = "1.0" anyhow = "1.0"
argon2 = { version = "0.5", features = ["std", "alloc"] } argon2 = { version = "0.5", features = ["std", "alloc"] }

View file

@ -65,26 +65,19 @@ pub struct Page {
} }
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
#[serde(tag = "kind")]
pub enum PageBlock { pub enum PageBlock {
Markup(MarkupBlock), MarkupV1 {
Gallery(GalleryBlock), /// Markup format (markdown, html, plain)
} format: String,
/// A block of content in written form (probably Markdown) /// Markup content (before rendering)
#[derive(Deserialize, Serialize)] content: String,
pub struct MarkupBlock { },
/// Markup format (markdown, html, plain) GalleryV1 {
pub format: String, /// Images in the gallery
images: Vec<ImageElement>,
/// Markup content (before rendering) },
pub content: String,
}
/// A block containing one or more images
#[derive(Deserialize, Serialize)]
pub struct GalleryBlock {
/// Images in the gallery
pub images: Vec<ImageElement>,
} }
/// Picture inside a gallery /// Picture inside a gallery

View file

@ -7,7 +7,7 @@ mod state;
use crate::{auth::http::refresh_sessions, state::Config}; use crate::{auth::http::refresh_sessions, state::Config};
use anyhow::Result; use anyhow::Result;
use axum::{middleware, Router, Server}; use axum::{middleware, Server};
use figment::{ use figment::{
providers::{Env, Format, Serialized, Toml}, providers::{Env, Format, Serialized, Toml},
Figment, Figment,
@ -33,12 +33,12 @@ async fn main() -> Result<()> {
sqlx::migrate!().run(&database).await?; sqlx::migrate!().run(&database).await?;
// Sanity check config
config.sanity_check();
let shared_state = Arc::new(AppState { database, config }); let shared_state = Arc::new(AppState { database, config });
let app = Router::new() let app = routes::create_router()
.nest("/auth", routes::auth::router())
.nest("/admin", routes::admin::router())
.nest("/posts", routes::posts::router())
.route_layer(middleware::from_fn_with_state( .route_layer(middleware::from_fn_with_state(
shared_state.clone(), shared_state.clone(),
refresh_sessions, refresh_sessions,

View file

@ -1,3 +1,17 @@
pub mod admin; use axum::Router;
pub mod auth; use std::sync::Arc;
pub mod posts;
use crate::state::AppState;
mod admin;
mod auth;
mod posts;
mod sites;
pub fn create_router() -> Router<Arc<AppState>> {
Router::new()
.nest("/auth", auth::router())
.nest("/admin", admin::router())
.nest("/posts", posts::router())
.nest("/sites", sites::router())
}

View file

@ -1,7 +1,8 @@
use axum::{ use axum::{
extract::{Path, State}, extract::{Path, State},
response::IntoResponse,
routing::get, routing::get,
Router, Json, Router,
}; };
use std::sync::Arc; use std::sync::Arc;
@ -10,14 +11,14 @@ use crate::{content::Page, error::AppError, state::AppState};
async fn get_page( async fn get_page(
State(state): State<Arc<AppState>>, State(state): State<Arc<AppState>>,
Path((site, slug)): Path<(String, String)>, Path((site, slug)): Path<(String, String)>,
) -> Result<String, AppError<'static>> { ) -> Result<impl IntoResponse, AppError<'static>> {
let page_query = sqlx::query_as( let page_query = sqlx::query_as(
"SELECT p.* FROM pages p JOIN sites s ON p.site = s.id WHERE p.slug = $1 AND s.name = $2", "SELECT p.* FROM pages p JOIN sites s ON p.site = s.id WHERE p.slug = $1 AND s.name = $2",
) )
.bind(slug) .bind(slug)
.bind(site); .bind(site);
let page: Page = page_query.fetch_one(&state.database).await?; let page: Page = page_query.fetch_one(&state.database).await?;
Ok(page.title) Ok(Json(page))
} }
pub fn router() -> Router<Arc<AppState>> { pub fn router() -> Router<Arc<AppState>> {

41
src/routes/sites.rs Normal file
View file

@ -0,0 +1,41 @@
use axum::{
extract::{Path, State},
response::IntoResponse,
routing::{get, post},
Json, Router,
};
use serde::Deserialize;
use serde_json::json;
use std::sync::Arc;
use crate::{content::Site, error::AppError, state::AppState};
async fn get_site(
State(state): State<Arc<AppState>>,
Path(name): Path<String>,
) -> Result<impl IntoResponse, AppError<'static>> {
let site_query = sqlx::query_as("SELECT * FROM sites WHERE name = $1").bind(name);
let site: Site = site_query.fetch_one(&state.database).await?;
Ok(Json(site))
}
#[derive(Deserialize)]
struct CreateSiteRequest {
name: String,
}
async fn create_site(
State(state): State<Arc<AppState>>,
Json(payload): Json<CreateSiteRequest>,
) -> Result<impl IntoResponse, AppError<'static>> {
sqlx::query!("INSERT INTO sites (name) VALUES ($1)", payload.name)
.execute(&state.database)
.await?;
Ok(Json(json!({"ok": true, "url": "test"})))
}
pub fn router() -> Router<Arc<AppState>> {
Router::new()
.route("/", post(create_site))
.route("/:name", get(get_site))
}

View file

@ -24,6 +24,18 @@ impl Config {
.map(|x| x.domain().unwrap_or("localhost").to_owned()) .map(|x| x.domain().unwrap_or("localhost").to_owned())
.unwrap_or("localhost".to_owned()) .unwrap_or("localhost".to_owned())
} }
pub fn sanity_check(&self) {
// check if base url is valid
if let Err(e) = Url::parse(&self.base_url) {
tracing::warn!("base URL is not valid: {}, falling back to localhost", e);
}
// check that session duration is sensible
if self.session_duration < 100 {
tracing::warn!("session duration is too low, this might cause some headaches");
}
}
} }
impl Default for Config { impl Default for Config {
@ -32,7 +44,7 @@ impl Default for Config {
bind: "127.0.0.1:3000".into(), bind: "127.0.0.1:3000".into(),
database_url: "postgres://artificiale:changeme@localhost/artificiale".into(), database_url: "postgres://artificiale:changeme@localhost/artificiale".into(),
session_duration: 3600, // 60min session_duration: 3600, // 60min
prune_interval: 10, // 60min prune_interval: 3600, // 60min
base_url: "http://localhost".into(), base_url: "http://localhost".into(),
} }
} }