Don't show subscribers-only posts if viewer is not mentioned

This commit is contained in:
silverpill 2022-09-27 22:18:58 +00:00
parent e7488112a9
commit 0ce0cd15c3
2 changed files with 18 additions and 22 deletions

View file

@ -104,13 +104,8 @@ pub async fn can_view_post(
}, },
Visibility::Subscribers => { Visibility::Subscribers => {
if let Some(user) = user { if let Some(user) = user {
let is_subscriber = has_relationship( // Can view only if mentioned
db_client, is_mentioned(user)
&user.id,
&post.author.id,
RelationshipType::Subscription,
).await?;
is_subscriber || is_mentioned(user)
} else { } else {
false false
} }
@ -218,6 +213,7 @@ mod tests {
let post = Post { let post = Post {
author: author.profile, author: author.profile,
visibility: Visibility::Subscribers, visibility: Visibility::Subscribers,
mentions: vec![subscriber.profile.clone()],
..Default::default() ..Default::default()
}; };
assert_eq!( assert_eq!(

View file

@ -252,6 +252,7 @@ fn build_visibility_filter() -> String {
"( "(
post.author_id = $current_user_id post.author_id = $current_user_id
OR post.visibility = {visibility_public} OR post.visibility = {visibility_public}
-- covers direct messages and subscribers-only posts
OR EXISTS ( OR EXISTS (
SELECT 1 FROM mention SELECT 1 FROM mention
WHERE post_id = post.id AND profile_id = $current_user_id WHERE post_id = post.id AND profile_id = $current_user_id
@ -263,20 +264,10 @@ fn build_visibility_filter() -> String {
AND target_id = post.author_id AND target_id = post.author_id
AND relationship_type = {relationship_follow} AND relationship_type = {relationship_follow}
) )
-- TODO: remove and rely on mentions instead
OR post.visibility = {visibility_subscribers} AND EXISTS (
SELECT 1 FROM relationship
WHERE
source_id = $current_user_id
AND target_id = post.author_id
AND relationship_type = {relationship_subscription}
)
)", )",
visibility_public=i16::from(&Visibility::Public), visibility_public=i16::from(&Visibility::Public),
visibility_followers=i16::from(&Visibility::Followers), visibility_followers=i16::from(&Visibility::Followers),
visibility_subscribers=i16::from(&Visibility::Subscribers),
relationship_follow=i16::from(&RelationshipType::Follow), relationship_follow=i16::from(&RelationshipType::Follow),
relationship_subscription=i16::from(&RelationshipType::Subscription),
) )
} }
@ -1324,7 +1315,7 @@ mod tests {
..Default::default() ..Default::default()
}; };
let post_10 = create_post(db_client, &user_2.id, post_data_10).await.unwrap(); let post_10 = create_post(db_client, &user_2.id, post_data_10).await.unwrap();
// Subscribers-only post by subscription // Subscribers-only post by subscription (without mention)
let user_data_3 = UserCreateData { let user_data_3 = UserCreateData {
username: "subscription".to_string(), username: "subscription".to_string(),
..Default::default() ..Default::default()
@ -1337,6 +1328,14 @@ mod tests {
..Default::default() ..Default::default()
}; };
let post_11 = create_post(db_client, &user_3.id, post_data_11).await.unwrap(); let post_11 = create_post(db_client, &user_3.id, post_data_11).await.unwrap();
// Subscribers-only post by subscription (with mention)
let post_data_12 = PostCreateData {
content: "subscribers only".to_string(),
visibility: Visibility::Subscribers,
mentions: vec![current_user.id],
..Default::default()
};
let post_12 = create_post(db_client, &user_3.id, post_data_12).await.unwrap();
// Repost from followed user if hiding reposts // Repost from followed user if hiding reposts
let user_data_4 = UserCreateData { let user_data_4 = UserCreateData {
username: "hide reposts".to_string(), username: "hide reposts".to_string(),
@ -1345,11 +1344,11 @@ mod tests {
let user_4 = create_user(db_client, user_data_4).await.unwrap(); let user_4 = create_user(db_client, user_data_4).await.unwrap();
follow(db_client, &current_user.id, &user_4.id).await.unwrap(); follow(db_client, &current_user.id, &user_4.id).await.unwrap();
hide_reposts(db_client, &current_user.id, &user_4.id).await.unwrap(); hide_reposts(db_client, &current_user.id, &user_4.id).await.unwrap();
let post_data_12 = PostCreateData { let post_data_13 = PostCreateData {
repost_of_id: Some(post_3.id), repost_of_id: Some(post_3.id),
..Default::default() ..Default::default()
}; };
let post_12 = create_post(db_client, &user_4.id, post_data_12).await.unwrap(); let post_13 = create_post(db_client, &user_4.id, post_data_13).await.unwrap();
let timeline = get_home_timeline(db_client, &current_user.id, None, 20).await.unwrap(); let timeline = get_home_timeline(db_client, &current_user.id, None, 20).await.unwrap();
assert_eq!(timeline.len(), 7); assert_eq!(timeline.len(), 7);
@ -1363,8 +1362,9 @@ mod tests {
assert_eq!(timeline.iter().any(|post| post.id == post_8.id), false); assert_eq!(timeline.iter().any(|post| post.id == post_8.id), false);
assert_eq!(timeline.iter().any(|post| post.id == post_9.id), true); assert_eq!(timeline.iter().any(|post| post.id == post_9.id), true);
assert_eq!(timeline.iter().any(|post| post.id == post_10.id), false); assert_eq!(timeline.iter().any(|post| post.id == post_10.id), false);
assert_eq!(timeline.iter().any(|post| post.id == post_11.id), true); assert_eq!(timeline.iter().any(|post| post.id == post_11.id), false);
assert_eq!(timeline.iter().any(|post| post.id == post_12.id), false); assert_eq!(timeline.iter().any(|post| post.id == post_12.id), true);
assert_eq!(timeline.iter().any(|post| post.id == post_13.id), false);
} }
#[tokio::test] #[tokio::test]