1
0
Fork 0
pique/src/handler/documents.rs
2024-06-01 15:54:43 -04:00

181 lines
5.1 KiB
Rust

use axum::{extract::Path, http::StatusCode, response::Redirect, Form};
use axum_login::AuthSession;
use crate::{
handler::internal_error,
models::{
documents::{self, NewDocument},
users::User,
},
permissions::{self, query::Permission},
prelude::*,
};
pub async fn documents_page(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
) -> Result<Response, (StatusCode, String)> {
if let Some(user) = auth_session.user {
render_documents_page(ctx, user).await
} else {
Ok(Redirect::to("/login").into_response())
}
}
async fn render_documents_page(ctx: Context, user: User) -> Result<Response, (StatusCode, String)> {
let mut db = ctx.db_pool.get().map_err(internal_error)?;
let documents =
permissions::query::accessible_documents(&mut db, &user.id).map_err(internal_error)?;
let projects =
permissions::query::accessible_projects(&mut db, &user.id).map_err(internal_error)?;
let values = context! {
user => user,
documents => documents,
projects => projects,
};
Ok(ctx.render_resp("documents/list_documents.html", values))
}
pub async fn create_document_page(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
) -> Result<Response, (StatusCode, String)> {
let user = match auth_session.user {
Some(user) => user,
None => return Ok(Redirect::to("/login").into_response()),
};
let mut db = ctx.db_pool.get().map_err(internal_error)?;
let projects =
permissions::query::accessible_projects(&mut db, &user.id).map_err(internal_error)?;
let values = context! {
user => user,
projects => projects,
};
Ok(ctx.render_resp("documents/create_document.html", values))
}
#[derive(Debug, Deserialize)]
pub struct CreateDocumentSubmission {
pub project_id: Uuid,
pub title: String,
}
pub async fn create_document_submit(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
form: Form<CreateDocumentSubmission>,
) -> Result<Response, (StatusCode, String)> {
let user = match auth_session.user {
Some(user) => user,
None => return Ok(Redirect::to("/login").into_response()),
};
let mut db = ctx.db_pool.get().map_err(internal_error)?;
let project_allowed = permissions::query::check_user_project(
&mut db,
&user.id,
&form.project_id.to_string(),
Permission::Write,
)
.map_err(internal_error)?;
if !project_allowed {
return Err((StatusCode::FORBIDDEN, "permission denied".to_owned()));
}
let new_document = NewDocument::new(
&user.id,
&form.project_id.to_string(),
form.title.to_owned(),
"".to_owned(),
);
let document = documents::query::create(&mut db, new_document).map_err(internal_error)?;
info!(?document, "document created");
Ok(Redirect::to("/documents").into_response())
}
pub async fn edit_document_page(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
Path((id,)): Path<(Uuid,)>,
) -> Result<Response, (StatusCode, String)> {
let user = match auth_session.user {
Some(user) => user,
None => return Ok(Redirect::to("/login").into_response()),
};
let mut db = ctx.db_pool.get().map_err(internal_error)?;
let document_allowed = permissions::query::check_user_document(
&mut db,
&user.id,
&id.to_string(),
Permission::Write,
)
.map_err(internal_error)?;
if !document_allowed {
return Err((StatusCode::FORBIDDEN, "permission denied".to_owned()));
}
let document = documents::query::by_id(&mut db, &id.to_string()).map_err(internal_error)?;
let projects =
permissions::query::accessible_projects(&mut db, &user.id).map_err(internal_error)?;
let values = context! {
user => user,
document => document,
projects => projects,
};
Ok(ctx.render_resp("documents/edit_document.html", values))
}
#[derive(Debug, Deserialize)]
pub struct EditDocumentSubmission {
pub title: String,
pub content: String,
}
pub async fn edit_document_submit(
State(ctx): State<Context>,
auth_session: AuthSession<Context>,
Path((document_id,)): Path<(Uuid,)>,
form: Form<EditDocumentSubmission>,
) -> Result<Response, (StatusCode, String)> {
let user = match auth_session.user {
Some(user) => user,
None => return Ok(Redirect::to("/login").into_response()),
};
let mut db = ctx.db_pool.get().map_err(internal_error)?;
let document_allowed = permissions::query::check_user_document(
&mut db,
&user.id,
&document_id.to_string(),
Permission::Write,
)
.map_err(internal_error)?;
if !document_allowed {
return Err((StatusCode::FORBIDDEN, "permission denied".to_owned()));
}
documents::query::update(
&mut db,
&document_id.to_string(),
form.title.to_owned(),
form.content.to_owned(),
)
.map_err(internal_error)?;
Ok(Redirect::to("/documents").into_response())
}