2024-05-05 18:18:39 +02:00
|
|
|
use activitypub_federation::{
|
|
|
|
|
activity_sending::SendActivityTask,
|
|
|
|
|
config::Data,
|
|
|
|
|
fetch::object_id::ObjectId,
|
|
|
|
|
protocol::context::WithContext,
|
|
|
|
|
traits::{ActivityHandler, Actor, Object},
|
|
|
|
|
};
|
|
|
|
|
use activitystreams_kinds::activity::{AcceptType, FollowType};
|
2024-08-03 03:49:07 +02:00
|
|
|
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityOrSelect, EntityTrait, QueryFilter, Set};
|
2024-05-05 17:05:09 +02:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use url::Url;
|
|
|
|
|
|
|
|
|
|
use crate::{
|
2024-08-03 15:30:34 +02:00
|
|
|
database::StateHandle,
|
|
|
|
|
entities::{
|
2024-08-03 03:49:07 +02:00
|
|
|
follow_relation::{self, Entity},
|
|
|
|
|
post, prelude, user,
|
2024-08-03 15:30:34 +02:00
|
|
|
},
|
|
|
|
|
error,
|
|
|
|
|
lysand::funcs::send_follow_accept_to_lysand,
|
|
|
|
|
utils::{generate_follow_accept_id, generate_random_object_id},
|
|
|
|
|
DB,
|
2024-05-05 17:05:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
|
|
|
pub struct Follow {
|
2024-08-03 03:49:07 +02:00
|
|
|
pub actor: ObjectId<user::Model>,
|
|
|
|
|
pub object: ObjectId<user::Model>,
|
2024-05-05 17:05:09 +02:00
|
|
|
#[serde(rename = "type")]
|
2024-08-03 03:49:07 +02:00
|
|
|
pub kind: FollowType,
|
|
|
|
|
pub id: Url,
|
2024-05-05 17:05:09 +02:00
|
|
|
}
|
|
|
|
|
|
2024-05-05 18:18:39 +02:00
|
|
|
impl Follow {
|
|
|
|
|
pub async fn send(
|
|
|
|
|
local_user: ObjectId<user::Model>,
|
|
|
|
|
followee: ObjectId<user::Model>,
|
|
|
|
|
inbox: Url,
|
|
|
|
|
data: &Data<StateHandle>,
|
|
|
|
|
) -> Result<(), error::Error> {
|
|
|
|
|
print!("Sending follow request to {}", &followee);
|
|
|
|
|
let create = Follow {
|
|
|
|
|
actor: local_user.clone(),
|
|
|
|
|
object: followee.clone(),
|
|
|
|
|
kind: FollowType::Follow,
|
2024-06-15 02:06:01 +02:00
|
|
|
id: generate_random_object_id(data.domain())?,
|
2024-05-05 18:18:39 +02:00
|
|
|
};
|
|
|
|
|
let create_with_context = WithContext::new_default(create);
|
|
|
|
|
let sends = SendActivityTask::prepare(
|
|
|
|
|
&create_with_context,
|
|
|
|
|
&data.local_user().await?,
|
|
|
|
|
vec![inbox],
|
|
|
|
|
data,
|
|
|
|
|
)
|
|
|
|
|
.await?;
|
|
|
|
|
for send in sends {
|
|
|
|
|
send.sign_and_send(data).await?;
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Deserialize, Serialize, Debug)]
|
|
|
|
|
pub struct Accept {
|
|
|
|
|
actor: ObjectId<user::Model>,
|
|
|
|
|
object: Follow,
|
|
|
|
|
#[serde(rename = "type")]
|
|
|
|
|
kind: AcceptType,
|
|
|
|
|
id: Url,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Accept {
|
|
|
|
|
pub async fn send(
|
|
|
|
|
follow_relation: follow_relation::Model,
|
|
|
|
|
follow_req: Follow,
|
|
|
|
|
inbox: Url,
|
|
|
|
|
data: &Data<StateHandle>,
|
|
|
|
|
) -> Result<(), error::Error> {
|
|
|
|
|
print!("Sending accept to {}", &follow_relation.follower_id);
|
|
|
|
|
let create = Accept {
|
|
|
|
|
actor: follow_req.object.clone(),
|
|
|
|
|
object: follow_req,
|
|
|
|
|
kind: AcceptType::Accept,
|
2024-06-27 05:13:38 +02:00
|
|
|
id: generate_follow_accept_id(data.domain(), follow_relation.id.to_string().as_str())?,
|
2024-05-05 18:18:39 +02:00
|
|
|
};
|
|
|
|
|
let create_with_context = WithContext::new_default(create);
|
|
|
|
|
let sends = SendActivityTask::prepare(
|
|
|
|
|
&create_with_context,
|
|
|
|
|
&data.local_user().await?,
|
|
|
|
|
vec![inbox],
|
|
|
|
|
data,
|
|
|
|
|
)
|
|
|
|
|
.await?;
|
|
|
|
|
for send in sends {
|
|
|
|
|
send.sign_and_send(data).await?;
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-05 17:05:09 +02:00
|
|
|
#[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<Self::DataType>) -> Result<(), Self::Error> {
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn receive(self, data: &Data<Self::DataType>) -> Result<(), Self::Error> {
|
2024-08-03 06:25:16 +02:00
|
|
|
//accept_follow(self, data).await?; TODO replace w/ lysand forward
|
2024-05-05 18:18:39 +02:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[async_trait::async_trait]
|
|
|
|
|
impl ActivityHandler for Accept {
|
|
|
|
|
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<Self::DataType>) -> Result<(), Self::Error> {
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn receive(self, data: &Data<Self::DataType>) -> Result<(), Self::Error> {
|
|
|
|
|
let user = self.actor.dereference(data).await?;
|
2024-08-03 12:09:02 +02:00
|
|
|
let follower_id;
|
|
|
|
|
let follower_bridge_url = self.object.actor.clone().to_string();
|
|
|
|
|
let split = follower_bridge_url.split("/").collect::<Vec<&str>>();
|
|
|
|
|
if split[split.len() - 1].is_empty() {
|
|
|
|
|
follower_id = split[split.len() - 2];
|
|
|
|
|
} else {
|
|
|
|
|
follower_id = split[split.len() - 1];
|
|
|
|
|
}
|
|
|
|
|
let follower = prelude::User::find()
|
|
|
|
|
.filter(user::Column::Id.eq(follower_id))
|
|
|
|
|
.one(data.database_connection.as_ref())
|
|
|
|
|
.await?;
|
|
|
|
|
save_accept_follow(user, follower.unwrap(), self).await?;
|
2024-05-05 17:05:09 +02:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-03 06:25:16 +02:00
|
|
|
/*
|
2024-05-05 18:18:39 +02:00
|
|
|
async fn accept_follow(
|
|
|
|
|
follow_req: Follow,
|
|
|
|
|
data: &Data<StateHandle>,
|
|
|
|
|
) -> Result<(), crate::error::Error> {
|
|
|
|
|
let local_user = follow_req.actor.dereference(data).await?;
|
|
|
|
|
let follower = follow_req.object.dereference(data).await?;
|
|
|
|
|
let follow_relation = save_follow(local_user, follower.clone()).await?;
|
|
|
|
|
Accept::send(follow_relation, follow_req, follower.inbox().clone(), data).await?;
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2024-08-03 06:25:16 +02:00
|
|
|
*/
|
2024-05-05 18:18:39 +02:00
|
|
|
|
2024-08-03 06:25:16 +02:00
|
|
|
async fn save_accept_follow(
|
2024-08-03 03:49:07 +02:00
|
|
|
followee: user::Model,
|
2024-05-05 17:05:09 +02:00
|
|
|
follower: user::Model,
|
2024-08-03 06:25:16 +02:00
|
|
|
accept_activity: Accept,
|
2024-05-05 18:18:39 +02:00
|
|
|
) -> Result<follow_relation::Model, crate::error::Error> {
|
2024-08-03 03:49:07 +02:00
|
|
|
let db = DB.get().unwrap();
|
|
|
|
|
let query = prelude::FollowRelation::find()
|
|
|
|
|
.filter(follow_relation::Column::FollowerId.eq(follower.id.as_str()))
|
|
|
|
|
.filter(follow_relation::Column::FolloweeId.eq(followee.id.as_str()))
|
|
|
|
|
.one(db)
|
|
|
|
|
.await?;
|
|
|
|
|
if query.is_none() {
|
|
|
|
|
return Err(crate::error::Error(anyhow::anyhow!("oopsie woopise")));
|
|
|
|
|
}
|
2024-08-03 06:25:16 +02:00
|
|
|
let lysand_accept_id = uuid::Uuid::now_v7().to_string();
|
|
|
|
|
// all values in the ActiveModel that are set, except the id, will be updated
|
|
|
|
|
let active_query = follow_relation::ActiveModel {
|
|
|
|
|
id: Set(query.unwrap().id),
|
|
|
|
|
ap_accept_id: Set(Some(accept_activity.id.to_string())),
|
|
|
|
|
ap_accept_json: Set(Some(serde_json::to_string(&accept_activity).unwrap())),
|
|
|
|
|
accept_id: Set(Some(lysand_accept_id)),
|
|
|
|
|
..Default::default()
|
|
|
|
|
};
|
2024-08-03 03:49:07 +02:00
|
|
|
// modify db entry
|
2024-08-03 06:25:16 +02:00
|
|
|
let res = prelude::FollowRelation::update(active_query);
|
|
|
|
|
let model = res.exec(db).await?;
|
2024-08-03 03:49:07 +02:00
|
|
|
|
2024-08-03 15:30:25 +02:00
|
|
|
let _ = send_follow_accept_to_lysand(model.clone()).await?;
|
|
|
|
|
|
2024-05-05 18:18:39 +02:00
|
|
|
Ok(model)
|
2024-05-05 17:05:09 +02:00
|
|
|
}
|