fix: respect private profile and check blocks on profile

This commit is contained in:
trisua 2025-09-02 19:06:53 -04:00
parent 2bd23f8214
commit 0b242ac5f0
4 changed files with 50 additions and 3 deletions

View file

@ -247,6 +247,7 @@ video {
user-select: none;
appearance: none;
overflow: hidden;
position: relative;
}
.button:not(nav *, .tab, .dropdown .inner *, .square) {

View file

@ -2,7 +2,7 @@
(text "{% if user -%}")
(meta ("http-equiv" "refresh") ("content" "0; /chats"))
(text "{% else %}")
(meta ("http-equiv" "refresh") ("content" "0; {{ config.service_hosts.tetratto|safe }}"))
(meta ("http-equiv" "refresh") ("content" "0; /login"))
(text "{%- endif %}")
(text "{% endblock %} {% block body %}")
(div

View file

@ -64,6 +64,10 @@
("href" "{{ config.service_hosts.tetratto }}/auth/register")
(text "sign up"))
(text "{%- else -%}")
(a
("class" "button")
("href" "/@{{ user.username }}")
(text "my profile"))
(a
("class" "button")
("href" "{{ config.service_hosts.tetratto }}/settings")

View file

@ -1,4 +1,6 @@
use crate::{State, config::Config, get_user_from_token, routes::default_context};
use crate::{
State, config::Config, database::DataManager, get_user_from_token, routes::default_context,
};
use axum::{
Extension,
extract::{Path, Query},
@ -7,7 +9,7 @@ use axum::{
use axum_extra::extract::CookieJar;
use serde::Deserialize;
use tera::Tera;
use tetratto_core::model::{Error, auth::User};
use tetratto_core::model::{Error, Result, auth::User};
pub async fn render_error(
e: Error,
@ -55,6 +57,38 @@ pub async fn login_request(jar: CookieJar, Extension(data): Extension<State>) ->
)
}
async fn check_user_blocked_or_private(
user: &Option<User>,
other_user: &User,
data: &DataManager,
) -> Result<()> {
if let Some(ua) = user {
if other_user.settings.private_profile
&& data
.2
.get_userfollow_by_initiator_receiver(other_user.id, ua.id)
.await
.is_err()
{
// private profile and other_user isn't following user
return Err(Error::NotAllowed);
} else if data
.2
.get_userblock_by_initiator_receiver(other_user.id, ua.id)
.await
.is_ok()
{
// blocked
return Err(Error::NotAllowed);
}
} else if other_user.settings.private_profile {
// private profile and we're not signed in
return Err(Error::NotAllowed);
}
Ok(())
}
#[derive(Deserialize)]
pub struct ProfileQuery {
#[serde(default)]
@ -90,6 +124,10 @@ pub async fn profile_request(
false
};
if !is_self && let Err(e) = check_user_blocked_or_private(&user, &profile, data).await {
return Err(render_error(e, tera, data.0.0.clone(), user).await);
}
let mut ctx = default_context(&data.0.0, &build_code, &user);
ctx.insert("profile", &profile);
@ -119,6 +157,10 @@ pub async fn confirm_dm_request(
}
};
if let Err(e) = check_user_blocked_or_private(&user, &profile, data).await {
return Err(render_error(e, tera, data.0.0.clone(), user).await);
}
let mut ctx = default_context(&data.0.0, &build_code, &user);
ctx.insert("profile", &profile);
Ok(Html(tera.render("confirm_dm.lisp", &ctx).unwrap()))