feat: Basic user creation form
This commit is contained in:
parent
78df25f150
commit
e28c584b26
5 changed files with 54 additions and 5 deletions
|
|
@ -67,12 +67,11 @@ pub trait DatabaseInterface: Clone + Send + Sync + 'static {
|
|||
&mut self,
|
||||
user: User,
|
||||
) -> Result<Result<(), UserCreationError>, BoxedError>;
|
||||
#[expect(unused)]
|
||||
async fn try_create_user(
|
||||
fn try_create_user(
|
||||
&mut self,
|
||||
new_user: User,
|
||||
current_user: &User,
|
||||
) -> Result<Result<(), UserCreationError>, BoxedError>;
|
||||
) -> impl Future<Output = Result<Result<(), UserCreationError>, BoxedError>> + Send;
|
||||
|
||||
fn list_all_domains(&self) -> impl Future<Output = Result<Vec<Domain>, BoxedError>> + Send;
|
||||
#[expect(unused)]
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ impl DatabaseInterface for MemoryDatabase {
|
|||
//
|
||||
// TODO: for now we don't allow creating service users manually
|
||||
// so we assume there's a domain provided
|
||||
// TODO: restrict user creation on non-declared domains
|
||||
let Some(new_user_domain) = &new_user.domain else {
|
||||
return Ok(Err(UserCreationError::Permissions));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ mod login;
|
|||
mod logout;
|
||||
mod session;
|
||||
use session::HttpSessionManager;
|
||||
mod user;
|
||||
|
||||
impl AxumListener for Listener {
|
||||
type Io = AbstractStreamKind;
|
||||
|
|
@ -102,6 +103,7 @@ pub async fn http_listen<D: DatabaseInterface>(listener: Listener, db: Database<
|
|||
.route("/logout", get(logout::logout))
|
||||
.route("/domain/{domain}", get(domain::get_domain))
|
||||
.route("/domain", post(domain::create_domain))
|
||||
.route("/user", post(user::create_user))
|
||||
.with_state(HttpState::new(db));
|
||||
|
||||
axum::serve(listener, app).await.unwrap();
|
||||
|
|
|
|||
49
src/http/user.rs
Normal file
49
src/http/user.rs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
use axum::extract::{Form, State};
|
||||
use axum::response::{IntoResponse, Redirect, Response};
|
||||
use axum_extra::extract::cookie::CookieJar;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::db::{DatabaseInterface, Role, User};
|
||||
use crate::http::HttpState;
|
||||
use crate::http::login::login_page;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct UserCreationForm {
|
||||
pub username: String,
|
||||
pub domain: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
pub async fn create_user<D: DatabaseInterface>(
|
||||
State(mut state): State<HttpState<D>>,
|
||||
cookies: CookieJar,
|
||||
Form(form): Form<UserCreationForm>,
|
||||
) -> Response {
|
||||
let Some(session) = state.sessions.get_session(&cookies) else {
|
||||
return login_page(State(state), None).await.into_response();
|
||||
};
|
||||
|
||||
// let domain = form.domain;
|
||||
// let op = Operation::CreateUser(domain.clone());
|
||||
// if !session.user.can_perform(&op) {
|
||||
// return format!("Not authorized to create a new user on domain {domain}").into_response()
|
||||
// }
|
||||
|
||||
let new_user = User {
|
||||
mail: format!("{}@{}", form.username, form.domain),
|
||||
username: form.username.clone(),
|
||||
domain: Some(form.domain.clone()),
|
||||
password: form.password,
|
||||
role: Role::User,
|
||||
};
|
||||
|
||||
match state.db.try_create_user(new_user, &session.user).await {
|
||||
Ok(Ok(())) => Redirect::to(&format!("/domain/{}", form.domain)).into_response(),
|
||||
Ok(Err(e)) => format!(
|
||||
"Failed to create user {} on domain {}: {}",
|
||||
form.username, form.domain, e
|
||||
)
|
||||
.into_response(),
|
||||
Err(e) => format!("Database error: {e}").into_response(),
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
<div>
|
||||
<h2>Create user</h2>
|
||||
<form action="/user" method="POST">
|
||||
<input type="hidden" name="domainname" value="{{ domain.name }}">
|
||||
<input type="hidden" name="domain" value="{{ domain.name }}">
|
||||
<input type="text" name="username" placeholder="username">
|
||||
<input type="password" name="password" placeholder="password">
|
||||
<button type="submit" class="button is-info">Create</button>
|
||||
|
|
|
|||
Loading…
Reference in a new issue