Migrate user and group to new activitystreams library

This commit is contained in:
Felix Ableitner 2020-07-03 14:20:28 +02:00
parent d03c435563
commit c9338027f2
12 changed files with 346 additions and 277 deletions

View file

@ -1,6 +1,10 @@
#!/bin/bash #!/bin/bash
set -e set -e
# make sure there are no old containers or old data around
sudo docker-compose --file ../federation/docker-compose.yml --project-directory . down
sudo rm -rf volumes
pushd ../../server/ pushd ../../server/
cargo build cargo build
popd popd

View file

@ -110,3 +110,4 @@ services:
image: dogbin/iframely:latest image: dogbin/iframely:latest
volumes: volumes:
- ../iframely.config.local.js:/iframely/config.local.js:ro - ../iframely.config.local.js:/iframely/config.local.js:ro
restart: always

145
server/Cargo.lock generated vendored
View file

@ -63,7 +63,7 @@ dependencies = [
"futures-util", "futures-util",
"log", "log",
"once_cell", "once_cell",
"parking_lot", "parking_lot 0.10.2",
"pin-project", "pin-project",
"smallvec", "smallvec",
"tokio", "tokio",
@ -269,7 +269,7 @@ dependencies = [
"lazy_static", "lazy_static",
"log", "log",
"num_cpus", "num_cpus",
"parking_lot", "parking_lot 0.10.2",
"threadpool", "threadpool",
] ]
@ -397,6 +397,12 @@ dependencies = [
"gimli", "gimli",
] ]
[[package]]
name = "adler"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccc9a9dd069569f212bc4330af9f17c4afb5e8ce185e83dbb14f1349dda18b10"
[[package]] [[package]]
name = "adler32" name = "adler32"
version = "1.1.0" version = "1.1.0"
@ -506,7 +512,7 @@ dependencies = [
"addr2line", "addr2line",
"cfg-if", "cfg-if",
"libc", "libc",
"miniz_oxide", "miniz_oxide 0.3.7",
"object", "object",
"rustc-demangle", "rustc-demangle",
] ]
@ -680,9 +686,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.55" version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1be3409f94d7bdceeb5f5fac551039d9b3f00e25da7a74fc4d33400a0d96368" checksum = "0fde55d2a2bfaa4c9668bbc63f531fbdeee3ffe188f4662511ce2c22b3eedebe"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -692,9 +698,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]] [[package]]
name = "chrono" name = "chrono"
version = "0.4.11" version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" checksum = "f0fee792e164f78f5fe0c296cc2eb3688a2ca2b70cdff33040922d298203f0c4"
dependencies = [ dependencies = [
"num-integer", "num-integer",
"num-traits 0.2.12", "num-traits 0.2.12",
@ -726,6 +732,15 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "cloudabi"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
dependencies = [
"bitflags",
]
[[package]] [[package]]
name = "comrak" name = "comrak"
version = "0.7.0" version = "0.7.0"
@ -1120,14 +1135,14 @@ dependencies = [
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.14" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" checksum = "68c90b0fc46cf89d227cc78b40e494ff81287a92dd07631e5af0d06fe3cf885e"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crc32fast", "crc32fast",
"libc", "libc",
"miniz_oxide", "miniz_oxide 0.4.0",
] ]
[[package]] [[package]]
@ -1470,6 +1485,12 @@ dependencies = [
"autocfg 1.0.0", "autocfg 1.0.0",
] ]
[[package]]
name = "instant"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69da7ce1490173c2bf4d26bc8be429aaeeaf4cce6c4b970b7949651fa17655fe"
[[package]] [[package]]
name = "iovec" name = "iovec"
version = "0.1.4" version = "0.1.4"
@ -1508,18 +1529,18 @@ checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.40" version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce10c23ad2ea25ceca0093bd3192229da4c5b3c0f2de499c1ecac0d98d452177" checksum = "c4b9172132a62451e56142bff9afc91c8e4a4500aa5b847da36815b63bfda916"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]] [[package]]
name = "jsonwebtoken" name = "jsonwebtoken"
version = "7.1.2" version = "7.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f325ae57ddcf609f02d891486ce740f5bbd0cc3e93f9bffaacdf6594b21404" checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32"
dependencies = [ dependencies = [
"base64 0.12.3", "base64 0.12.3",
"pem", "pem",
@ -1676,6 +1697,15 @@ dependencies = [
"scopeguard", "scopeguard",
] ]
[[package]]
name = "lock_api"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de302ce1fe7482db13738fbaf2e21cfb06a986b89c0bf38d88abf16681aada4e"
dependencies = [
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.8" version = "0.4.8"
@ -1781,6 +1811,15 @@ dependencies = [
"adler32", "adler32",
] ]
[[package]]
name = "miniz_oxide"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
dependencies = [
"adler",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.6.22" version = "0.6.22"
@ -1985,8 +2024,19 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
dependencies = [ dependencies = [
"lock_api", "lock_api 0.3.4",
"parking_lot_core", "parking_lot_core 0.7.2",
]
[[package]]
name = "parking_lot"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
dependencies = [
"instant",
"lock_api 0.4.0",
"parking_lot_core 0.8.0",
] ]
[[package]] [[package]]
@ -1996,7 +2046,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cloudabi", "cloudabi 0.0.3",
"libc",
"redox_syscall",
"smallvec",
"winapi 0.3.9",
]
[[package]]
name = "parking_lot_core"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
dependencies = [
"cfg-if",
"cloudabi 0.1.0",
"instant",
"libc", "libc",
"redox_syscall", "redox_syscall",
"smallvec", "smallvec",
@ -2164,12 +2229,12 @@ dependencies = [
[[package]] [[package]]
name = "r2d2" name = "r2d2"
version = "0.8.8" version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1497e40855348e4a8a40767d8e55174bce1e445a3ac9254ad44ad468ee0485af" checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f"
dependencies = [ dependencies = [
"log", "log",
"parking_lot", "parking_lot 0.11.0",
"scheduled-thread-pool", "scheduled-thread-pool",
] ]
@ -2306,7 +2371,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
dependencies = [ dependencies = [
"cloudabi", "cloudabi 0.0.3",
"fuchsia-cprng", "fuchsia-cprng",
"libc", "libc",
"rand_core 0.4.2", "rand_core 0.4.2",
@ -2462,11 +2527,11 @@ dependencies = [
[[package]] [[package]]
name = "scheduled-thread-pool" name = "scheduled-thread-pool"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0988d7fdf88d5e5fcf5923a0f1e8ab345f3e98ab4bc6bc45a2d5ff7f7458fbf6" checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7"
dependencies = [ dependencies = [
"parking_lot", "parking_lot 0.11.0",
] ]
[[package]] [[package]]
@ -2570,9 +2635,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.55" version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226" checksum = "3433e879a558dde8b5e8feb2a04899cf34fdde1fafb894687e52105fc1162ac3"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"itoa", "itoa",
@ -3106,9 +3171,9 @@ checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.7" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
@ -3222,9 +3287,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.63" version = "0.2.64"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c2dc4aa152834bc334f506c1a06b866416a8b6697d5c9f75b9a689c8486def0" checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"wasm-bindgen-macro", "wasm-bindgen-macro",
@ -3232,9 +3297,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.63" version = "0.2.64"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded84f06e0ed21499f6184df0e0cb3494727b0c5da89534e0fcc55c51d812101" checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"lazy_static", "lazy_static",
@ -3247,9 +3312,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.63" version = "0.2.64"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "838e423688dac18d73e31edce74ddfac468e37b1506ad163ffaf0a46f703ffe3" checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@ -3257,9 +3322,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.63" version = "0.2.64"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3156052d8ec77142051a533cdd686cba889537b213f948cd1d20869926e68e92" checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -3270,15 +3335,15 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.63" version = "0.2.64"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9ba19973a58daf4db6f352eda73dc0e289493cd29fb2632eb172085b6521acd" checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae"
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.40" version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b72fe77fd39e4bd3eaa4412fd299a0be6b3dfe9d2597e2f1c20beb968f41d17" checksum = "863539788676619aac1a23e2df3655e96b32b0e05eb72ca34ba045ad573c625d"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",

View file

@ -123,7 +123,7 @@ impl FromApub for CommentForm {
/// Parse an ActivityPub note received from another instance into a Lemmy comment /// Parse an ActivityPub note received from another instance into a Lemmy comment
async fn from_apub( async fn from_apub(
note: &Note, note: &mut Note,
client: &Client, client: &Client,
pool: &DbPool, pool: &DbPool,
) -> Result<CommentForm, LemmyError> { ) -> Result<CommentForm, LemmyError> {

View file

@ -4,7 +4,7 @@ use crate::{
create_apub_response, create_apub_response,
create_apub_tombstone_response, create_apub_tombstone_response,
create_tombstone, create_tombstone,
extensions::{group_extensions::GroupExtension, signatures::PublicKey}, extensions::group_extensions::GroupExtension,
fetcher::get_or_fetch_and_upsert_remote_user, fetcher::get_or_fetch_and_upsert_remote_user,
get_shared_inbox, get_shared_inbox,
ActorType, ActorType,
@ -27,21 +27,25 @@ use crate::{
}; };
use activitystreams::{ use activitystreams::{
activity::{Accept, Announce, Delete, Remove, Undo}, activity::{Accept, Announce, Delete, Remove, Undo},
actor::{kind::GroupType, properties::ApActorProperties, Group},
collection::UnorderedCollection,
context,
endpoint::EndpointProperties,
object::properties::ObjectProperties,
Activity, Activity,
Base, Base,
BaseBox, BaseBox,
}; };
use activitystreams_ext::Ext3; use activitystreams_ext::Ext2;
use activitystreams_new::{activity::Follow, object::Tombstone}; use activitystreams_new::{
activity::Follow,
actor::{kind::GroupType, ApActor, Endpoints, Group},
base::BaseExt,
collection::UnorderedCollection,
context,
object::Tombstone,
prelude::*,
primitives::{XsdAnyUri, XsdDateTime},
};
use actix_web::{body::Body, client::Client, web, HttpResponse}; use actix_web::{body::Body, client::Client, web, HttpResponse};
use itertools::Itertools; use itertools::Itertools;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt::Debug; use std::{fmt::Debug, str::FromStr};
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct CommunityQuery { pub struct CommunityQuery {
@ -54,9 +58,6 @@ impl ToApub for Community {
// Turn a Lemmy Community into an ActivityPub group that can be sent out over the network. // Turn a Lemmy Community into an ActivityPub group that can be sent out over the network.
async fn to_apub(&self, pool: &DbPool) -> Result<GroupExt, LemmyError> { async fn to_apub(&self, pool: &DbPool) -> Result<GroupExt, LemmyError> {
let mut group = Group::default();
let oprops: &mut ObjectProperties = group.as_mut();
// The attributed to, is an ordered vector with the creator actor_ids first, // The attributed to, is an ordered vector with the creator actor_ids first,
// then the rest of the moderators // then the rest of the moderators
// TODO Technically the instance admins can mod the community, but lets // TODO Technically the instance admins can mod the community, but lets
@ -66,36 +67,36 @@ impl ToApub for Community {
CommunityModeratorView::for_community(&conn, id) CommunityModeratorView::for_community(&conn, id)
}) })
.await??; .await??;
let moderators = moderators.into_iter().map(|m| m.user_actor_id).collect(); let moderators: Vec<String> = moderators.into_iter().map(|m| m.user_actor_id).collect();
oprops let mut group = Group::new();
.set_context_xsd_any_uri(context())? group
.set_id(self.actor_id.to_owned())? .set_context(context())
.set_name_xsd_string(self.name.to_owned())? .set_id(XsdAnyUri::from_str(&self.actor_id)?)
.set_published(convert_datetime(self.published))? .set_name(self.name.to_owned())
.set_many_attributed_to_xsd_any_uris(moderators)?; .set_published(XsdDateTime::from(convert_datetime(self.published)))
.set_many_attributed_tos(moderators);
if let Some(u) = self.updated.to_owned() { if let Some(u) = self.updated.to_owned() {
oprops.set_updated(convert_datetime(u))?; group.set_updated(XsdDateTime::from(convert_datetime(u)));
} }
if let Some(d) = self.description.to_owned() { if let Some(d) = self.description.to_owned() {
// TODO: this should be html, also add source field with raw markdown // TODO: this should be html, also add source field with raw markdown
// -> same for post.content and others // -> same for post.content and others
oprops.set_content_xsd_string(d)?; group.set_content(d);
} }
let mut endpoint_props = EndpointProperties::default(); let mut ap_actor = ApActor::new(self.get_inbox_url().parse()?, group);
ap_actor
endpoint_props.set_shared_inbox(self.get_shared_inbox_url())?; .set_preferred_username(self.title.to_owned())
.set_outbox(self.get_outbox_url().parse()?)
let mut actor_props = ApActorProperties::default(); .set_followers(self.get_followers_url().parse()?)
.set_following(self.get_following_url().parse()?)
actor_props .set_liked(self.get_liked_url().parse()?)
.set_preferred_username(self.title.to_owned())? .set_endpoints(Endpoints {
.set_inbox(self.get_inbox_url())? shared_inbox: Some(self.get_shared_inbox_url().parse()?),
.set_outbox(self.get_outbox_url())? ..Default::default()
.set_endpoints(endpoint_props)? });
.set_followers(self.get_followers_url())?;
let nsfw = self.nsfw; let nsfw = self.nsfw;
let category_id = self.category_id; let category_id = self.category_id;
@ -104,10 +105,9 @@ impl ToApub for Community {
}) })
.await??; .await??;
Ok(Ext3::new( Ok(Ext2::new(
group, ap_actor,
group_extension, group_extension,
actor_props,
self.get_public_key_ext(), self.get_public_key_ext(),
)) ))
} }
@ -367,38 +367,52 @@ impl FromApub for CommunityForm {
type ApubType = GroupExt; type ApubType = GroupExt;
/// Parse an ActivityPub group received from another instance into a Lemmy community. /// Parse an ActivityPub group received from another instance into a Lemmy community.
async fn from_apub(group: &GroupExt, client: &Client, pool: &DbPool) -> Result<Self, LemmyError> { async fn from_apub(
let group_extensions: &GroupExtension = &group.ext_one; group: &mut GroupExt,
let oprops = &group.inner.object_props; client: &Client,
let aprops = &group.ext_two; pool: &DbPool,
let public_key: &PublicKey = &group.ext_three.public_key; ) -> Result<Self, LemmyError> {
// TODO: this is probably gonna cause problems cause fetcher:292 also calls take_attributed_to()
let mut creator_and_moderator_uris = oprops.get_many_attributed_to_xsd_any_uris().unwrap(); let creator_and_moderator_uris = group.clone().take_attributed_to().unwrap();
let creator_uri = creator_and_moderator_uris.next().unwrap(); let creator_uri = creator_and_moderator_uris
.as_many()
.unwrap()
.iter()
.next()
.unwrap()
.as_xsd_any_uri()
.unwrap();
let creator = get_or_fetch_and_upsert_remote_user(creator_uri.as_str(), client, pool).await?; let creator = get_or_fetch_and_upsert_remote_user(creator_uri.as_str(), client, pool).await?;
Ok(CommunityForm { Ok(CommunityForm {
name: oprops.get_name_xsd_string().unwrap().to_string(), name: group
title: aprops.get_preferred_username().unwrap().to_string(), .take_name()
.unwrap()
.as_single_xsd_string()
.unwrap()
.into(),
title: group.inner.take_preferred_username().unwrap(),
// TODO: should be parsed as html and tags like <script> removed (or use markdown source) // TODO: should be parsed as html and tags like <script> removed (or use markdown source)
// -> same for post.content etc // -> same for post.content etc
description: oprops.get_content_xsd_string().map(|s| s.to_string()), description: group
category_id: group_extensions.category.identifier.parse::<i32>()?, .take_content()
.map(|s| s.as_single_xsd_string().unwrap().into()),
category_id: group.ext_one.category.identifier.parse::<i32>()?,
creator_id: creator.id, creator_id: creator.id,
removed: None, removed: None,
published: oprops published: group
.get_published() .take_published()
.map(|u| u.as_ref().to_owned().naive_local()), .map(|u| u.as_ref().to_owned().naive_local()),
updated: oprops updated: group
.get_updated() .take_updated()
.map(|u| u.as_ref().to_owned().naive_local()), .map(|u| u.as_ref().to_owned().naive_local()),
deleted: None, deleted: None,
nsfw: group_extensions.sensitive, nsfw: group.ext_one.sensitive,
actor_id: oprops.get_id().unwrap().to_string(), actor_id: group.id().unwrap().to_string(),
local: false, local: false,
private_key: None, private_key: None,
public_key: Some(public_key.to_owned().public_key_pem), public_key: Some(group.ext_two.to_owned().public_key.public_key_pem),
last_refreshed_at: Some(naive_now()), last_refreshed_at: Some(naive_now()),
}) })
} }
@ -439,14 +453,12 @@ pub async fn get_apub_community_followers(
}) })
.await??; .await??;
let mut collection = UnorderedCollection::default(); let mut collection = UnorderedCollection::new(vec![]);
let oprops: &mut ObjectProperties = collection.as_mut();
oprops
.set_context_xsd_any_uri(context())?
.set_id(community.actor_id)?;
collection collection
.collection_props .set_context(context())
.set_total_items(community_followers.len() as u64)?; // TODO: this needs its own ID
.set_id(community.actor_id.parse()?)
.set_total_items(community_followers.len() as u64);
Ok(create_apub_response(&collection)) Ok(create_apub_response(&collection))
} }

View file

@ -1,13 +1,14 @@
use activitystreams::object::Note;
use actix_web::client::Client;
use diesel::{result::Error::NotFound, PgConnection};
use log::debug;
use serde::Deserialize;
use std::{fmt::Debug, time::Duration};
use url::Url;
use crate::{ use crate::{
api::site::SearchResponse, api::site::SearchResponse,
apub::{
get_apub_protocol_string,
is_apub_id_valid,
FromApub,
GroupExt,
PageExt,
PersonExt,
APUB_JSON_CONTENT_TYPE,
},
blocking, blocking,
db::{ db::{
comment::{Comment, CommentForm}, comment::{Comment, CommentForm},
@ -17,6 +18,7 @@ use crate::{
post::{Post, PostForm}, post::{Post, PostForm},
post_view::PostView, post_view::PostView,
user::{UserForm, User_}, user::{UserForm, User_},
user_view::UserView,
Crud, Crud,
Joinable, Joinable,
SearchType, SearchType,
@ -27,20 +29,15 @@ use crate::{
DbPool, DbPool,
LemmyError, LemmyError,
}; };
use activitystreams::object::Note;
use crate::{ use activitystreams_new::{base::BaseExt, prelude::*, primitives::XsdAnyUri};
apub::{ use actix_web::client::Client;
get_apub_protocol_string,
is_apub_id_valid,
FromApub,
GroupExt,
PageExt,
PersonExt,
APUB_JSON_CONTENT_TYPE,
},
db::user_view::UserView,
};
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use diesel::{result::Error::NotFound, PgConnection};
use log::debug;
use serde::Deserialize;
use std::{fmt::Debug, time::Duration};
use url::Url;
static ACTOR_REFETCH_INTERVAL_SECONDS: i64 = 24 * 60 * 60; static ACTOR_REFETCH_INTERVAL_SECONDS: i64 = 24 * 60 * 60;
@ -149,7 +146,7 @@ pub async fn search_by_apub_id(
let response = match fetch_remote_object::<SearchAcceptedObjects>(client, &query_url).await? { let response = match fetch_remote_object::<SearchAcceptedObjects>(client, &query_url).await? {
SearchAcceptedObjects::Person(p) => { SearchAcceptedObjects::Person(p) => {
let user_uri = p.inner.object_props.get_id().unwrap().to_string(); let user_uri = p.inner.id().unwrap().to_string();
let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?; let user = get_or_fetch_and_upsert_remote_user(&user_uri, client, pool).await?;
@ -158,7 +155,7 @@ pub async fn search_by_apub_id(
response response
} }
SearchAcceptedObjects::Group(g) => { SearchAcceptedObjects::Group(g) => {
let community_uri = g.inner.object_props.get_id().unwrap().to_string(); let community_uri = g.inner.id().unwrap().to_string();
let community = let community =
get_or_fetch_and_upsert_remote_community(&community_uri, client, pool).await?; get_or_fetch_and_upsert_remote_community(&community_uri, client, pool).await?;
@ -174,15 +171,15 @@ pub async fn search_by_apub_id(
response response
} }
SearchAcceptedObjects::Page(p) => { SearchAcceptedObjects::Page(mut p) => {
let post_form = PostForm::from_apub(&p, client, pool).await?; let post_form = PostForm::from_apub(&mut p, client, pool).await?;
let p = blocking(pool, move |conn| upsert_post(&post_form, conn)).await??; let p = blocking(pool, move |conn| upsert_post(&post_form, conn)).await??;
response.posts = vec![blocking(pool, move |conn| PostView::read(conn, p.id, None)).await??]; response.posts = vec![blocking(pool, move |conn| PostView::read(conn, p.id, None)).await??];
response response
} }
SearchAcceptedObjects::Comment(c) => { SearchAcceptedObjects::Comment(mut c) => {
let post_url = c let post_url = c
.object_props .object_props
.get_many_in_reply_to_xsd_any_uris() .get_many_in_reply_to_xsd_any_uris()
@ -192,9 +189,9 @@ pub async fn search_by_apub_id(
.to_string(); .to_string();
// TODO: also fetch parent comments if any // TODO: also fetch parent comments if any
let post = fetch_remote_object(client, &Url::parse(&post_url)?).await?; let mut post = fetch_remote_object(client, &Url::parse(&post_url)?).await?;
let post_form = PostForm::from_apub(&post, client, pool).await?; let post_form = PostForm::from_apub(&mut post, client, pool).await?;
let comment_form = CommentForm::from_apub(&c, client, pool).await?; let comment_form = CommentForm::from_apub(&mut c, client, pool).await?;
blocking(pool, move |conn| upsert_post(&post_form, conn)).await??; blocking(pool, move |conn| upsert_post(&post_form, conn)).await??;
let c = blocking(pool, move |conn| upsert_comment(&comment_form, conn)).await??; let c = blocking(pool, move |conn| upsert_comment(&comment_form, conn)).await??;
@ -224,9 +221,9 @@ pub async fn get_or_fetch_and_upsert_remote_user(
// If its older than a day, re-fetch it // If its older than a day, re-fetch it
Ok(u) if !u.local && should_refetch_actor(u.last_refreshed_at) => { Ok(u) if !u.local && should_refetch_actor(u.last_refreshed_at) => {
debug!("Fetching and updating from remote user: {}", apub_id); debug!("Fetching and updating from remote user: {}", apub_id);
let person = fetch_remote_object::<PersonExt>(client, &Url::parse(apub_id)?).await?; let mut person = fetch_remote_object::<PersonExt>(client, &Url::parse(apub_id)?).await?;
let mut uf = UserForm::from_apub(&person, client, pool).await?; let mut uf = UserForm::from_apub(&mut person, client, pool).await?;
uf.last_refreshed_at = Some(naive_now()); uf.last_refreshed_at = Some(naive_now());
let user = blocking(pool, move |conn| User_::update(conn, u.id, &uf)).await??; let user = blocking(pool, move |conn| User_::update(conn, u.id, &uf)).await??;
@ -235,9 +232,9 @@ pub async fn get_or_fetch_and_upsert_remote_user(
Ok(u) => Ok(u), Ok(u) => Ok(u),
Err(NotFound {}) => { Err(NotFound {}) => {
debug!("Fetching and creating remote user: {}", apub_id); debug!("Fetching and creating remote user: {}", apub_id);
let person = fetch_remote_object::<PersonExt>(client, &Url::parse(apub_id)?).await?; let mut person = fetch_remote_object::<PersonExt>(client, &Url::parse(apub_id)?).await?;
let uf = UserForm::from_apub(&person, client, pool).await?; let uf = UserForm::from_apub(&mut person, client, pool).await?;
let user = blocking(pool, move |conn| User_::create(conn, &uf)).await??; let user = blocking(pool, move |conn| User_::create(conn, &uf)).await??;
Ok(user) Ok(user)
@ -275,9 +272,9 @@ pub async fn get_or_fetch_and_upsert_remote_community(
match community { match community {
Ok(c) if !c.local && should_refetch_actor(c.last_refreshed_at) => { Ok(c) if !c.local && should_refetch_actor(c.last_refreshed_at) => {
debug!("Fetching and updating from remote community: {}", apub_id); debug!("Fetching and updating from remote community: {}", apub_id);
let group = fetch_remote_object::<GroupExt>(client, &Url::parse(apub_id)?).await?; let mut group = fetch_remote_object::<GroupExt>(client, &Url::parse(apub_id)?).await?;
let mut cf = CommunityForm::from_apub(&group, client, pool).await?; let mut cf = CommunityForm::from_apub(&mut group, client, pool).await?;
cf.last_refreshed_at = Some(naive_now()); cf.last_refreshed_at = Some(naive_now());
let community = blocking(pool, move |conn| Community::update(conn, c.id, &cf)).await??; let community = blocking(pool, move |conn| Community::update(conn, c.id, &cf)).await??;
@ -286,17 +283,19 @@ pub async fn get_or_fetch_and_upsert_remote_community(
Ok(c) => Ok(c), Ok(c) => Ok(c),
Err(NotFound {}) => { Err(NotFound {}) => {
debug!("Fetching and creating remote community: {}", apub_id); debug!("Fetching and creating remote community: {}", apub_id);
let group = fetch_remote_object::<GroupExt>(client, &Url::parse(apub_id)?).await?; let mut group = fetch_remote_object::<GroupExt>(client, &Url::parse(apub_id)?).await?;
let cf = CommunityForm::from_apub(&group, client, pool).await?; let cf = CommunityForm::from_apub(&mut group, client, pool).await?;
let community = blocking(pool, move |conn| Community::create(conn, &cf)).await??; let community = blocking(pool, move |conn| Community::create(conn, &cf)).await??;
// Also add the community moderators too // Also add the community moderators too
let creator_and_moderator_uris = group let attributed_to = group.inner.take_attributed_to().unwrap();
.inner let creator_and_moderator_uris: Vec<&XsdAnyUri> = attributed_to
.object_props .as_many()
.get_many_attributed_to_xsd_any_uris() .unwrap()
.unwrap(); .iter()
.map(|a| a.as_xsd_any_uri().unwrap())
.collect();
let mut creator_and_moderators = Vec::new(); let mut creator_and_moderators = Vec::new();
@ -350,8 +349,8 @@ pub async fn get_or_fetch_and_insert_remote_post(
Ok(p) => Ok(p), Ok(p) => Ok(p),
Err(NotFound {}) => { Err(NotFound {}) => {
debug!("Fetching and creating remote post: {}", post_ap_id); debug!("Fetching and creating remote post: {}", post_ap_id);
let post = fetch_remote_object::<PageExt>(client, &Url::parse(post_ap_id)?).await?; let mut post = fetch_remote_object::<PageExt>(client, &Url::parse(post_ap_id)?).await?;
let post_form = PostForm::from_apub(&post, client, pool).await?; let post_form = PostForm::from_apub(&mut post, client, pool).await?;
let post = blocking(pool, move |conn| Post::create(conn, &post_form)).await??; let post = blocking(pool, move |conn| Post::create(conn, &post_form)).await??;
@ -388,8 +387,8 @@ pub async fn get_or_fetch_and_insert_remote_comment(
"Fetching and creating remote comment and its parents: {}", "Fetching and creating remote comment and its parents: {}",
comment_ap_id comment_ap_id
); );
let comment = fetch_remote_object::<Note>(client, &Url::parse(comment_ap_id)?).await?; let mut comment = fetch_remote_object::<Note>(client, &Url::parse(comment_ap_id)?).await?;
let comment_form = CommentForm::from_apub(&comment, client, pool).await?; let comment_form = CommentForm::from_apub(&mut comment, client, pool).await?;
let comment = blocking(pool, move |conn| Comment::create(conn, &comment_form)).await??; let comment = blocking(pool, move |conn| Comment::create(conn, &comment_form)).await??;

View file

@ -25,20 +25,22 @@ use crate::{
MentionData, MentionData,
Settings, Settings,
}; };
use activitystreams::{ use activitystreams::object::Page;
actor::{properties::ApActorProperties, Group, Person}, use activitystreams_ext::{Ext1, Ext2};
object::Page, use activitystreams_new::{
activity::Follow,
actor::{ApActor, Group, Person},
object::Tombstone,
prelude::*,
}; };
use activitystreams_ext::{Ext1, Ext2, Ext3};
use activitystreams_new::{activity::Follow, object::Tombstone, prelude::*};
use actix_web::{body::Body, client::Client, HttpResponse}; use actix_web::{body::Body, client::Client, HttpResponse};
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use log::debug; use log::debug;
use serde::Serialize; use serde::Serialize;
use url::Url; use url::Url;
type GroupExt = Ext3<Group, GroupExtension, ApActorProperties, PublicKeyExtension>; type GroupExt = Ext2<ApActor<Group>, GroupExtension, PublicKeyExtension>;
type PersonExt = Ext2<Person, ApActorProperties, PublicKeyExtension>; type PersonExt = Ext1<ApActor<Person>, PublicKeyExtension>;
type PageExt = Ext1<Page, PageExtension>; type PageExt = Ext1<Page, PageExtension>;
pub static APUB_JSON_CONTENT_TYPE: &str = "application/activity+json"; pub static APUB_JSON_CONTENT_TYPE: &str = "application/activity+json";
@ -163,7 +165,7 @@ fn create_tombstone(
pub trait FromApub { pub trait FromApub {
type ApubType; type ApubType;
async fn from_apub( async fn from_apub(
apub: &Self::ApubType, apub: &mut Self::ApubType,
client: &Client, client: &Client,
pool: &DbPool, pool: &DbPool,
) -> Result<Self, LemmyError> ) -> Result<Self, LemmyError>

View file

@ -164,7 +164,7 @@ impl FromApub for PostForm {
/// Parse an ActivityPub page received from another instance into a Lemmy post. /// Parse an ActivityPub page received from another instance into a Lemmy post.
async fn from_apub( async fn from_apub(
page: &PageExt, page: &mut PageExt,
client: &Client, client: &Client,
pool: &DbPool, pool: &DbPool,
) -> Result<PostForm, LemmyError> { ) -> Result<PostForm, LemmyError> {

View file

@ -71,7 +71,7 @@ impl FromApub for PrivateMessageForm {
/// Parse an ActivityPub note received from another instance into a Lemmy Private message /// Parse an ActivityPub note received from another instance into a Lemmy Private message
async fn from_apub( async fn from_apub(
note: &Note, note: &mut Note,
client: &Client, client: &Client,
pool: &DbPool, pool: &DbPool,
) -> Result<PrivateMessageForm, LemmyError> { ) -> Result<PrivateMessageForm, LemmyError> {

View file

@ -335,7 +335,7 @@ async fn receive_create_post(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let page = create let mut page = create
.create_props .create_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -353,7 +353,7 @@ async fn receive_create_post(
insert_activity(user.id, create, false, pool).await?; insert_activity(user.id, create, false, pool).await?;
let post = PostForm::from_apub(&page, client, pool).await?; let post = PostForm::from_apub(&mut page, client, pool).await?;
let inserted_post = blocking(pool, move |conn| Post::create(conn, &post)).await??; let inserted_post = blocking(pool, move |conn| Post::create(conn, &post)).await??;
@ -381,7 +381,7 @@ async fn receive_create_comment(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let note = create let mut note = create
.create_props .create_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -399,7 +399,7 @@ async fn receive_create_comment(
insert_activity(user.id, create, false, pool).await?; insert_activity(user.id, create, false, pool).await?;
let comment = CommentForm::from_apub(&note, client, pool).await?; let comment = CommentForm::from_apub(&mut note, client, pool).await?;
let inserted_comment = blocking(pool, move |conn| Comment::create(conn, &comment)).await??; let inserted_comment = blocking(pool, move |conn| Comment::create(conn, &comment)).await??;
@ -440,7 +440,7 @@ async fn receive_update_post(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let page = update let mut page = update
.update_props .update_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -458,7 +458,7 @@ async fn receive_update_post(
insert_activity(user.id, update, false, pool).await?; insert_activity(user.id, update, false, pool).await?;
let post = PostForm::from_apub(&page, client, pool).await?; let post = PostForm::from_apub(&mut page, client, pool).await?;
let post_id = get_or_fetch_and_insert_remote_post(&post.ap_id, client, pool) let post_id = get_or_fetch_and_insert_remote_post(&post.ap_id, client, pool)
.await? .await?
@ -486,7 +486,7 @@ async fn receive_like_post(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let page = like let mut page = like
.like_props .like_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -500,7 +500,7 @@ async fn receive_like_post(
insert_activity(user.id, like, false, pool).await?; insert_activity(user.id, like, false, pool).await?;
let post = PostForm::from_apub(&page, client, pool).await?; let post = PostForm::from_apub(&mut page, client, pool).await?;
let post_id = get_or_fetch_and_insert_remote_post(&post.ap_id, client, pool) let post_id = get_or_fetch_and_insert_remote_post(&post.ap_id, client, pool)
.await? .await?
@ -537,7 +537,7 @@ async fn receive_dislike_post(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let page = dislike let mut page = dislike
.dislike_props .dislike_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -555,7 +555,7 @@ async fn receive_dislike_post(
insert_activity(user.id, dislike, false, pool).await?; insert_activity(user.id, dislike, false, pool).await?;
let post = PostForm::from_apub(&page, client, pool).await?; let post = PostForm::from_apub(&mut page, client, pool).await?;
let post_id = get_or_fetch_and_insert_remote_post(&post.ap_id, client, pool) let post_id = get_or_fetch_and_insert_remote_post(&post.ap_id, client, pool)
.await? .await?
@ -592,7 +592,7 @@ async fn receive_update_comment(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let note = update let mut note = update
.update_props .update_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -610,7 +610,7 @@ async fn receive_update_comment(
insert_activity(user.id, update, false, pool).await?; insert_activity(user.id, update, false, pool).await?;
let comment = CommentForm::from_apub(&note, client, pool).await?; let comment = CommentForm::from_apub(&mut note, client, pool).await?;
let comment_id = get_or_fetch_and_insert_remote_comment(&comment.ap_id, client, pool) let comment_id = get_or_fetch_and_insert_remote_comment(&comment.ap_id, client, pool)
.await? .await?
@ -651,7 +651,7 @@ async fn receive_like_comment(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let note = like let mut note = like
.like_props .like_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -665,7 +665,7 @@ async fn receive_like_comment(
insert_activity(user.id, like, false, pool).await?; insert_activity(user.id, like, false, pool).await?;
let comment = CommentForm::from_apub(&note, client, pool).await?; let comment = CommentForm::from_apub(&mut note, client, pool).await?;
let comment_id = get_or_fetch_and_insert_remote_comment(&comment.ap_id, client, pool) let comment_id = get_or_fetch_and_insert_remote_comment(&comment.ap_id, client, pool)
.await? .await?
@ -709,7 +709,7 @@ async fn receive_dislike_comment(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let note = dislike let mut note = dislike
.dislike_props .dislike_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -727,7 +727,7 @@ async fn receive_dislike_comment(
insert_activity(user.id, dislike, false, pool).await?; insert_activity(user.id, dislike, false, pool).await?;
let comment = CommentForm::from_apub(&note, client, pool).await?; let comment = CommentForm::from_apub(&mut note, client, pool).await?;
let comment_id = get_or_fetch_and_insert_remote_comment(&comment.ap_id, client, pool) let comment_id = get_or_fetch_and_insert_remote_comment(&comment.ap_id, client, pool)
.await? .await?
@ -777,7 +777,7 @@ async fn receive_delete_community(
.unwrap() .unwrap()
.to_string(); .to_string();
let group = delete let mut group = delete
.delete_props .delete_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -789,7 +789,7 @@ async fn receive_delete_community(
insert_activity(user.id, delete, false, pool).await?; insert_activity(user.id, delete, false, pool).await?;
let community_actor_id = CommunityForm::from_apub(&group, client, pool) let community_actor_id = CommunityForm::from_apub(&mut group, client, pool)
.await? .await?
.actor_id; .actor_id;
@ -854,7 +854,7 @@ async fn receive_remove_community(
.unwrap() .unwrap()
.to_string(); .to_string();
let group = remove let mut group = remove
.remove_props .remove_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -866,7 +866,7 @@ async fn receive_remove_community(
insert_activity(mod_.id, remove, false, pool).await?; insert_activity(mod_.id, remove, false, pool).await?;
let community_actor_id = CommunityForm::from_apub(&group, client, pool) let community_actor_id = CommunityForm::from_apub(&mut group, client, pool)
.await? .await?
.actor_id; .actor_id;
@ -931,7 +931,7 @@ async fn receive_delete_post(
.unwrap() .unwrap()
.to_string(); .to_string();
let page = delete let mut page = delete
.delete_props .delete_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -943,7 +943,7 @@ async fn receive_delete_post(
insert_activity(user.id, delete, false, pool).await?; insert_activity(user.id, delete, false, pool).await?;
let post_ap_id = PostForm::from_apub(&page, client, pool).await?.ap_id; let post_ap_id = PostForm::from_apub(&mut page, client, pool).await?.ap_id;
let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?;
@ -997,7 +997,7 @@ async fn receive_remove_post(
.unwrap() .unwrap()
.to_string(); .to_string();
let page = remove let mut page = remove
.remove_props .remove_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1009,7 +1009,7 @@ async fn receive_remove_post(
insert_activity(mod_.id, remove, false, pool).await?; insert_activity(mod_.id, remove, false, pool).await?;
let post_ap_id = PostForm::from_apub(&page, client, pool).await?.ap_id; let post_ap_id = PostForm::from_apub(&mut page, client, pool).await?.ap_id;
let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?;
@ -1063,7 +1063,7 @@ async fn receive_delete_comment(
.unwrap() .unwrap()
.to_string(); .to_string();
let note = delete let mut note = delete
.delete_props .delete_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1075,7 +1075,7 @@ async fn receive_delete_comment(
insert_activity(user.id, delete, false, pool).await?; insert_activity(user.id, delete, false, pool).await?;
let comment_ap_id = CommentForm::from_apub(&note, client, pool).await?.ap_id; let comment_ap_id = CommentForm::from_apub(&mut note, client, pool).await?.ap_id;
let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?;
@ -1131,7 +1131,7 @@ async fn receive_remove_comment(
.unwrap() .unwrap()
.to_string(); .to_string();
let note = remove let mut note = remove
.remove_props .remove_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1143,7 +1143,7 @@ async fn receive_remove_comment(
insert_activity(mod_.id, remove, false, pool).await?; insert_activity(mod_.id, remove, false, pool).await?;
let comment_ap_id = CommentForm::from_apub(&note, client, pool).await?.ap_id; let comment_ap_id = CommentForm::from_apub(&mut note, client, pool).await?.ap_id;
let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?;
@ -1259,7 +1259,7 @@ async fn receive_undo_delete_comment(
.unwrap() .unwrap()
.to_string(); .to_string();
let note = delete let mut note = delete
.delete_props .delete_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1271,7 +1271,7 @@ async fn receive_undo_delete_comment(
insert_activity(user.id, delete, false, pool).await?; insert_activity(user.id, delete, false, pool).await?;
let comment_ap_id = CommentForm::from_apub(&note, client, pool).await?.ap_id; let comment_ap_id = CommentForm::from_apub(&mut note, client, pool).await?.ap_id;
let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?;
@ -1327,7 +1327,7 @@ async fn receive_undo_remove_comment(
.unwrap() .unwrap()
.to_string(); .to_string();
let note = remove let mut note = remove
.remove_props .remove_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1339,7 +1339,7 @@ async fn receive_undo_remove_comment(
insert_activity(mod_.id, remove, false, pool).await?; insert_activity(mod_.id, remove, false, pool).await?;
let comment_ap_id = CommentForm::from_apub(&note, client, pool).await?.ap_id; let comment_ap_id = CommentForm::from_apub(&mut note, client, pool).await?.ap_id;
let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?; let comment = get_or_fetch_and_insert_remote_comment(&comment_ap_id, client, pool).await?;
@ -1395,7 +1395,7 @@ async fn receive_undo_delete_post(
.unwrap() .unwrap()
.to_string(); .to_string();
let page = delete let mut page = delete
.delete_props .delete_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1407,7 +1407,7 @@ async fn receive_undo_delete_post(
insert_activity(user.id, delete, false, pool).await?; insert_activity(user.id, delete, false, pool).await?;
let post_ap_id = PostForm::from_apub(&page, client, pool).await?.ap_id; let post_ap_id = PostForm::from_apub(&mut page, client, pool).await?.ap_id;
let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?;
@ -1461,7 +1461,7 @@ async fn receive_undo_remove_post(
.unwrap() .unwrap()
.to_string(); .to_string();
let page = remove let mut page = remove
.remove_props .remove_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1473,7 +1473,7 @@ async fn receive_undo_remove_post(
insert_activity(mod_.id, remove, false, pool).await?; insert_activity(mod_.id, remove, false, pool).await?;
let post_ap_id = PostForm::from_apub(&page, client, pool).await?.ap_id; let post_ap_id = PostForm::from_apub(&mut page, client, pool).await?.ap_id;
let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?; let post = get_or_fetch_and_insert_remote_post(&post_ap_id, client, pool).await?;
@ -1527,7 +1527,7 @@ async fn receive_undo_delete_community(
.unwrap() .unwrap()
.to_string(); .to_string();
let group = delete let mut group = delete
.delete_props .delete_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1539,7 +1539,7 @@ async fn receive_undo_delete_community(
insert_activity(user.id, delete, false, pool).await?; insert_activity(user.id, delete, false, pool).await?;
let community_actor_id = CommunityForm::from_apub(&group, client, pool) let community_actor_id = CommunityForm::from_apub(&mut group, client, pool)
.await? .await?
.actor_id; .actor_id;
@ -1604,7 +1604,7 @@ async fn receive_undo_remove_community(
.unwrap() .unwrap()
.to_string(); .to_string();
let group = remove let mut group = remove
.remove_props .remove_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1616,7 +1616,7 @@ async fn receive_undo_remove_community(
insert_activity(mod_.id, remove, false, pool).await?; insert_activity(mod_.id, remove, false, pool).await?;
let community_actor_id = CommunityForm::from_apub(&group, client, pool) let community_actor_id = CommunityForm::from_apub(&mut group, client, pool)
.await? .await?
.actor_id; .actor_id;
@ -1704,7 +1704,7 @@ async fn receive_undo_like_comment(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let note = like let mut note = like
.like_props .like_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1718,7 +1718,7 @@ async fn receive_undo_like_comment(
insert_activity(user.id, like, false, pool).await?; insert_activity(user.id, like, false, pool).await?;
let comment = CommentForm::from_apub(&note, client, pool).await?; let comment = CommentForm::from_apub(&mut note, client, pool).await?;
let comment_id = get_or_fetch_and_insert_remote_comment(&comment.ap_id, client, pool) let comment_id = get_or_fetch_and_insert_remote_comment(&comment.ap_id, client, pool)
.await? .await?
@ -1758,7 +1758,7 @@ async fn receive_undo_like_post(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let page = like let mut page = like
.like_props .like_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -1772,7 +1772,7 @@ async fn receive_undo_like_post(
insert_activity(user.id, like, false, pool).await?; insert_activity(user.id, like, false, pool).await?;
let post = PostForm::from_apub(&page, client, pool).await?; let post = PostForm::from_apub(&mut page, client, pool).await?;
let post_id = get_or_fetch_and_insert_remote_post(&post.ap_id, client, pool) let post_id = get_or_fetch_and_insert_remote_post(&post.ap_id, client, pool)
.await? .await?

View file

@ -1,13 +1,5 @@
use crate::{ use crate::{
apub::{ apub::{activities::send_activity, create_apub_response, ActorType, FromApub, PersonExt, ToApub},
activities::send_activity,
create_apub_response,
extensions::signatures::PublicKey,
ActorType,
FromApub,
PersonExt,
ToApub,
},
blocking, blocking,
convert_datetime, convert_datetime,
db::{ db::{
@ -19,20 +11,17 @@ use crate::{
DbPool, DbPool,
LemmyError, LemmyError,
}; };
use activitystreams::{ use activitystreams_ext::Ext1;
actor::{properties::ApActorProperties, Person},
context,
endpoint::EndpointProperties,
object::{properties::ObjectProperties, AnyImage, Image},
primitives::XsdAnyUri,
};
use activitystreams_ext::Ext2;
use activitystreams_new::{ use activitystreams_new::{
activity::{Follow, Undo}, activity::{Follow, Undo},
object::Tombstone, actor::{ApActor, Endpoints, Person},
context,
object::{Image, Tombstone},
prelude::*, prelude::*,
primitives::{XsdAnyUri, XsdDateTime},
}; };
use actix_web::{body::Body, client::Client, web, HttpResponse}; use actix_web::{body::Body, client::Client, web, HttpResponse};
use failure::_core::str::FromStr;
use serde::Deserialize; use serde::Deserialize;
#[derive(Deserialize)] #[derive(Deserialize)]
@ -47,46 +36,39 @@ impl ToApub for User_ {
// Turn a Lemmy Community into an ActivityPub group that can be sent out over the network. // Turn a Lemmy Community into an ActivityPub group that can be sent out over the network.
async fn to_apub(&self, _pool: &DbPool) -> Result<PersonExt, LemmyError> { async fn to_apub(&self, _pool: &DbPool) -> Result<PersonExt, LemmyError> {
// TODO go through all these to_string and to_owned() // TODO go through all these to_string and to_owned()
let mut person = Person::default(); let mut person = Person::new();
let oprops: &mut ObjectProperties = person.as_mut(); person
oprops .set_context(context())
.set_context_xsd_any_uri(context())? .set_id(XsdAnyUri::from_str(&self.actor_id)?)
.set_id(self.actor_id.to_string())? .set_name(self.name.to_owned())
.set_name_xsd_string(self.name.to_owned())? .set_published(XsdDateTime::from(convert_datetime(self.published)));
.set_published(convert_datetime(self.published))?;
if let Some(u) = self.updated { if let Some(u) = self.updated {
oprops.set_updated(convert_datetime(u))?; person.set_updated(XsdDateTime::from(convert_datetime(u)));
}
if let Some(i) = &self.preferred_username {
oprops.set_name_xsd_string(i.to_owned())?;
} }
if let Some(avatar_url) = &self.avatar { if let Some(avatar_url) = &self.avatar {
let mut image = Image::new(); let mut image = Image::new();
image image.set_url(avatar_url.to_owned());
.object_props person.set_icon(image.into_any_base()?);
.set_url_xsd_any_uri(avatar_url.to_owned())?;
let any_image = AnyImage::from_concrete(image)?;
oprops.set_icon_any_image(any_image)?;
} }
let mut endpoint_props = EndpointProperties::default(); let mut ap_actor = ApActor::new(self.get_inbox_url().parse()?, person);
ap_actor
.set_outbox(self.get_outbox_url().parse()?)
.set_followers(self.get_followers_url().parse()?)
.set_following(self.get_following_url().parse()?)
.set_liked(self.get_liked_url().parse()?)
.set_endpoints(Endpoints {
shared_inbox: Some(self.get_shared_inbox_url().parse()?),
..Default::default()
});
endpoint_props.set_shared_inbox(self.get_shared_inbox_url())?; if let Some(i) = &self.preferred_username {
ap_actor.set_preferred_username(i.to_owned());
}
let mut actor_props = ApActorProperties::default(); Ok(Ext1::new(ap_actor, self.get_public_key_ext()))
actor_props
.set_inbox(self.get_inbox_url())?
.set_outbox(self.get_outbox_url())?
.set_endpoints(endpoint_props)?
.set_followers(self.get_followers_url())?
.set_following(self.get_following_url())?
.set_liked(self.get_liked_url())?;
Ok(Ext2::new(person, actor_props, self.get_public_key_ext()))
} }
fn to_tombstone(&self) -> Result<Tombstone, LemmyError> { fn to_tombstone(&self) -> Result<Tombstone, LemmyError> {
unimplemented!() unimplemented!()
@ -203,31 +185,33 @@ impl ActorType for User_ {
impl FromApub for UserForm { impl FromApub for UserForm {
type ApubType = PersonExt; type ApubType = PersonExt;
/// Parse an ActivityPub person received from another instance into a Lemmy user. /// Parse an ActivityPub person received from another instance into a Lemmy user.
async fn from_apub(person: &PersonExt, _: &Client, _: &DbPool) -> Result<Self, LemmyError> { async fn from_apub(person: &mut PersonExt, _: &Client, _: &DbPool) -> Result<Self, LemmyError> {
let oprops = &person.inner.object_props; let avatar = match person.take_icon() {
let aprops = &person.ext_one; Some(any_image) => Image::from_any_base(any_image.as_one().unwrap().clone())
let public_key: &PublicKey = &person.ext_two.public_key; .unwrap()
.unwrap()
let avatar = match oprops.get_icon_any_image() { .url
Some(any_image) => any_image .unwrap()
.to_owned() .as_single_xsd_any_uri()
.into_concrete::<Image>()?
.object_props
.get_url_xsd_any_uri()
.map(|u| u.to_string()), .map(|u| u.to_string()),
None => None, None => None,
}; };
Ok(UserForm { Ok(UserForm {
name: oprops.get_name_xsd_string().unwrap().to_string(), name: person
preferred_username: aprops.get_preferred_username().map(|u| u.to_string()), .take_name()
.unwrap()
.as_single_xsd_string()
.unwrap()
.into(),
preferred_username: person.inner.take_preferred_username(),
password_encrypted: "".to_string(), password_encrypted: "".to_string(),
admin: false, admin: false,
banned: false, banned: false,
email: None, email: None,
avatar, avatar,
updated: oprops updated: person
.get_updated() .take_updated()
.map(|u| u.as_ref().to_owned().naive_local()), .map(|u| u.as_ref().to_owned().naive_local()),
show_nsfw: false, show_nsfw: false,
theme: "".to_string(), theme: "".to_string(),
@ -237,11 +221,13 @@ impl FromApub for UserForm {
show_avatars: false, show_avatars: false,
send_notifications_to_email: false, send_notifications_to_email: false,
matrix_user_id: None, matrix_user_id: None,
actor_id: oprops.get_id().unwrap().to_string(), actor_id: person.id().unwrap().to_string(),
bio: oprops.get_summary_xsd_string().map(|s| s.to_string()), bio: person
.take_summary()
.map(|s| s.as_single_xsd_string().unwrap().into()),
local: false, local: false,
private_key: None, private_key: None,
public_key: Some(public_key.to_owned().public_key_pem), public_key: Some(person.ext_one.public_key.to_owned().public_key_pem),
last_refreshed_at: Some(naive_now()), last_refreshed_at: Some(naive_now()),
}) })
} }

View file

@ -116,7 +116,7 @@ async fn receive_create_private_message(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let note = create let mut note = create
.create_props .create_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -135,7 +135,7 @@ async fn receive_create_private_message(
insert_activity(user.id, create, false, pool).await?; insert_activity(user.id, create, false, pool).await?;
let private_message = PrivateMessageForm::from_apub(&note, client, pool).await?; let private_message = PrivateMessageForm::from_apub(&mut note, client, pool).await?;
let inserted_private_message = blocking(pool, move |conn| { let inserted_private_message = blocking(pool, move |conn| {
PrivateMessage::create(conn, &private_message) PrivateMessage::create(conn, &private_message)
@ -168,7 +168,7 @@ async fn receive_update_private_message(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let note = update let mut note = update
.update_props .update_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -187,7 +187,7 @@ async fn receive_update_private_message(
insert_activity(user.id, update, false, pool).await?; insert_activity(user.id, update, false, pool).await?;
let private_message_form = PrivateMessageForm::from_apub(&note, client, pool).await?; let private_message_form = PrivateMessageForm::from_apub(&mut note, client, pool).await?;
let private_message_ap_id = private_message_form.ap_id.clone(); let private_message_ap_id = private_message_form.ap_id.clone();
let private_message = blocking(pool, move |conn| { let private_message = blocking(pool, move |conn| {
@ -228,7 +228,7 @@ async fn receive_delete_private_message(
pool: &DbPool, pool: &DbPool,
chat_server: ChatServerParam, chat_server: ChatServerParam,
) -> Result<HttpResponse, LemmyError> { ) -> Result<HttpResponse, LemmyError> {
let note = delete let mut note = delete
.delete_props .delete_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -247,7 +247,7 @@ async fn receive_delete_private_message(
insert_activity(user.id, delete, false, pool).await?; insert_activity(user.id, delete, false, pool).await?;
let private_message_form = PrivateMessageForm::from_apub(&note, client, pool).await?; let private_message_form = PrivateMessageForm::from_apub(&mut note, client, pool).await?;
let private_message_ap_id = private_message_form.ap_id; let private_message_ap_id = private_message_form.ap_id;
let private_message = blocking(pool, move |conn| { let private_message = blocking(pool, move |conn| {
@ -308,7 +308,7 @@ async fn receive_undo_delete_private_message(
.to_owned() .to_owned()
.into_concrete::<Delete>()?; .into_concrete::<Delete>()?;
let note = delete let mut note = delete
.delete_props .delete_props
.get_object_base_box() .get_object_base_box()
.to_owned() .to_owned()
@ -327,7 +327,7 @@ async fn receive_undo_delete_private_message(
insert_activity(user.id, delete, false, pool).await?; insert_activity(user.id, delete, false, pool).await?;
let private_message = PrivateMessageForm::from_apub(&note, client, pool).await?; let private_message = PrivateMessageForm::from_apub(&mut note, client, pool).await?;
let private_message_ap_id = private_message.ap_id.clone(); let private_message_ap_id = private_message.ap_id.clone();
let private_message_id = blocking(pool, move |conn| { let private_message_id = blocking(pool, move |conn| {