]> Untitled Git - lemmy.git/commitdiff
Add pending status for federated follows
authorFelix Ableitner <me@nutomic.com>
Tue, 10 Nov 2020 15:45:10 +0000 (16:45 +0100)
committerFelix Ableitner <me@nutomic.com>
Tue, 10 Nov 2020 15:45:10 +0000 (16:45 +0100)
lemmy_api/src/community.rs
lemmy_api/src/user.rs
lemmy_apub/src/activities/send/user.rs
lemmy_apub/src/inbox/community_inbox.rs
lemmy_apub/src/inbox/user_inbox.rs
lemmy_db/src/community.rs
lemmy_db/src/lib.rs
lemmy_db/src/schema.rs
migrations/2020-11-10-150835_community_follower_pending/down.sql [new file with mode: 0644]
migrations/2020-11-10-150835_community_follower_pending/up.sql [new file with mode: 0644]

index 4c9d769bac6c077ac50fd18beb8ad8de8eb3c33e..a9e130b9b7589751d0f7490cc9e1ffe6dd03b5e4 100644 (file)
@@ -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 {
index 41f77271ac4d5e17ae93e74391044e69dfa2047b..4828888ff377dd80b9da0558dfcdcf713c63e1b6 100644 (file)
@@ -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);
index 39b10ef5fa042e3594d8c42ddb38471794f4f9eb..2839d83bac4d77ec542c4fceaac9ba644ec26369 100644 (file)
@@ -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())
index 6cd4a017ff530526993131ee2f144b40c1926065..137f3fea49ba9f90a542b81dc8f353aad3cbdcdb 100644 (file)
@@ -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.
index 624a2b234ed209db4d5ab132c72ab8f2fe4a5364..f28df83af0eec933bb8b6cab9275045744b5c8c7 100644 (file)
@@ -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(())
 }
index 733f63a15c451db3c0fe2b5d7eee3d40b54a4e6f..4a11557c0687bf6f9079462e1704ce2d3418a243 100644 (file)
@@ -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<CommunityFollowerForm> for CommunityFollower {
@@ -295,6 +297,19 @@ impl Followable<CommunityFollowerForm> for CommunityFollower {
       .values(community_follower_form)
       .get_result::<Self>(conn)
   }
+  fn follow_accepted(conn: &PgConnection, community_id_: i32, user_id_: i32) -> Result<Self, Error>
+  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::<Self>(conn)
+  }
   fn unfollow(
     conn: &PgConnection,
     community_follower_form: &CommunityFollowerForm,
index 40f6c3d26909cde8e57d1bc91a3e7b8594e14f2c..c17bc025404ba258f4d4125198a8203319afb167 100644 (file)
@@ -54,6 +54,9 @@ pub trait Crud<T> {
 
 pub trait Followable<T> {
   fn follow(conn: &PgConnection, form: &T) -> Result<Self, Error>
+  where
+    Self: Sized;
+  fn follow_accepted(conn: &PgConnection, community_id: i32, user_id: i32) -> Result<Self, Error>
   where
     Self: Sized;
   fn unfollow(conn: &PgConnection, form: &T) -> Result<usize, Error>
index ec1e259958efe7d16bb00c34309bcadea29b3805..7eeea9686806412e94fde86561e0b59171758612 100644 (file)
@@ -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 (file)
index 0000000..72cbeaa
--- /dev/null
@@ -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 (file)
index 0000000..599bed6
--- /dev/null
@@ -0,0 +1 @@
+ALTER TABLE community_follower ADD COLUMN pending BOOLEAN DEFAULT FALSE;
\ No newline at end of file