From ce5f97ac338a25ea9033046a6334022681230fc8 Mon Sep 17 00:00:00 2001 From: aprilthepink Date: Sun, 5 May 2024 17:05:09 +0200 Subject: [PATCH] feat: Refactor migration and follow code --- .../m20240505_002524_user_follow_relation.rs | 15 +++-- src/activities/follow.rs | 63 +++++++++++++++++++ src/activities/mod.rs | 1 + src/entities/mod.rs | 2 +- src/objects/person.rs | 3 +- 5 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 src/activities/follow.rs diff --git a/migration/src/m20240505_002524_user_follow_relation.rs b/migration/src/m20240505_002524_user_follow_relation.rs index f10dd8c..42931bb 100644 --- a/migration/src/m20240505_002524_user_follow_relation.rs +++ b/migration/src/m20240505_002524_user_follow_relation.rs @@ -8,7 +8,6 @@ pub struct Migration; #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager .create_table( Table::create() @@ -21,8 +20,16 @@ impl MigrationTrait for Migration { .auto_increment() .primary_key(), ) - .col(ColumnDef::new(FollowRelation::FolloweeId).string().not_null()) - .col(ColumnDef::new(FollowRelation::FollowerId).string().not_null()) + .col( + ColumnDef::new(FollowRelation::FolloweeId) + .string() + .not_null(), + ) + .col( + ColumnDef::new(FollowRelation::FollowerId) + .string() + .not_null(), + ) .col(ColumnDef::new(FollowRelation::FolloweeHost).string()) .col(ColumnDef::new(FollowRelation::FollowerHost).string()) .col(ColumnDef::new(FollowRelation::FolloweeInbox).string()) @@ -62,5 +69,5 @@ enum FollowRelation { FolloweeHost, FollowerHost, FolloweeInbox, - FollowerInbox + FollowerInbox, } diff --git a/src/activities/follow.rs b/src/activities/follow.rs new file mode 100644 index 0000000..af7dca4 --- /dev/null +++ b/src/activities/follow.rs @@ -0,0 +1,63 @@ +use activitypub_federation::{config::Data, fetch::object_id::ObjectId, traits::ActivityHandler}; +use activitystreams_kinds::activity::FollowType; +use sea_orm::{ActiveModelTrait, Set}; +use serde::{Deserialize, Serialize}; +use url::Url; + +use crate::{ + database::StateHandle, + entities::{follow_relation, prelude::FollowRelation, user}, + DB, +}; + +#[derive(Deserialize, Serialize, Debug)] +pub struct Follow { + actor: ObjectId, + object: ObjectId, + #[serde(rename = "type")] + kind: FollowType, + id: Url, +} + +#[async_trait::async_trait] +impl ActivityHandler for Follow { + type DataType = StateHandle; + type Error = crate::error::Error; + + fn id(&self) -> &Url { + &self.id + } + + fn actor(&self) -> &Url { + self.actor.inner() + } + + async fn verify(&self, data: &Data) -> Result<(), Self::Error> { + Ok(()) + } + + async fn receive(self, data: &Data) -> Result<(), Self::Error> { + let local_user = self.object.dereference(data).await?; + let follower = self.actor.dereference(data).await?; + save_follow(local_user, follower).await?; + Ok(()) + } +} + +async fn save_follow( + local_user: user::Model, + follower: user::Model, +) -> Result<(), crate::error::Error> { + let url = Url::parse(&follower.url)?; + let follow_relation = follow_relation::ActiveModel { + followee_id: Set(local_user.id.clone()), + follower_id: Set(follower.id.clone()), + followee_host: Set(None), + follower_host: Set(Some(url.host_str().unwrap().to_string())), + followee_inbox: Set(Some(local_user.inbox.clone())), + follower_inbox: Set(Some(follower.inbox.clone())), + ..Default::default() + }; + follow_relation.insert(DB.get().unwrap()).await?; + Ok(()) +} diff --git a/src/activities/mod.rs b/src/activities/mod.rs index 7e15ee0..6899c10 100644 --- a/src/activities/mod.rs +++ b/src/activities/mod.rs @@ -1 +1,2 @@ pub mod create_post; +pub mod follow; diff --git a/src/entities/mod.rs b/src/entities/mod.rs index ecd232e..ca0e920 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -2,6 +2,6 @@ pub mod prelude; +pub mod follow_relation; pub mod post; pub mod user; -pub mod follow_relation; diff --git a/src/objects/person.rs b/src/objects/person.rs index 3e7e013..efba22e 100644 --- a/src/objects/person.rs +++ b/src/objects/person.rs @@ -1,5 +1,5 @@ use crate::{ - activities::create_post::CreatePost, + activities::{create_post::CreatePost, follow::Follow}, database::{State, StateHandle}, entities::{self, user}, error::Error, @@ -40,6 +40,7 @@ pub struct DbUser { #[enum_delegate::implement(ActivityHandler)] pub enum PersonAcceptedActivities { CreateNote(CreatePost), + Follow(Follow), } impl DbUser {