feat: Basic domain creation form

This commit is contained in:
selfhoster selfhoster 2026-09-19 10:51:23 +02:00
commit 78df25f150
3 changed files with 31 additions and 4 deletions

View file

@ -53,7 +53,7 @@ pub trait DatabaseInterface: Clone + Send + Sync + 'static {
fn create_domain( fn create_domain(
&mut self, &mut self,
domain: &str, domain: &str,
) -> impl Future<Output = Result<Result<(), DomainCreationError>, BoxedError>>; ) -> impl Future<Output = Result<Result<(), DomainCreationError>, BoxedError>> + Send;
fn get_domain( fn get_domain(
&self, &self,
domain: &str, domain: &str,

View file

@ -1,8 +1,9 @@
use axum::extract::{Path, State}; use axum::extract::{Form, Path, State};
use axum::response::{Html, IntoResponse, Response}; use axum::response::{Html, IntoResponse, Redirect, Response};
use axum_extra::extract::cookie::CookieJar; use axum_extra::extract::cookie::CookieJar;
use http::StatusCode; use http::StatusCode;
use minijinja::context; use minijinja::context;
use serde::Deserialize;
use crate::db::{DatabaseInterface, Operation}; use crate::db::{DatabaseInterface, Operation};
use crate::http::HttpState; use crate::http::HttpState;
@ -52,3 +53,29 @@ pub async fn get_domain<D: DatabaseInterface>(
.unwrap(); .unwrap();
(StatusCode::OK, Html(page)).into_response() (StatusCode::OK, Html(page)).into_response()
} }
#[derive(Clone, Debug, Deserialize)]
pub struct DomainCreationForm {
domainname: String,
}
pub async fn create_domain<D: DatabaseInterface>(
State(mut state): State<HttpState<D>>,
cookies: CookieJar,
Form(form): Form<DomainCreationForm>,
) -> Response {
let Some(session) = state.sessions.get_session(&cookies) else {
return login_page(State(state), None).await.into_response();
};
let op = Operation::CreateDomain;
if !session.user.can_perform(&op) {
return "Not authorized to create a new domain".into_response();
}
match state.db.create_domain(&form.domainname).await {
Ok(Ok(())) => Redirect::to(&format!("/domain/{}", form.domainname)).into_response(),
Ok(Err(e)) => format!("Failed to create domain {}: {}", form.domainname, e).into_response(),
Err(e) => format!("Database error: {e}").into_response(),
}
}

View file

@ -101,7 +101,7 @@ pub async fn http_listen<D: DatabaseInterface>(listener: Listener, db: Database<
.route("/login", post(login::post_login)) .route("/login", post(login::post_login))
.route("/logout", get(logout::logout)) .route("/logout", get(logout::logout))
.route("/domain/{domain}", get(domain::get_domain)) .route("/domain/{domain}", get(domain::get_domain))
//.route("/domain", post(domain::create_domain)) .route("/domain", post(domain::create_domain))
.with_state(HttpState::new(db)); .with_state(HttpState::new(db));
axum::serve(listener, app).await.unwrap(); axum::serve(listener, app).await.unwrap();