From 0e24ccbf29c1a9368ad0a0899daaa54707a2c031 Mon Sep 17 00:00:00 2001 From: Bat Date: Fri, 18 May 2018 09:04:40 +0100 Subject: [PATCH] Use activitystreams in the Inbox trait --- src/activity_pub/inbox.rs | 46 +++++++++++++++++++++++---------------- src/activity_pub/mod.rs | 8 +++++-- src/models/blogs.rs | 29 ++++++++++++++++++++---- src/models/users.rs | 30 ++++++++++++++++++++----- 4 files changed, 83 insertions(+), 30 deletions(-) diff --git a/src/activity_pub/inbox.rs b/src/activity_pub/inbox.rs index 25a9200d..0a4d6c3f 100644 --- a/src/activity_pub/inbox.rs +++ b/src/activity_pub/inbox.rs @@ -1,18 +1,19 @@ +use activitystreams_traits::Actor; use activitystreams_types::{ actor::Person, - activity::{Create, Follow, Like, Undo}, + activity::{Accept, Create, Follow, Like, Undo}, object::{Article, Note} }; -use activitystreams::activity::Activity; use diesel::PgConnection; use failure::Error; use serde_json; -// use activity_pub::broadcast; +use activity_pub::{broadcast, IntoId}; use activity_pub::actor::Actor as APActor; use activity_pub::sign::*; use models::blogs::Blog; use models::comments::*; +use models::follows; use models::likes; use models::posts::*; use models::users::User; @@ -63,10 +64,10 @@ pub trait Inbox { fn follow(&self, conn: &PgConnection, follow: Follow) -> Result<(), Error> { let from = User::from_url(conn, follow.actor.as_str().unwrap().to_string()).unwrap(); match User::from_url(conn, follow.object.as_str().unwrap().to_string()) { - Some(u) => self.accept_follow(conn, &from, &u, &follow, from.id, u.id), + Some(u) => self.accept_follow(conn, &from, &u, follow, from.id, u.id), None => { let blog = Blog::from_url(conn, follow.object.as_str().unwrap().to_string()).unwrap(); - self.accept_follow(conn, &from, &blog, &follow, from.id, blog.id) + self.accept_follow(conn, &from, &blog, follow, from.id, blog.id) } }; Ok(()) @@ -117,22 +118,29 @@ pub trait Inbox { } } - fn accept_follow( + fn accept_follow( &self, - _conn: &PgConnection, - _from: &A, - _target: &B, - _follow: &T, - _from_id: i32, - _target_id: i32 + conn: &PgConnection, + from: &A, + target: &B, + follow: Follow, + from_id: i32, + target_id: i32 ) { - // TODO - //Follow::insert(conn, NewFollow { - // follower_id: from_id, - // following_id: target_id - //}); + follows::Follow::insert(conn, follows::NewFollow { + follower_id: from_id, + following_id: target_id + }); - //let accept = activity::Accept::new(target, follow, conn); - //broadcast(conn, from, accept, vec![target.clone()]); + let mut accept = Accept::default();//new(target, follow, conn); + accept.set_actor_link(from.into()).unwrap(); + accept.set_object_object(follow).unwrap(); + broadcast(conn, &*from, accept, vec![target.clone()]); } } + +pub trait WithInbox { + fn get_inbox_url(&self) -> String; + + fn get_shared_inbox_url(&self) -> Option; +} diff --git a/src/activity_pub/mod.rs b/src/activity_pub/mod.rs index 9ac4c073..864a5f5a 100644 --- a/src/activity_pub/mod.rs +++ b/src/activity_pub/mod.rs @@ -1,4 +1,4 @@ -use activitystreams_traits::{Activity, Object, Link}; +use activitystreams_traits::{Activity, Actor, Object, Link}; use array_tool::vec::Uniq; use diesel::PgConnection; use reqwest::Client; @@ -76,7 +76,7 @@ impl<'r, O: Object> Responder<'r> for ActivityStream { } } -pub fn broadcast(conn: &PgConnection, sender: &S, act: A, to: Vec) { +pub fn broadcast(conn: &PgConnection, sender: &S, act: A, to: Vec) { let boxes = to.into_iter() .map(|u| u.get_shared_inbox_url().unwrap_or(u.get_inbox_url())) .collect::>() @@ -116,4 +116,8 @@ impl Id { } } +pub trait IntoId { + fn into(&self) -> Id; +} + impl Link for Id {} diff --git a/src/models/blogs.rs b/src/models/blogs.rs index 6a931253..66851f75 100644 --- a/src/models/blogs.rs +++ b/src/models/blogs.rs @@ -1,3 +1,4 @@ +use activitystreams_traits::{Actor, Object}; use activitystreams_types::collection::OrderedCollection; use reqwest::Client; use reqwest::header::{Accept, qitem}; @@ -11,15 +12,16 @@ use openssl::pkey::{PKey, Private}; use openssl::rsa::Rsa; use openssl::sign::Signer; -use activity_pub::ActivityStream; -use activity_pub::actor::{Actor, ActorType}; +use activity_pub::{ActivityStream, Id}; +use activity_pub::actor::{Actor as APActor, ActorType}; +use activity_pub::inbox::WithInbox; use activity_pub::sign; use activity_pub::webfinger::*; use models::instance::Instance; use schema::blogs; -#[derive(Queryable, Identifiable, Serialize, Clone)] +#[derive(Queryable, Identifiable, Serialize, Deserialize, Clone)] pub struct Blog { pub id: i32, pub actor_id: String, @@ -173,7 +175,26 @@ impl Blog { } } -impl Actor for Blog { +impl Into for Blog { + fn into(self) -> Id { + Id::new(self.ap_url) + } +} + +impl Object for Blog {} +impl Actor for Blog {} + +impl WithInbox for Blog { + fn get_inbox_url(&self) -> String { + self.inbox_url.clone() + } + + fn get_shared_inbox_url(&self) -> Option { + None + } +} + +impl APActor for Blog { fn get_box_prefix() -> &'static str { "~" } diff --git a/src/models/users.rs b/src/models/users.rs index 1a50c713..e39dcb14 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -1,3 +1,4 @@ +use activitystreams_traits::{Actor, Object}; use activitystreams_types::{ activity::Create, collection::OrderedCollection @@ -19,9 +20,9 @@ use serde_json; use url::Url; use BASE_URL; -use activity_pub::{ap_url, ActivityStream}; -use activity_pub::actor::{ActorType, Actor}; -use activity_pub::inbox::Inbox; +use activity_pub::{ap_url, ActivityStream, Id, IntoId}; +use activity_pub::actor::{ActorType, Actor as APActor}; +use activity_pub::inbox::{Inbox, WithInbox}; use activity_pub::sign::{Signer, gen_keypair}; use activity_pub::webfinger::{Webfinger, resolve}; use db_conn::DbConn; @@ -35,7 +36,7 @@ use schema::users; pub const AUTH_COOKIE: &'static str = "user_id"; -#[derive(Queryable, Identifiable, Serialize, Clone)] +#[derive(Queryable, Identifiable, Serialize, Deserialize, Clone)] pub struct User { pub id: i32, pub username: String, @@ -292,7 +293,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for User { } } -impl Actor for User { +impl APActor for User { fn get_box_prefix() -> &'static str { "@" } @@ -357,6 +358,25 @@ impl Actor for User { } } +impl IntoId for User { + fn into(&self) -> Id { + Id::new(self.ap_url.clone()) + } +} + +impl Object for User {} +impl Actor for User {} + +impl WithInbox for User { + fn get_inbox_url(&self) -> String { + self.inbox_url.clone() + } + + fn get_shared_inbox_url(&self) -> Option { + self.shared_inbox_url.clone() + } +} + impl Inbox for User { fn received(&self, conn: &PgConnection, act: serde_json::Value) { self.save(conn, act.clone()).unwrap();