mirror of
https://git.joinplu.me/Plume/Plume.git
synced 2024-11-29 23:11:02 +00:00
Use shared inbox when available
But it is not yet stored in the database, so it means never
This commit is contained in:
parent
b91f567777
commit
fdc481e384
9 changed files with 52 additions and 32 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -16,6 +16,11 @@ name = "antidote"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "array_tool"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
|
@ -801,6 +806,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
name = "plume"
|
name = "plume"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bcrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bcrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1575,6 +1581,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45"
|
"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 aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
|
||||||
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
||||||
|
"checksum array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271"
|
||||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||||
"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e"
|
"checksum backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe525f66f42d207968308ee86bc2dd60aa5fab535b22e616323a173d097d8e"
|
||||||
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
|
||||||
|
|
|
@ -3,6 +3,7 @@ authors = ["Bat' <baptiste@gelez.xyz>"]
|
||||||
name = "plume"
|
name = "plume"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
array_tool = "1.0"
|
||||||
base64 = "0.9"
|
base64 = "0.9"
|
||||||
bcrypt = "0.2"
|
bcrypt = "0.2"
|
||||||
dotenv = "*"
|
dotenv = "*"
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use reqwest::Client;
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
|
||||||
use BASE_URL;
|
use BASE_URL;
|
||||||
use activity_pub::{activity_pub, ActivityPub, context, ap_url};
|
use activity_pub::{activity_pub, ActivityPub, context, ap_url};
|
||||||
use activity_pub::activity::Activity;
|
|
||||||
use activity_pub::request;
|
|
||||||
use activity_pub::sign::*;
|
|
||||||
use models::instance::Instance;
|
use models::instance::Instance;
|
||||||
|
|
||||||
pub enum ActorType {
|
pub enum ActorType {
|
||||||
|
@ -38,6 +34,8 @@ pub trait Actor: Sized {
|
||||||
|
|
||||||
fn get_inbox_url(&self) -> String;
|
fn get_inbox_url(&self) -> String;
|
||||||
|
|
||||||
|
fn get_shared_inbox_url(&self) -> Option<String>;
|
||||||
|
|
||||||
fn custom_props(&self, _conn: &PgConnection) -> serde_json::Map<String, serde_json::Value> {
|
fn custom_props(&self, _conn: &PgConnection) -> serde_json::Map<String, serde_json::Value> {
|
||||||
serde_json::Map::new()
|
serde_json::Map::new()
|
||||||
}
|
}
|
||||||
|
@ -84,23 +82,5 @@ pub trait Actor: Sized {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_to_inbox<A: Activity, S: Actor + Signer>(&self, conn: &PgConnection, sender: &S, act: A) {
|
|
||||||
let mut act = act.serialize();
|
|
||||||
act["@context"] = context();
|
|
||||||
let signed = act.sign(sender, conn);
|
|
||||||
|
|
||||||
let res = Client::new()
|
|
||||||
.post(&self.get_inbox_url()[..])
|
|
||||||
.headers(request::headers())
|
|
||||||
.header(request::signature(sender, request::headers(), conn))
|
|
||||||
.header(request::digest(signed.to_string()))
|
|
||||||
.body(signed.to_string())
|
|
||||||
.send();
|
|
||||||
match res {
|
|
||||||
Ok(mut r) => println!("Successfully sent activity to inbox ({})\n\n{:?}", self.get_inbox_url(), r.text().unwrap()),
|
|
||||||
Err(e) => println!("Error while sending to inbox ({:?})", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_url(conn: &PgConnection, url: String) -> Option<Self>;
|
fn from_url(conn: &PgConnection, url: String) -> Option<Self>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use serde_json;
|
||||||
|
|
||||||
use activity_pub::activity;
|
use activity_pub::activity;
|
||||||
use activity_pub::actor::Actor;
|
use activity_pub::actor::Actor;
|
||||||
|
use activity_pub::outbox::broadcast;
|
||||||
use activity_pub::sign::*;
|
use activity_pub::sign::*;
|
||||||
use models::blogs::Blog;
|
use models::blogs::Blog;
|
||||||
use models::comments::*;
|
use models::comments::*;
|
||||||
|
@ -79,7 +80,7 @@ pub trait Inbox: Actor + Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept_follow<A: Actor, B: Actor + Signer, T: activity::Activity>(
|
fn accept_follow<A: Actor + Signer, B: Actor + Clone, T: activity::Activity>(
|
||||||
&self,
|
&self,
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
from: &A,
|
from: &A,
|
||||||
|
@ -94,6 +95,6 @@ pub trait Inbox: Actor + Sized {
|
||||||
});
|
});
|
||||||
|
|
||||||
let accept = activity::Accept::new(target, follow, conn);
|
let accept = activity::Accept::new(target, follow, conn);
|
||||||
from.send_to_inbox(conn, target, accept)
|
broadcast(conn, from, accept, vec![target.clone()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
use array_tool::vec::Uniq;
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
|
use reqwest::Client;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket::response::{Response, Responder};
|
use rocket::response::{Response, Responder};
|
||||||
use rocket::request::Request;
|
use rocket::request::Request;
|
||||||
|
@ -8,8 +10,8 @@ use std::sync::Arc;
|
||||||
use activity_pub::{activity_pub, ActivityPub, context};
|
use activity_pub::{activity_pub, ActivityPub, context};
|
||||||
use activity_pub::activity::Activity;
|
use activity_pub::activity::Activity;
|
||||||
use activity_pub::actor::Actor;
|
use activity_pub::actor::Actor;
|
||||||
use activity_pub::sign::Signer;
|
use activity_pub::request;
|
||||||
use models::users::User;
|
use activity_pub::sign::*;
|
||||||
|
|
||||||
pub struct Outbox {
|
pub struct Outbox {
|
||||||
id: String,
|
id: String,
|
||||||
|
@ -42,8 +44,28 @@ impl<'r> Responder<'r> for Outbox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn broadcast<A: Activity + Clone, S: Actor + Signer>(conn: &PgConnection, sender: &S, act: A, to: Vec<User>) {
|
pub fn broadcast<A: Activity + Clone, S: Actor + Signer, T: Actor>(conn: &PgConnection, sender: &S, act: A, to: Vec<T>) {
|
||||||
for user in to {
|
let boxes = to.into_iter()
|
||||||
user.send_to_inbox(conn, sender, act.clone()); // TODO: run it in Sidekiq or something like that
|
.map(|u| u.get_shared_inbox_url().unwrap_or(u.get_inbox_url()))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.unique();
|
||||||
|
for inbox in boxes {
|
||||||
|
// TODO: run it in Sidekiq or something like that
|
||||||
|
|
||||||
|
let mut act = act.serialize();
|
||||||
|
act["@context"] = context();
|
||||||
|
let signed = act.sign(sender, conn);
|
||||||
|
|
||||||
|
let res = Client::new()
|
||||||
|
.post(&inbox[..])
|
||||||
|
.headers(request::headers())
|
||||||
|
.header(request::signature(sender, request::headers(), conn))
|
||||||
|
.header(request::digest(signed.to_string()))
|
||||||
|
.body(signed.to_string())
|
||||||
|
.send();
|
||||||
|
match res {
|
||||||
|
Ok(mut r) => println!("Successfully sent activity to inbox ({})\n\n{:?}", inbox, r.text().unwrap()),
|
||||||
|
Err(e) => println!("Error while sending to inbox ({:?})", e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#![feature(plugin, custom_derive, iterator_find_map)]
|
#![feature(plugin, custom_derive, iterator_find_map)]
|
||||||
#![plugin(rocket_codegen)]
|
#![plugin(rocket_codegen)]
|
||||||
|
|
||||||
|
extern crate array_tool;
|
||||||
extern crate base64;
|
extern crate base64;
|
||||||
extern crate bcrypt;
|
extern crate bcrypt;
|
||||||
extern crate chrono;
|
extern crate chrono;
|
||||||
|
|
|
@ -15,7 +15,7 @@ use models::instance::Instance;
|
||||||
use schema::blogs;
|
use schema::blogs;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Queryable, Identifiable, Serialize)]
|
#[derive(Queryable, Identifiable, Serialize, Clone)]
|
||||||
pub struct Blog {
|
pub struct Blog {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub actor_id: String,
|
pub actor_id: String,
|
||||||
|
@ -130,6 +130,10 @@ impl Actor for Blog {
|
||||||
self.inbox_url.clone()
|
self.inbox_url.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_shared_inbox_url(&self) -> Option<String> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn from_url(conn: &PgConnection, url: String) -> Option<Blog> {
|
fn from_url(conn: &PgConnection, url: String) -> Option<Blog> {
|
||||||
blogs::table.filter(blogs::ap_url.eq(url))
|
blogs::table.filter(blogs::ap_url.eq(url))
|
||||||
.limit(1)
|
.limit(1)
|
||||||
|
|
|
@ -300,6 +300,10 @@ impl Actor for User {
|
||||||
self.inbox_url.clone()
|
self.inbox_url.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_shared_inbox_url(&self) -> Option<String> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn custom_props(&self, conn: &PgConnection) -> serde_json::Map<String, serde_json::Value> {
|
fn custom_props(&self, conn: &PgConnection) -> serde_json::Map<String, serde_json::Value> {
|
||||||
let mut res = serde_json::Map::new();
|
let mut res = serde_json::Map::new();
|
||||||
res.insert("publicKey".to_string(), json!({
|
res.insert("publicKey".to_string(), json!({
|
||||||
|
|
|
@ -6,7 +6,7 @@ use serde_json;
|
||||||
use activity_pub::{activity, activity_pub, ActivityPub, context};
|
use activity_pub::{activity, activity_pub, ActivityPub, context};
|
||||||
use activity_pub::actor::Actor;
|
use activity_pub::actor::Actor;
|
||||||
use activity_pub::inbox::Inbox;
|
use activity_pub::inbox::Inbox;
|
||||||
use activity_pub::outbox::Outbox;
|
use activity_pub::outbox::{broadcast, Outbox};
|
||||||
use db_conn::DbConn;
|
use db_conn::DbConn;
|
||||||
use models::follows::*;
|
use models::follows::*;
|
||||||
use models::instance::Instance;
|
use models::instance::Instance;
|
||||||
|
@ -48,7 +48,7 @@ fn follow(name: String, conn: DbConn, user: User) -> Redirect {
|
||||||
follower_id: user.id,
|
follower_id: user.id,
|
||||||
following_id: target.id
|
following_id: target.id
|
||||||
});
|
});
|
||||||
target.send_to_inbox(&*conn, &user, activity::Follow::new(&user, &target, &*conn));
|
broadcast(&*conn, &user, activity::Follow::new(&user, &target, &*conn), vec![target]);
|
||||||
Redirect::to(format!("/@/{}", name).as_ref())
|
Redirect::to(format!("/@/{}", name).as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue