From: Felix Ableitner Date: Tue, 10 Nov 2020 15:45:10 +0000 (+0100) Subject: Add pending status for federated follows X-Git-Url: http://these/git/%7B%60%24%7BwebArchiveUrl%7D/%22%7B%7D/%24%7B%60data:application/%22https:/hacktivis.me/%7BpictrsAvatarThumbnail%28this.props.site.site.icon%29%7D?a=commitdiff_plain;h=06e82fe7619ced71d59bc712e3e6bc6f2c04da30;p=lemmy.git Add pending status for federated follows --- diff --git a/lemmy_api/src/community.rs b/lemmy_api/src/community.rs index 4c9d769b..a9e130b9 100644 --- a/lemmy_api/src/community.rs +++ b/lemmy_api/src/community.rs @@ -188,6 +188,7 @@ impl Perform for CreateCommunity { let community_follower_form = CommunityFollowerForm { community_id: inserted_community.id, user_id: user.id, + pending: false, }; let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form); @@ -479,6 +480,7 @@ impl Perform for FollowCommunity { let community_follower_form = CommunityFollowerForm { community_id: data.community_id, user_id: user.id, + pending: false, }; if community.local { diff --git a/lemmy_api/src/user.rs b/lemmy_api/src/user.rs index 41f77271..4828888f 100644 --- a/lemmy_api/src/user.rs +++ b/lemmy_api/src/user.rs @@ -251,6 +251,7 @@ impl Perform for Register { let community_follower_form = CommunityFollowerForm { community_id: main_community.id, user_id: inserted_user.id, + pending: false, }; let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form); diff --git a/lemmy_apub/src/activities/send/user.rs b/lemmy_apub/src/activities/send/user.rs index 39b10ef5..2839d83b 100644 --- a/lemmy_apub/src/activities/send/user.rs +++ b/lemmy_apub/src/activities/send/user.rs @@ -12,7 +12,12 @@ use activitystreams::{ base::{AnyBase, BaseExt, ExtendsExt}, object::ObjectExt, }; -use lemmy_db::{community::Community, user::User_, DbPool}; +use lemmy_db::{ + community::{Community, CommunityFollower, CommunityFollowerForm}, + user::User_, + DbPool, + Followable, +}; use lemmy_structs::blocking; use lemmy_utils::LemmyError; use lemmy_websocket::LemmyContext; @@ -44,6 +49,16 @@ impl ActorType for User_ { }) .await??; + let community_follower_form = CommunityFollowerForm { + community_id: community.id, + user_id: self.id, + pending: true, + }; + blocking(&context.pool(), move |conn| { + CommunityFollower::follow(conn, &community_follower_form).ok() + }) + .await?; + let mut follow = Follow::new(self.actor_id.to_owned(), community.actor_id()?); follow .set_context(activitystreams::context()) diff --git a/lemmy_apub/src/inbox/community_inbox.rs b/lemmy_apub/src/inbox/community_inbox.rs index 6cd4a017..137f3fea 100644 --- a/lemmy_apub/src/inbox/community_inbox.rs +++ b/lemmy_apub/src/inbox/community_inbox.rs @@ -191,6 +191,7 @@ async fn handle_follow( let community_follower_form = CommunityFollowerForm { community_id: community.id, user_id: user.id, + pending: false, }; // This will fail if they're already a follower, but ignore the error. @@ -245,6 +246,7 @@ async fn handle_undo_follow( let community_follower_form = CommunityFollowerForm { community_id: community.id, user_id: user.id, + pending: false, }; // This will fail if they aren't a follower, but ignore the error. diff --git a/lemmy_apub/src/inbox/user_inbox.rs b/lemmy_apub/src/inbox/user_inbox.rs index 624a2b23..f28df83a 100644 --- a/lemmy_apub/src/inbox/user_inbox.rs +++ b/lemmy_apub/src/inbox/user_inbox.rs @@ -46,7 +46,7 @@ use actix_web::{web, HttpRequest, HttpResponse}; use anyhow::{anyhow, Context}; use diesel::NotFound; use lemmy_db::{ - community::{Community, CommunityFollower, CommunityFollowerForm}, + community::{Community, CommunityFollower}, private_message::PrivateMessage, user::User_, Followable, @@ -173,8 +173,6 @@ async fn receive_accept( let accept = Accept::from_any_base(activity)?.context(location_info!())?; verify_activity_domains_valid(&accept, &actor.actor_id()?, false)?; - // TODO: we should check that we actually sent this activity, because the remote instance - // could just put a fake Follow let object = accept.object().to_owned().one().context(location_info!())?; let follow = Follow::from_any_base(object)?.context(location_info!())?; verify_activity_domains_valid(&follow, &user.actor_id()?, false)?; @@ -188,17 +186,13 @@ async fn receive_accept( let community = get_or_fetch_and_upsert_community(&community_uri, context, request_counter).await?; - // Now you need to add this to the community follower - let community_follower_form = CommunityFollowerForm { - community_id: community.id, - user_id: user.id, - }; - - // This will fail if they're already a follower + let community_id = community.id; + let user_id = user.id; + // This will throw an error if no follow was requested blocking(&context.pool(), move |conn| { - CommunityFollower::follow(conn, &community_follower_form).ok() + CommunityFollower::follow_accepted(conn, community_id, user_id) }) - .await?; + .await??; Ok(()) } diff --git a/lemmy_db/src/community.rs b/lemmy_db/src/community.rs index 733f63a1..4a11557c 100644 --- a/lemmy_db/src/community.rs +++ b/lemmy_db/src/community.rs @@ -275,6 +275,7 @@ pub struct CommunityFollower { pub id: i32, pub community_id: i32, pub user_id: i32, + pub pending: bool, pub published: chrono::NaiveDateTime, } @@ -283,6 +284,7 @@ pub struct CommunityFollower { pub struct CommunityFollowerForm { pub community_id: i32, pub user_id: i32, + pub pending: bool, } impl Followable for CommunityFollower { @@ -295,6 +297,19 @@ impl Followable for CommunityFollower { .values(community_follower_form) .get_result::(conn) } + fn follow_accepted(conn: &PgConnection, community_id_: i32, user_id_: i32) -> Result + where + Self: Sized, + { + use crate::schema::community_follower::dsl::*; + diesel::update( + community_follower + .filter(community_id.eq(community_id_)) + .filter(user_id.eq(user_id_)), + ) + .set(pending.eq(true)) + .get_result::(conn) + } fn unfollow( conn: &PgConnection, community_follower_form: &CommunityFollowerForm, diff --git a/lemmy_db/src/lib.rs b/lemmy_db/src/lib.rs index 40f6c3d2..c17bc025 100644 --- a/lemmy_db/src/lib.rs +++ b/lemmy_db/src/lib.rs @@ -54,6 +54,9 @@ pub trait Crud { pub trait Followable { fn follow(conn: &PgConnection, form: &T) -> Result + where + Self: Sized; + fn follow_accepted(conn: &PgConnection, community_id: i32, user_id: i32) -> Result where Self: Sized; fn unfollow(conn: &PgConnection, form: &T) -> Result diff --git a/lemmy_db/src/schema.rs b/lemmy_db/src/schema.rs index ec1e2599..7eeea968 100644 --- a/lemmy_db/src/schema.rs +++ b/lemmy_db/src/schema.rs @@ -149,6 +149,7 @@ table! { id -> Int4, community_id -> Int4, user_id -> Int4, + pending -> Bool, published -> Timestamp, } } diff --git a/migrations/2020-11-10-150835_community_follower_pending/down.sql b/migrations/2020-11-10-150835_community_follower_pending/down.sql new file mode 100644 index 00000000..72cbeaa3 --- /dev/null +++ b/migrations/2020-11-10-150835_community_follower_pending/down.sql @@ -0,0 +1 @@ +ALTER TABLE community_follower DROP COLUMN pending; \ No newline at end of file diff --git a/migrations/2020-11-10-150835_community_follower_pending/up.sql b/migrations/2020-11-10-150835_community_follower_pending/up.sql new file mode 100644 index 00000000..599bed62 --- /dev/null +++ b/migrations/2020-11-10-150835_community_follower_pending/up.sql @@ -0,0 +1 @@ +ALTER TABLE community_follower ADD COLUMN pending BOOLEAN DEFAULT FALSE; \ No newline at end of file