294 lines
8.3 KiB
Rust
294 lines
8.3 KiB
Rust
use axum::{
|
|
extract::{Path, Query},
|
|
response::{Html, IntoResponse, Redirect},
|
|
Extension,
|
|
};
|
|
use axum_extra::extract::CookieJar;
|
|
use crate::{
|
|
assets::initial_context,
|
|
check_user_blocked_or_private, get_lang, get_user_from_token,
|
|
routes::pages::{render_error, JournalsAppQuery},
|
|
State,
|
|
};
|
|
use tetratto_core::model::{journals::JournalPrivacyPermission, Error};
|
|
|
|
pub async fn redirect_request() -> impl IntoResponse {
|
|
Redirect::to("/journals/0/0")
|
|
}
|
|
|
|
/// `/journals/{journal}/{note}`
|
|
pub async fn app_request(
|
|
jar: CookieJar,
|
|
Extension(data): Extension<State>,
|
|
Path((selected_journal, selected_note)): Path<(usize, usize)>,
|
|
Query(props): Query<JournalsAppQuery>,
|
|
) -> impl IntoResponse {
|
|
let data = data.read().await;
|
|
let user = match get_user_from_token!(jar, data.0) {
|
|
Some(ua) => ua,
|
|
None => {
|
|
return Err(Html(
|
|
render_error(Error::NotAllowed, &jar, &data, &None).await,
|
|
));
|
|
}
|
|
};
|
|
|
|
let journals = match data.0.get_journals_by_user(user.id).await {
|
|
Ok(p) => Some(p),
|
|
Err(e) => {
|
|
return Err(Html(
|
|
render_error(e, &jar, &data, &Some(user.to_owned())).await,
|
|
));
|
|
}
|
|
};
|
|
|
|
let notes = match data.0.get_notes_by_journal(selected_journal).await {
|
|
Ok(p) => Some(p),
|
|
Err(e) => {
|
|
return Err(Html(render_error(e, &jar, &data, &Some(user)).await));
|
|
}
|
|
};
|
|
|
|
// get journal and check privacy settings
|
|
let journal = if selected_journal != 0 {
|
|
match data.0.get_journal_by_id(selected_journal).await {
|
|
Ok(p) => Some(p),
|
|
Err(e) => {
|
|
return Err(Html(render_error(e, &jar, &data, &Some(user)).await));
|
|
}
|
|
}
|
|
} else {
|
|
None
|
|
};
|
|
|
|
if let Some(ref j) = journal {
|
|
// if we're not the owner, we shouldn't be viewing this journal from this endpoint
|
|
if user.id != j.owner {
|
|
return Err(Html(
|
|
render_error(Error::NotAllowed, &jar, &data, &Some(user.to_owned())).await,
|
|
));
|
|
}
|
|
}
|
|
|
|
// ...
|
|
let note = if selected_note != 0 {
|
|
match data.0.get_note_by_id(selected_note).await {
|
|
Ok(p) => Some(p),
|
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &Some(user)).await)),
|
|
}
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let lang = get_lang!(jar, data.0);
|
|
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
|
|
|
context.insert("selected_journal", &selected_journal);
|
|
context.insert("selected_note", &selected_note);
|
|
|
|
context.insert("journal", &journal);
|
|
context.insert("note", ¬e);
|
|
|
|
context.insert("journals", &journals);
|
|
context.insert("notes", ¬es);
|
|
|
|
context.insert("view_mode", &props.view);
|
|
context.insert("is_editor", &true);
|
|
|
|
// return
|
|
Ok(Html(data.1.render("journals/app.html", &context).unwrap()))
|
|
}
|
|
|
|
/// `/@{owner}/{journal}/{note}`
|
|
pub async fn view_request(
|
|
jar: CookieJar,
|
|
Extension(data): Extension<State>,
|
|
Path((owner, selected_journal, mut selected_note)): Path<(String, String, String)>,
|
|
) -> impl IntoResponse {
|
|
let data = data.read().await;
|
|
let user = match get_user_from_token!(jar, data.0) {
|
|
Some(ua) => Some(ua),
|
|
None => None,
|
|
};
|
|
|
|
if selected_note == "index" {
|
|
selected_note = String::new();
|
|
}
|
|
|
|
// if we don't have a selected journal, we shouldn't be here probably
|
|
if selected_journal.is_empty() | (selected_note == "journal.css") {
|
|
return Err(Html(
|
|
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
|
));
|
|
}
|
|
|
|
// get owner
|
|
let owner = match data.0.get_user_by_username(&owner).await {
|
|
Ok(ua) => ua,
|
|
Err(e) => {
|
|
return Err(Html(render_error(e, &jar, &data, &user).await));
|
|
}
|
|
};
|
|
|
|
check_user_blocked_or_private!(user, owner, data, jar);
|
|
|
|
// get journal and check privacy settings
|
|
let journal = match data
|
|
.0
|
|
.get_journal_by_owner_title(owner.id, &selected_journal)
|
|
.await
|
|
{
|
|
Ok(p) => p,
|
|
Err(e) => {
|
|
return Err(Html(render_error(e, &jar, &data, &user).await));
|
|
}
|
|
};
|
|
|
|
if journal.privacy == JournalPrivacyPermission::Private {
|
|
if let Some(ref user) = user {
|
|
if user.id != journal.owner {
|
|
return Err(Html(
|
|
render_error(Error::NotAllowed, &jar, &data, &Some(user.to_owned())).await,
|
|
));
|
|
}
|
|
} else {
|
|
return Err(Html(
|
|
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
|
));
|
|
}
|
|
}
|
|
|
|
// ...
|
|
let note = if !selected_note.is_empty() {
|
|
match data
|
|
.0
|
|
.get_note_by_journal_title(journal.id, &selected_note)
|
|
.await
|
|
{
|
|
Ok(p) => Some(p),
|
|
Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)),
|
|
}
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let lang = get_lang!(jar, data.0);
|
|
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
|
|
|
if selected_journal.is_empty() {
|
|
context.insert("selected_journal", &0);
|
|
} else {
|
|
context.insert("selected_journal", &selected_journal);
|
|
}
|
|
|
|
if selected_note.is_empty() {
|
|
context.insert("selected_note", &0);
|
|
} else {
|
|
context.insert("selected_note", &selected_note);
|
|
}
|
|
|
|
context.insert("journal", &journal);
|
|
context.insert("note", ¬e);
|
|
|
|
context.insert("owner", &owner);
|
|
context.insert::<[i8; 0], &str>("notes", &[]);
|
|
|
|
context.insert("view_mode", &true);
|
|
context.insert("is_editor", &false);
|
|
|
|
// return
|
|
Ok(Html(data.1.render("journals/app.html", &context).unwrap()))
|
|
}
|
|
|
|
/// `/@{owner}/{journal}`
|
|
pub async fn index_view_request(
|
|
jar: CookieJar,
|
|
Extension(data): Extension<State>,
|
|
Path((owner, selected_journal)): Path<(String, String)>,
|
|
Query(props): Query<JournalsAppQuery>,
|
|
) -> impl IntoResponse {
|
|
let data = data.read().await;
|
|
let user = match get_user_from_token!(jar, data.0) {
|
|
Some(ua) => Some(ua),
|
|
None => None,
|
|
};
|
|
|
|
// get owner
|
|
let owner = match data.0.get_user_by_username(&owner).await {
|
|
Ok(ua) => ua,
|
|
Err(e) => {
|
|
return Err(Html(render_error(e, &jar, &data, &user).await));
|
|
}
|
|
};
|
|
|
|
check_user_blocked_or_private!(user, owner, data, jar);
|
|
|
|
// get journal and check privacy settings
|
|
let journal = match data
|
|
.0
|
|
.get_journal_by_owner_title(owner.id, &selected_journal)
|
|
.await
|
|
{
|
|
Ok(p) => p,
|
|
Err(e) => {
|
|
return Err(Html(render_error(e, &jar, &data, &user).await));
|
|
}
|
|
};
|
|
|
|
if journal.privacy == JournalPrivacyPermission::Private {
|
|
if let Some(ref user) = user {
|
|
if user.id != journal.owner {
|
|
return Err(Html(
|
|
render_error(Error::NotAllowed, &jar, &data, &Some(user.to_owned())).await,
|
|
));
|
|
}
|
|
} else {
|
|
return Err(Html(
|
|
render_error(Error::NotAllowed, &jar, &data, &user).await,
|
|
));
|
|
}
|
|
}
|
|
|
|
// ...
|
|
let notes = if props.tag.is_empty() {
|
|
match data.0.get_notes_by_journal(journal.id).await {
|
|
Ok(p) => Some(p),
|
|
Err(e) => {
|
|
return Err(Html(render_error(e, &jar, &data, &user).await));
|
|
}
|
|
}
|
|
} else {
|
|
match data
|
|
.0
|
|
.get_notes_by_journal_tag(journal.id, &props.tag)
|
|
.await
|
|
{
|
|
Ok(p) => Some(p),
|
|
Err(e) => {
|
|
return Err(Html(render_error(e, &jar, &data, &user).await));
|
|
}
|
|
}
|
|
};
|
|
|
|
let lang = get_lang!(jar, data.0);
|
|
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
|
|
|
if selected_journal.is_empty() {
|
|
context.insert("selected_journal", &0);
|
|
} else {
|
|
context.insert("selected_journal", &selected_journal);
|
|
}
|
|
|
|
context.insert("selected_note", &0);
|
|
context.insert("journal", &journal);
|
|
|
|
context.insert("owner", &owner);
|
|
context.insert("notes", ¬es);
|
|
|
|
context.insert("view_mode", &true);
|
|
context.insert("is_editor", &false);
|
|
context.insert("tag", &props.tag);
|
|
|
|
// return
|
|
Ok(Html(data.1.render("journals/app.html", &context).unwrap()))
|
|
}
|