181 lines
5.1 KiB
Rust
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())
|
|
}
|