1
0
Fork 0
pique/src/handler/documents.rs

180 lines
5.1 KiB
Rust

use axum::extract::Path;
use axum::http::StatusCode;
use axum::response::Redirect;
use axum::Form;
use axum_login::AuthSession;
use crate::handler::internal_error;
use crate::models::documents::{self, NewDocument};
use crate::models::users::User;
use crate::permissions::q::Permission;
use crate::permissions::{self};
use crate::prelude::*;
pub async fn documents_page(
State(provider): State<Provider>,
auth_session: AuthSession<Provider>,
) -> Result<Response, (StatusCode, String)> {
if let Some(user) = auth_session.user {
render_documents_page(provider, user).await
} else {
Ok(Redirect::to("/login").into_response())
}
}
async fn render_documents_page(
provider: Provider,
user: User,
) -> Result<Response, (StatusCode, String)> {
let mut db = provider.db_pool.get().map_err(internal_error)?;
let documents =
permissions::q::accessible_documents(&mut db, &user.id).map_err(internal_error)?;
let projects =
permissions::q::accessible_projects(&mut db, &user.id).map_err(internal_error)?;
let values = context! {
user => user,
documents => documents,
projects => projects,
};
provider.render_resp("documents/list_documents.html", values)
}
pub async fn create_document_page(
State(provider): State<Provider>,
auth_session: AuthSession<Provider>,
) -> Result<Response, (StatusCode, String)> {
let user = match auth_session.user {
Some(user) => user,
None => return Ok(Redirect::to("/login").into_response()),
};
let mut db = provider.db_pool.get().map_err(internal_error)?;
let projects =
permissions::q::accessible_projects(&mut db, &user.id).map_err(internal_error)?;
let values = context! {
user => user,
projects => projects,
};
provider.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(provider): State<Provider>,
auth_session: AuthSession<Provider>,
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 = provider.db_pool.get().map_err(internal_error)?;
let project_allowed = permissions::q::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::q::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(provider): State<Provider>,
auth_session: AuthSession<Provider>,
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 = provider.db_pool.get().map_err(internal_error)?;
let document_allowed =
permissions::q::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::q::by_id(&mut db, &id.to_string()).map_err(internal_error)?;
let projects =
permissions::q::accessible_projects(&mut db, &user.id).map_err(internal_error)?;
let values = context! {
user => user,
document => document,
projects => projects,
};
provider.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(provider): State<Provider>,
auth_session: AuthSession<Provider>,
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 = provider.db_pool.get().map_err(internal_error)?;
let document_allowed = permissions::q::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::q::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())
}