add sanity check, fix config default
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
b03a7a165b
commit
cce6272373
8 changed files with 176 additions and 32 deletions
85
Cargo.lock
generated
85
Cargo.lock
generated
|
@ -358,12 +358,42 @@ dependencies = [
|
|||
"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]]
|
||||
name = "event-listener"
|
||||
version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
|
||||
dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "figment"
|
||||
version = "0.10.10"
|
||||
|
@ -371,8 +401,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "4547e226f4c9ab860571e070a9034192b3175580ecea38da34fcdb53a018c9a5"
|
||||
dependencies = [
|
||||
"atomic",
|
||||
"parking_lot 0.12.1",
|
||||
"pear",
|
||||
"serde",
|
||||
"tempfile",
|
||||
"toml",
|
||||
"uncased",
|
||||
"version_check",
|
||||
|
@ -509,6 +541,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
|
@ -648,6 +686,17 @@ dependencies = [
|
|||
"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]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
|
@ -684,6 +733,12 @@ version = "0.2.146"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.10"
|
||||
|
@ -800,7 +855,7 @@ version = "1.15.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.2.6",
|
||||
"libc",
|
||||
]
|
||||
|
||||
|
@ -1053,6 +1108,20 @@ dependencies = [
|
|||
"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]]
|
||||
name = "rustls"
|
||||
version = "0.20.8"
|
||||
|
@ -1378,6 +1447,20 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
|
|
|
@ -14,7 +14,7 @@ sqlx = { version = "0.6", features = [ "runtime-tokio-rustls", "postgres", "uuid
|
|||
uuid = { version = "1.3", features = ["v4", "fast-rng", "serde"] }
|
||||
serde = { version = "1" }
|
||||
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"] }
|
||||
anyhow = "1.0"
|
||||
argon2 = { version = "0.5", features = ["std", "alloc"] }
|
||||
|
|
|
@ -65,26 +65,19 @@ pub struct Page {
|
|||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[serde(tag = "kind")]
|
||||
pub enum PageBlock {
|
||||
Markup(MarkupBlock),
|
||||
Gallery(GalleryBlock),
|
||||
}
|
||||
|
||||
/// A block of content in written form (probably Markdown)
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct MarkupBlock {
|
||||
MarkupV1 {
|
||||
/// Markup format (markdown, html, plain)
|
||||
pub format: String,
|
||||
format: String,
|
||||
|
||||
/// Markup content (before rendering)
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
/// A block containing one or more images
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct GalleryBlock {
|
||||
content: String,
|
||||
},
|
||||
GalleryV1 {
|
||||
/// Images in the gallery
|
||||
pub images: Vec<ImageElement>,
|
||||
images: Vec<ImageElement>,
|
||||
},
|
||||
}
|
||||
|
||||
/// Picture inside a gallery
|
||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -7,7 +7,7 @@ mod state;
|
|||
|
||||
use crate::{auth::http::refresh_sessions, state::Config};
|
||||
use anyhow::Result;
|
||||
use axum::{middleware, Router, Server};
|
||||
use axum::{middleware, Server};
|
||||
use figment::{
|
||||
providers::{Env, Format, Serialized, Toml},
|
||||
Figment,
|
||||
|
@ -33,12 +33,12 @@ async fn main() -> Result<()> {
|
|||
|
||||
sqlx::migrate!().run(&database).await?;
|
||||
|
||||
// Sanity check config
|
||||
config.sanity_check();
|
||||
|
||||
let shared_state = Arc::new(AppState { database, config });
|
||||
|
||||
let app = Router::new()
|
||||
.nest("/auth", routes::auth::router())
|
||||
.nest("/admin", routes::admin::router())
|
||||
.nest("/posts", routes::posts::router())
|
||||
let app = routes::create_router()
|
||||
.route_layer(middleware::from_fn_with_state(
|
||||
shared_state.clone(),
|
||||
refresh_sessions,
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
pub mod admin;
|
||||
pub mod auth;
|
||||
pub mod posts;
|
||||
use axum::Router;
|
||||
use std::sync::Arc;
|
||||
|
||||
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())
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use axum::{
|
||||
extract::{Path, State},
|
||||
response::IntoResponse,
|
||||
routing::get,
|
||||
Router,
|
||||
Json, Router,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -10,14 +11,14 @@ use crate::{content::Page, error::AppError, state::AppState};
|
|||
async fn get_page(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Path((site, slug)): Path<(String, String)>,
|
||||
) -> Result<String, AppError<'static>> {
|
||||
) -> Result<impl IntoResponse, AppError<'static>> {
|
||||
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",
|
||||
)
|
||||
.bind(slug)
|
||||
.bind(site);
|
||||
let page: Page = page_query.fetch_one(&state.database).await?;
|
||||
Ok(page.title)
|
||||
Ok(Json(page))
|
||||
}
|
||||
|
||||
pub fn router() -> Router<Arc<AppState>> {
|
||||
|
|
41
src/routes/sites.rs
Normal file
41
src/routes/sites.rs
Normal 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))
|
||||
}
|
14
src/state.rs
14
src/state.rs
|
@ -24,6 +24,18 @@ impl Config {
|
|||
.map(|x| x.domain().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 {
|
||||
|
@ -32,7 +44,7 @@ impl Default for Config {
|
|||
bind: "127.0.0.1:3000".into(),
|
||||
database_url: "postgres://artificiale:changeme@localhost/artificiale".into(),
|
||||
session_duration: 3600, // 60min
|
||||
prune_interval: 10, // 60min
|
||||
prune_interval: 3600, // 60min
|
||||
base_url: "http://localhost".into(),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue