From 78362feffbcf8ed2a699c167e8ea93f973575d03 Mon Sep 17 00:00:00 2001 From: Bat Date: Sun, 10 Jun 2018 12:13:07 +0100 Subject: [PATCH] Use the activitypub crate --- Cargo.lock | 30 +++++++++++++++++++++++++++ Cargo.toml | 1 + src/activity_pub/inbox.rs | 35 +++++++++++++++---------------- src/activity_pub/mod.rs | 2 +- src/main.rs | 5 +---- src/models/blogs.rs | 3 +-- src/models/comments.rs | 6 +++--- src/models/likes.rs | 10 ++++----- src/models/posts.rs | 10 ++++----- src/models/reshares.rs | 10 ++++----- src/models/users.rs | 43 ++++++++++++++------------------------- src/routes/blogs.rs | 2 +- src/routes/user.rs | 6 +++--- 13 files changed, 88 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5f5db7af..6ca0a34b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,16 @@ +[[package]] +name = "activitypub" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "activitystreams-traits 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "activitystreams-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "activitystreams" version = "0.1.1" @@ -41,6 +54,20 @@ dependencies = [ "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "activitystreams-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "activitystreams-traits 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "adler32" version = "1.0.2" @@ -936,6 +963,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "plume" version = "0.1.0" dependencies = [ + "activitypub 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "activitystreams 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "activitystreams-traits 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1811,10 +1839,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum activitypub 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c87040997a45d9da90327a11191bda4f2b1812d8c3e2062ea8d539eb8e2bfde7" "checksum activitystreams 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "638541e5169c839f6581302c50e38876312389475cd911ecc7c446c7491004cc" "checksum activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48db826c588a009960d74530e7c215e21fae130f585362504dc6b6357e5ce86b" "checksum activitystreams-traits 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "670ef03168e704b0cae242e7a5d8b40506772b339687e01a3496fc4afe2e8542" "checksum activitystreams-types 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aff9aa0c3412fe4da72a1f6e4b1c2e9792bfdf1308b709389192f17aa8e2b3cd" +"checksum activitystreams-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "14806b3c88c439e1670fdc99d9b18bf1a47d4fa7152fe8a3bd7da08b6ced3e95" "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" diff --git a/Cargo.toml b/Cargo.toml index 41241766..815bf6df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ authors = ["Bat' "] name = "plume" version = "0.1.0" [dependencies] +activitypub = "0.1" activitystreams = "0.1" activitystreams-derive = "0.1" activitystreams-traits = "0.1" diff --git a/src/activity_pub/inbox.rs b/src/activity_pub/inbox.rs index 1b45b442..06a44a96 100644 --- a/src/activity_pub/inbox.rs +++ b/src/activity_pub/inbox.rs @@ -1,9 +1,10 @@ -use activitystreams_traits::Actor; -use activitystreams_types::{ +use activitypub::{ + Actor, actor::Person, activity::{Accept, Announce, Create, Follow, Like, Undo}, - object::{Article, Note} + object::Note }; +use activitystreams_types::object::Article; use diesel::PgConnection; use failure::Error; use serde_json; @@ -67,11 +68,11 @@ 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()) { + let from = User::from_url(conn, follow.follow_props.actor.as_str().unwrap().to_string()).unwrap(); + match User::from_url(conn, follow.follow_props.object.as_str().unwrap().to_string()) { 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(); + let blog = Blog::from_url(conn, follow.follow_props.object.as_str().unwrap().to_string()).unwrap(); self.accept_follow(conn, &from, &blog, follow, from.id, blog.id) } }; @@ -79,8 +80,8 @@ pub trait Inbox { } fn like(&self, conn: &PgConnection, like: Like) -> Result<(), Error> { - let liker = User::from_url(conn, like.actor.as_str().unwrap().to_string()); - let post = Post::find_by_ap_url(conn, like.object.as_str().unwrap().to_string()); + let liker = User::from_url(conn, like.like_props.actor.as_str().unwrap().to_string()); + let post = Post::find_by_ap_url(conn, like.like_props.object.as_str().unwrap().to_string()); likes::Like::insert(conn, likes::NewLike { post_id: post.unwrap().id, user_id: liker.unwrap().id, @@ -90,14 +91,14 @@ pub trait Inbox { } fn unlike(&self, conn: &PgConnection, undo: Undo) -> Result<(), Error> { - let like = likes::Like::find_by_ap_url(conn, undo.object_object::()?.object_props.id_string()?).unwrap(); + let like = likes::Like::find_by_ap_url(conn, undo.undo_props.object_object::()?.object_props.id_string()?).unwrap(); like.delete(conn); Ok(()) } fn announce(&self, conn: &PgConnection, announce: Announce) -> Result<(), Error> { - let user = User::from_url(conn, announce.actor.as_str().unwrap().to_string()); - let post = Post::find_by_ap_url(conn, announce.object.as_str().unwrap().to_string()); + let user = User::from_url(conn, announce.announce_props.actor.as_str().unwrap().to_string()); + let post = Post::find_by_ap_url(conn, announce.announce_props.object.as_str().unwrap().to_string()); Reshare::insert(conn, NewReshare { post_id: post.unwrap().id, user_id: user.unwrap().id, @@ -113,9 +114,9 @@ pub trait Inbox { "Announce" => self.announce(conn, serde_json::from_value(act.clone())?), "Create" => { let act: Create = serde_json::from_value(act.clone())?; - match act.object["type"].as_str().unwrap() { - "Article" => self.new_article(conn, act.object_object()?), - "Note" => self.new_comment(conn, act.object_object()?, act.actor_object::()?.object_props.id_string()?), + match act.create_props.object["type"].as_str().unwrap() { + "Article" => self.new_article(conn, act.create_props.object_object()?), + "Note" => self.new_comment(conn, act.create_props.object_object()?, act.create_props.actor_object::()?.object_props.id_string()?), _ => Err(InboxError::InvalidType)? } }, @@ -123,7 +124,7 @@ pub trait Inbox { "Like" => self.like(conn, serde_json::from_value(act.clone())?), "Undo" => { let act: Undo = serde_json::from_value(act.clone())?; - match act.object["type"].as_str().unwrap() { + match act.undo_props.object["type"].as_str().unwrap() { "Like" => self.unlike(conn, act), _ => Err(InboxError::CantUndo)? } @@ -150,8 +151,8 @@ pub trait Inbox { }); let mut accept = Accept::default(); - accept.set_actor_link::(from.clone().into_id()).unwrap(); - accept.set_object_object(follow).unwrap(); + accept.accept_props.set_actor_link::(from.clone().into_id()).unwrap(); + accept.accept_props.set_object_object(follow).unwrap(); broadcast(conn, &*from, accept, vec![target.clone()]); } } diff --git a/src/activity_pub/mod.rs b/src/activity_pub/mod.rs index f544d15e..febd9591 100644 --- a/src/activity_pub/mod.rs +++ b/src/activity_pub/mod.rs @@ -1,4 +1,4 @@ -use activitystreams_traits::{Activity, Actor, Object, Link}; +use activitypub::{Activity, Actor, Object, Link}; use array_tool::vec::Uniq; use diesel::PgConnection; use reqwest::Client; diff --git a/src/main.rs b/src/main.rs index 3e6d3a03..5ffbe607 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,7 @@ #![feature(plugin, custom_derive, iterator_find_map)] #![plugin(rocket_codegen)] -extern crate activitystreams; -#[macro_use] -extern crate activitystreams_derive; -extern crate activitystreams_traits; +extern crate activitypub; extern crate activitystreams_types; extern crate array_tool; extern crate base64; diff --git a/src/models/blogs.rs b/src/models/blogs.rs index 46765486..fbec62e5 100644 --- a/src/models/blogs.rs +++ b/src/models/blogs.rs @@ -1,5 +1,4 @@ -use activitystreams_traits::{Actor, Object}; -use activitystreams_types::collection::OrderedCollection; +use activitypub::{Actor, Object, collection::OrderedCollection}; use reqwest::{ Client, header::{Accept, qitem}, diff --git a/src/models/comments.rs b/src/models/comments.rs index 8a24195e..042e0f67 100644 --- a/src/models/comments.rs +++ b/src/models/comments.rs @@ -1,4 +1,4 @@ -use activitystreams_types::{ +use activitypub::{ activity::Create, object::{Note, properties::ObjectProperties} }; @@ -105,8 +105,8 @@ impl Comment { pub fn create_activity(&self, conn: &PgConnection) -> Create { let mut act = Create::default(); - act.set_actor_link(self.get_author(conn).into_id()).unwrap(); - act.set_object_object(self.into_activity(conn)).unwrap(); + act.create_props.set_actor_link(self.get_author(conn).into_id()).unwrap(); + act.create_props.set_object_object(self.into_activity(conn)).unwrap(); act.object_props.set_id_string(format!("{}/activity", self.ap_url.clone().unwrap())).unwrap(); act } diff --git a/src/models/likes.rs b/src/models/likes.rs index acf505dc..65b24ff8 100644 --- a/src/models/likes.rs +++ b/src/models/likes.rs @@ -1,4 +1,4 @@ -use activitystreams_types::activity; +use activitypub::activity; use chrono; use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; use serde_json; @@ -76,15 +76,15 @@ impl Like { diesel::delete(self).execute(conn).unwrap(); let mut act = activity::Undo::default(); - act.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap(); - act.set_object_object(self.into_activity(conn)).unwrap(); + act.undo_props.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap(); + act.undo_props.set_object_object(self.into_activity(conn)).unwrap(); act } pub fn into_activity(&self, conn: &PgConnection) -> activity::Like { let mut act = activity::Like::default(); - act.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap(); - act.set_object_link(Post::get(conn, self.post_id).unwrap().into_id()).unwrap(); + act.like_props.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap(); + act.like_props.set_object_link(Post::get(conn, self.post_id).unwrap().into_id()).unwrap(); act.object_props.set_id_string(format!("{}/like/{}", User::get(conn, self.user_id).unwrap().ap_url, Post::get(conn, self.post_id).unwrap().ap_url diff --git a/src/models/posts.rs b/src/models/posts.rs index 0a3b8923..1ac4116f 100644 --- a/src/models/posts.rs +++ b/src/models/posts.rs @@ -1,7 +1,5 @@ -use activitystreams_types::{ - activity::Create, - object::{Article, properties::ObjectProperties} -}; +use activitypub::activity::Create; +use activitystreams_types::object::{Article, properties::ObjectProperties}; use chrono::NaiveDateTime; use diesel::{self, PgConnection, RunQueryDsl, QueryDsl, ExpressionMethods, BelongingToDsl}; use diesel::dsl::any; @@ -177,8 +175,8 @@ impl Post { pub fn create_activity(&self, conn: &PgConnection) -> Create { let mut act = Create::default(); act.object_props.set_id_string(format!("{}/activity", self.ap_url)).unwrap(); - act.set_actor_link(Id::new(self.get_authors(conn)[0].clone().ap_url)).unwrap(); - act.set_object_object(self.into_activity(conn)).unwrap(); + act.create_props.set_actor_link(Id::new(self.get_authors(conn)[0].clone().ap_url)).unwrap(); + act.create_props.set_object_object(self.into_activity(conn)).unwrap(); act } } diff --git a/src/models/reshares.rs b/src/models/reshares.rs index 6d8c138e..65c4739e 100644 --- a/src/models/reshares.rs +++ b/src/models/reshares.rs @@ -1,4 +1,4 @@ -use activitystreams_types::activity; +use activitypub::activity; use chrono::NaiveDateTime; use diesel::{self, PgConnection, QueryDsl, RunQueryDsl, ExpressionMethods}; @@ -84,15 +84,15 @@ impl Reshare { diesel::delete(self).execute(conn).unwrap(); let mut act = activity::Undo::default(); - act.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap(); - act.set_object_object(self.into_activity(conn)).unwrap(); + act.undo_props.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap(); + act.undo_props.set_object_object(self.into_activity(conn)).unwrap(); act } pub fn into_activity(&self, conn: &PgConnection) -> activity::Announce { let mut act = activity::Announce::default(); - act.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap(); - act.set_object_link(Post::get(conn, self.post_id).unwrap().into_id()).unwrap(); + act.announce_props.set_actor_link(User::get(conn, self.user_id).unwrap().into_id()).unwrap(); + act.announce_props.set_object_link(Post::get(conn, self.post_id).unwrap().into_id()).unwrap(); act.object_props.set_id_string(self.ap_url.clone()).unwrap(); act diff --git a/src/models/users.rs b/src/models/users.rs index e15ed42d..89698ab9 100644 --- a/src/models/users.rs +++ b/src/models/users.rs @@ -1,9 +1,8 @@ -use activitystreams_traits::{Actor, Object, Link}; -use activitystreams_types::{ - actor::Person, +use activitypub::{ + Actor, Object, + actor::{Person, properties::ApActorProperties}, collection::OrderedCollection, - object::properties::ObjectProperties, - CustomObject + object::properties::ObjectProperties }; use bcrypt; use chrono::NaiveDateTime; @@ -302,7 +301,7 @@ impl User { PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.clone().unwrap().as_ref()).unwrap()).unwrap() } - pub fn into_activity(&self, conn: &PgConnection) -> CustomObject { + pub fn into_activity(&self, conn: &PgConnection) -> Person { let mut actor = Person::default(); actor.object_props = ObjectProperties { id: Some(serde_json::to_value(self.compute_id(conn)).unwrap()), @@ -311,34 +310,22 @@ impl User { url: Some(serde_json::to_value(self.compute_id(conn)).unwrap()), ..ObjectProperties::default() }; - - CustomObject::new(actor, ApProps { - inbox: Some(serde_json::to_value(self.compute_inbox(conn)).unwrap()), - outbox: Some(serde_json::to_value(self.compute_outbox(conn)).unwrap()), + actor.ap_actor_props = ApActorProperties { + inbox: serde_json::to_value(self.compute_inbox(conn)).unwrap(), + outbox: serde_json::to_value(self.compute_outbox(conn)).unwrap(), preferred_username: Some(serde_json::to_value(self.get_actor_id()).unwrap()), endpoints: Some(json!({ "sharedInbox": ap_url(format!("{}/inbox", BASE_URL.as_str())) - })) - }) + })), + followers: None, + following: None, + liked: None, + streams: None + }; + actor } } -#[derive(Serialize, Deserialize, Default, Properties)] -#[serde(rename_all = "camelCase")] -pub struct ApProps { - #[activitystreams(ab(Object, Link))] - inbox: Option, - - #[activitystreams(ab(Object, Link))] - outbox: Option, - - #[activitystreams(ab(Object, Link))] - preferred_username: Option, - - #[activitystreams(ab(Object))] - endpoints: Option -} - impl<'a, 'r> FromRequest<'a, 'r> for User { type Error = (); diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs index 863f60a2..ab42d493 100644 --- a/src/routes/blogs.rs +++ b/src/routes/blogs.rs @@ -1,4 +1,4 @@ -use activitystreams_types::collection::OrderedCollection; +use activitypub::collection::OrderedCollection; use rocket::{ request::Form, response::{Redirect, Flash} diff --git a/src/routes/user.rs b/src/routes/user.rs index 35192b09..95223ff3 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -1,4 +1,4 @@ -use activitystreams_types::{ +use activitypub::{ activity::Follow, collection::OrderedCollection }; @@ -82,8 +82,8 @@ fn follow(name: String, conn: DbConn, user: User) -> Redirect { following_id: target.id }); let mut act = Follow::default(); - act.set_actor_link::(user.clone().into_id()).unwrap(); - act.set_object_object(user.into_activity(&*conn)).unwrap(); + act.follow_props.set_actor_link::(user.clone().into_id()).unwrap(); + act.follow_props.set_object_object(user.into_activity(&*conn)).unwrap(); act.object_props.set_id_string(format!("{}/follow/{}", user.ap_url, target.ap_url)).unwrap(); broadcast(&*conn, &user, act, vec![target]); Redirect::to(format!("/@/{}/", name).as_ref())