diff --git a/crates/app/src/routes/api/v1/auth/profile.rs b/crates/app/src/routes/api/v1/auth/profile.rs index a18783f..c8d7e7f 100644 --- a/crates/app/src/routes/api/v1/auth/profile.rs +++ b/crates/app/src/routes/api/v1/auth/profile.rs @@ -133,12 +133,13 @@ pub async fn update_user_password_request( None => return Json(Error::NotAllowed.into()), }; - if user.id != id && !user.permissions.check(FinePermission::MANAGE_USERS) { + let can_force = user.permissions.check(FinePermission::MANAGE_USERS); + if user.id != id && !can_force { return Json(Error::NotAllowed.into()); } match data - .update_user_password(id, req.from, req.to, user, false) + .update_user_password(id, req.from, req.to, user, can_force) .await { Ok(_) => Json(ApiReturn { diff --git a/crates/app/src/routes/pages/communities.rs b/crates/app/src/routes/pages/communities.rs index 27ae107..e6949ff 100644 --- a/crates/app/src/routes/pages/communities.rs +++ b/crates/app/src/routes/pages/communities.rs @@ -351,7 +351,7 @@ pub async fn feed_request( .get_posts_by_community(community.id, 12, props.page) .await { - Ok(p) => match data.0.fill_posts(p, &ignore_users).await { + Ok(p) => match data.0.fill_posts(p, &ignore_users, &user).await { Ok(p) => p, Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)), }, @@ -359,7 +359,7 @@ pub async fn feed_request( }; let pinned = match data.0.get_pinned_posts_by_community(community.id).await { - Ok(p) => match data.0.fill_posts(p, &ignore_users).await { + Ok(p) => match data.0.fill_posts(p, &ignore_users, &user).await { Ok(p) => p, Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)), }, @@ -609,7 +609,7 @@ pub async fn post_request( check_user_blocked_or_private!(user, owner, data, jar); // check repost - let reposting = data.0.get_post_reposting(&post, &ignore_users).await; + let reposting = data.0.get_post_reposting(&post, &ignore_users, &user).await; // check question let question = match data.0.get_post_question(&post, &ignore_users).await { @@ -634,7 +634,7 @@ pub async fn post_request( }; let feed = match data.0.get_post_comments(post.id, 12, props.page).await { - Ok(p) => match data.0.fill_posts(p, &ignore_users).await { + Ok(p) => match data.0.fill_posts(p, &ignore_users, &user).await { Ok(p) => p, Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)), }, @@ -730,7 +730,7 @@ pub async fn reposts_request( check_user_blocked_or_private!(user, owner, data, jar); // check repost - let reposting = data.0.get_post_reposting(&post, &ignore_users).await; + let reposting = data.0.get_post_reposting(&post, &ignore_users, &user).await; // check question let question = match data.0.get_post_question(&post, &ignore_users).await { @@ -760,7 +760,7 @@ pub async fn reposts_request( .get_quoting_posts_by_quoting(post.id, 12, props.page) .await { - Ok(p) => match data.0.fill_posts(p, &ignore_users).await { + Ok(p) => match data.0.fill_posts(p, &ignore_users, &user).await { Ok(p) => p, Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)), }, @@ -768,7 +768,7 @@ pub async fn reposts_request( } } else { match data.0.get_reposts_by_quoting(post.id, 12, props.page).await { - Ok(p) => match data.0.fill_posts(p, &ignore_users).await { + Ok(p) => match data.0.fill_posts(p, &ignore_users, &user).await { Ok(p) => p, Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)), }, @@ -882,7 +882,10 @@ pub async fn likes_request( } // check repost - let reposting = data.0.get_post_reposting(&post, &ignore_users).await; + let reposting = data + .0 + .get_post_reposting(&post, &ignore_users, &Some(user.clone())) + .await; // check question let question = match data.0.get_post_question(&post, &ignore_users).await { @@ -1095,7 +1098,7 @@ pub async fn question_request( .get_posts_by_question(question.id, 12, props.page) .await { - Ok(p) => match data.0.fill_posts(p, &ignore_users).await { + Ok(p) => match data.0.fill_posts(p, &ignore_users, &user).await { Ok(p) => p, Err(e) => return Err(Html(render_error(e, &jar, &data, &user).await)), }, diff --git a/crates/app/src/routes/pages/misc.rs b/crates/app/src/routes/pages/misc.rs index d018954..1edc42b 100644 --- a/crates/app/src/routes/pages/misc.rs +++ b/crates/app/src/routes/pages/misc.rs @@ -38,7 +38,11 @@ pub async fn index_request( // all timeline for unauthenticated users // i'm only changing this for stripe let list = match data.0.get_latest_posts(12, req.page).await { - Ok(l) => match data.0.fill_posts_with_community(l, 0, &Vec::new()).await { + Ok(l) => match data + .0 + .fill_posts_with_community(l, 0, &Vec::new(), &None) + .await + { Ok(l) => l, Err(e) => return Html(render_error(e, &jar, &data, &None).await), }, @@ -64,7 +68,7 @@ pub async fn index_request( { Ok(l) => match data .0 - .fill_posts_with_community(l, user.id, &ignore_users) + .fill_posts_with_community(l, user.id, &ignore_users, &Some(user.clone())) .await { Ok(l) => l, @@ -103,6 +107,7 @@ pub async fn popular_request( l, if let Some(ref ua) = user { ua.id } else { 0 }, &ignore_users, + &user, ) .await { @@ -145,7 +150,7 @@ pub async fn following_request( { Ok(l) => match data .0 - .fill_posts_with_community(l, user.id, &ignore_users) + .fill_posts_with_community(l, user.id, &ignore_users, &Some(user.clone())) .await { Ok(l) => l, @@ -186,6 +191,7 @@ pub async fn all_request( l, if let Some(ref ua) = user { ua.id } else { 0 }, &ignore_users, + &user, ) .await { diff --git a/crates/app/src/routes/pages/profile.rs b/crates/app/src/routes/pages/profile.rs index c0c7530..f5c3d4e 100644 --- a/crates/app/src/routes/pages/profile.rs +++ b/crates/app/src/routes/pages/profile.rs @@ -237,6 +237,7 @@ pub async fn posts_request( p, if let Some(ref ua) = user { ua.id } else { 0 }, &ignore_users, + &user, ) .await { @@ -257,6 +258,7 @@ pub async fn posts_request( p, if let Some(ref ua) = user { ua.id } else { 0 }, &ignore_users, + &user, ) .await { @@ -275,6 +277,7 @@ pub async fn posts_request( p, if let Some(ref ua) = user { ua.id } else { 0 }, &ignore_users, + &user, ) .await { diff --git a/crates/app/src/routes/pages/stacks.rs b/crates/app/src/routes/pages/stacks.rs index bb19b00..e103636 100644 --- a/crates/app/src/routes/pages/stacks.rs +++ b/crates/app/src/routes/pages/stacks.rs @@ -68,7 +68,14 @@ pub async fn posts_request( let ignore_users = data.0.get_userblocks_receivers(user.id).await; let list = match data .0 - .get_stack_posts(user.id, stack.id, 12, req.page, &ignore_users) + .get_stack_posts( + user.id, + stack.id, + 12, + req.page, + &ignore_users, + &Some(user.clone()), + ) .await { Ok(l) => l, diff --git a/crates/core/src/database/auth.rs b/crates/core/src/database/auth.rs index 9c19af9..e98a5d1 100644 --- a/crates/core/src/database/auth.rs +++ b/crates/core/src/database/auth.rs @@ -387,7 +387,7 @@ impl DataManager { force: bool, ) -> Result<()> { // verify password - if (hash_salted(from.clone(), user.salt.clone()) != user.password) && !force { + if !user.check_password(from.clone()) && !force { return Err(Error::MiscError("Password does not match".to_string())); } diff --git a/crates/core/src/database/posts.rs b/crates/core/src/database/posts.rs index 6fd107a..d46ee3e 100644 --- a/crates/core/src/database/posts.rs +++ b/crates/core/src/database/posts.rs @@ -83,6 +83,7 @@ impl DataManager { &self, post: &Post, ignore_users: &[usize], + user: &Option, ) -> Option<(User, Post)> { if let Some(ref repost) = post.context.repost { if let Some(reposting) = repost.reposting { @@ -95,6 +96,30 @@ impl DataManager { return None; } + // check private profile settings + let owner = match self.get_user_by_id(x.owner).await { + Ok(ua) => ua, + Err(_) => return None, + }; + + if let Some(ua) = user { + // TODO: maybe check community membership to see if we can MANAGE_POSTS in community + if owner.settings.private_profile + && owner.id != ua.id + && !ua.permissions.check(FinePermission::MANAGE_POSTS) + { + if self + .get_userfollow_by_initiator_receiver(owner.id, ua.id) + .await + .is_err() + { + // owner isn't following us, we aren't the owner, AND we don't have MANAGE_POSTS permission + return None; + } + } + } + + // ... x.mark_as_repost(); Some(( match self.get_user_by_id(x.owner).await { @@ -141,6 +166,7 @@ impl DataManager { &self, posts: Vec, ignore_users: &[usize], + user: &Option, ) -> Result, Option<(Question, User)>)>> { let mut out: Vec<(Post, User, Option<(User, Post)>, Option<(Question, User)>)> = Vec::new(); @@ -152,20 +178,20 @@ impl DataManager { continue; } - if let Some(user) = users.get(&owner) { + if let Some(ua) = users.get(&owner) { out.push(( post.clone(), - user.clone(), - self.get_post_reposting(&post, ignore_users).await, + ua.clone(), + self.get_post_reposting(&post, ignore_users, user).await, self.get_post_question(&post, ignore_users).await?, )); } else { - let user = self.get_user_by_id(owner).await?; - users.insert(owner, user.clone()); + let ua = self.get_user_by_id(owner).await?; + users.insert(owner, ua.clone()); out.push(( post.clone(), - user, - self.get_post_reposting(&post, ignore_users).await, + ua, + self.get_post_reposting(&post, ignore_users, user).await, self.get_post_question(&post, ignore_users).await?, )); } @@ -180,6 +206,7 @@ impl DataManager { posts: Vec, user_id: usize, ignore_users: &[usize], + user: &Option, ) -> Result< Vec<( Post, @@ -209,51 +236,51 @@ impl DataManager { let community = post.community; - if let Some((user, community)) = seen_before.get(&(owner, community)) { + if let Some((ua, community)) = seen_before.get(&(owner, community)) { out.push(( post.clone(), - user.clone(), + ua.clone(), community.to_owned(), - self.get_post_reposting(&post, ignore_users).await, + self.get_post_reposting(&post, ignore_users, user).await, self.get_post_question(&post, ignore_users).await?, )); } else { - let user = self.get_user_by_id(owner).await?; + let ua = self.get_user_by_id(owner).await?; // check relationship - if user.settings.private_profile && user.id != user_id { + if ua.settings.private_profile && ua.id != user_id { if user_id == 0 { continue; } - if let Some(is_following) = seen_user_follow_statuses.get(&(user.id, user_id)) { - if !is_following && (user.id != user_id) { + if let Some(is_following) = seen_user_follow_statuses.get(&(ua.id, user_id)) { + if !is_following && (ua.id != user_id) { // post owner is not following us continue; } } else { if self - .get_userfollow_by_initiator_receiver(user.id, user_id) + .get_userfollow_by_initiator_receiver(ua.id, user_id) .await .is_err() { // post owner is not following us - seen_user_follow_statuses.insert((user.id, user_id), false); + seen_user_follow_statuses.insert((ua.id, user_id), false); continue; } - seen_user_follow_statuses.insert((user.id, user_id), true); + seen_user_follow_statuses.insert((ua.id, user_id), true); } } // ... let community = self.get_community_by_id(community).await?; - seen_before.insert((owner, community.id), (user.clone(), community.clone())); + seen_before.insert((owner, community.id), (ua.clone(), community.clone())); out.push(( post.clone(), - user, + ua, community, - self.get_post_reposting(&post, ignore_users).await, + self.get_post_reposting(&post, ignore_users, user).await, self.get_post_question(&post, ignore_users).await?, )); } diff --git a/crates/core/src/database/stacks.rs b/crates/core/src/database/stacks.rs index 162adad..6eac313 100644 --- a/crates/core/src/database/stacks.rs +++ b/crates/core/src/database/stacks.rs @@ -43,6 +43,7 @@ impl DataManager { batch: usize, page: usize, ignore_users: &Vec, + user: &Option, ) -> Result< Vec<( Post, @@ -61,6 +62,7 @@ impl DataManager { .await?, as_user_id, ignore_users, + user, ) .await? } @@ -73,6 +75,7 @@ impl DataManager { self.get_latest_posts(batch, page).await?, as_user_id, &ignore_users, + user, ) .await? } @@ -81,6 +84,7 @@ impl DataManager { self.get_popular_posts(batch, page, 604_800_000).await?, as_user_id, &ignore_users, + user, ) .await? }