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