]> Untitled Git - lemmy.git/commitdiff
Federate community category and nsfw
authorFelix <me@nutomic.com>
Tue, 5 May 2020 14:30:13 +0000 (16:30 +0200)
committerFelix <me@nutomic.com>
Tue, 5 May 2020 14:30:13 +0000 (16:30 +0200)
server/src/api/mod.rs
server/src/apub/community.rs
server/src/apub/extensions/group_extensions.rs [new file with mode: 0644]
server/src/apub/extensions/mod.rs [new file with mode: 0644]
server/src/apub/extensions/page_extension.rs [moved from server/src/apub/page_extension.rs with 69% similarity]
server/src/apub/extensions/signatures.rs [moved from server/src/apub/signatures.rs with 90% similarity]
server/src/apub/fetcher.rs
server/src/apub/mod.rs
server/src/db/code_migrations.rs

index 8bc03feea5e250d824cae64a5a1e69f59776bce7..9112a3be32829febd3b3888c915b48d0059d92db 100644 (file)
@@ -23,8 +23,8 @@ use crate::{
 };
 
 use crate::apub::{
+  extensions::signatures::generate_actor_keypair,
   fetcher::search_by_apub_id,
-  signatures::generate_actor_keypair,
   {make_apub_endpoint, ActorType, ApubLikeableType, ApubObjectType, EndpointType},
 };
 use crate::settings::Settings;
index feffa70ef9b089819853a4cb5b9caa7baa57fa7f..f7cd213d3e523eb5aaba2ac6c170f3f2b7e6f3f8 100644 (file)
@@ -51,7 +51,14 @@ impl ToApub for Community {
       .set_endpoints(endpoint_props)?
       .set_followers(self.get_followers_url())?;
 
-    Ok(group.extend(actor_props).extend(self.get_public_key_ext()))
+    let group_extension = GroupExtension::new(conn, self.category_id, self.nsfw)?;
+
+    Ok(
+      group
+        .extend(group_extension)
+        .extend(actor_props)
+        .extend(self.get_public_key_ext()),
+    )
   }
 
   fn to_tombstone(&self) -> Result<Tombstone, Error> {
@@ -304,7 +311,8 @@ impl FromApub for CommunityForm {
 
   /// Parse an ActivityPub group received from another instance into a Lemmy community.
   fn from_apub(group: &GroupExt, conn: &PgConnection) -> Result<Self, Error> {
-    let oprops = &group.base.base.object_props;
+    let group_extensions: &GroupExtension = &group.base.base.extension;
+    let oprops = &group.base.base.base.object_props;
     let aprops = &group.base.extension;
     let public_key: &PublicKey = &group.extension.public_key;
 
@@ -325,7 +333,7 @@ impl FromApub for CommunityForm {
       // TODO: should be parsed as html and tags like <script> removed (or use markdown source)
       //       -> same for post.content etc
       description: oprops.get_content_xsd_string().map(|s| s.to_string()),
-      category_id: 1, // -> peertube uses `"category": {"identifier": "9","name": "Comedy"},`
+      category_id: group_extensions.category.identifier.parse::<i32>()?,
       creator_id: creator.id,
       removed: None,
       published: oprops
@@ -335,7 +343,7 @@ impl FromApub for CommunityForm {
         .get_updated()
         .map(|u| u.as_ref().to_owned().naive_local()),
       deleted: None,
-      nsfw: false,
+      nsfw: group_extensions.sensitive,
       actor_id: oprops.get_id().unwrap().to_string(),
       local: false,
       private_key: None,
diff --git a/server/src/apub/extensions/group_extensions.rs b/server/src/apub/extensions/group_extensions.rs
new file mode 100644 (file)
index 0000000..10cee5c
--- /dev/null
@@ -0,0 +1,42 @@
+use crate::db::category::Category;
+use crate::db::Crud;
+use activitystreams::ext::Extension;
+use activitystreams::Actor;
+use diesel::PgConnection;
+use failure::Error;
+use serde::{Deserialize, Serialize};
+
+#[derive(Clone, Debug, Default, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GroupExtension {
+  pub category: GroupCategory,
+  pub sensitive: bool,
+}
+
+#[derive(Clone, Debug, Default, Deserialize, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct GroupCategory {
+  // Using a string because that's how Peertube does it.
+  pub identifier: String,
+  pub name: String,
+}
+
+impl GroupExtension {
+  pub fn new(
+    conn: &PgConnection,
+    category_id: i32,
+    sensitive: bool,
+  ) -> Result<GroupExtension, Error> {
+    let category = Category::read(conn, category_id)?;
+    let group_category = GroupCategory {
+      identifier: category_id.to_string(),
+      name: category.name,
+    };
+    Ok(GroupExtension {
+      category: group_category,
+      sensitive,
+    })
+  }
+}
+
+impl<T> Extension<T> for GroupExtension where T: Actor {}
diff --git a/server/src/apub/extensions/mod.rs b/server/src/apub/extensions/mod.rs
new file mode 100644 (file)
index 0000000..fdd06e5
--- /dev/null
@@ -0,0 +1,3 @@
+pub mod group_extensions;
+pub mod page_extension;
+pub mod signatures;
similarity index 69%
rename from server/src/apub/page_extension.rs
rename to server/src/apub/extensions/page_extension.rs
index 03b145ec843a91d8ab7cf6c2f2a20c2cd4016bb7..435a869a9c3894391cb0782be17393d38c5e9fba 100644 (file)
@@ -1,4 +1,6 @@
-use super::*;
+use activitystreams::ext::Extension;
+use activitystreams::Base;
+use serde::{Deserialize, Serialize};
 
 #[derive(Clone, Debug, Default, Deserialize, Serialize)]
 #[serde(rename_all = "camelCase")]
similarity index 90%
rename from server/src/apub/signatures.rs
rename to server/src/apub/extensions/signatures.rs
index cf064603bb5d5b989143b5d37f5f75688ae8ae70..d89e0dd30b2082534afcc695235d4e76c5a386a7 100644 (file)
@@ -1,4 +1,15 @@
-use super::*;
+use activitystreams::ext::Extension;
+use activitystreams::Actor;
+use actix_web::HttpRequest;
+use failure::Error;
+use http::request::Builder;
+use http_signature_normalization::Config;
+use log::debug;
+use openssl::hash::MessageDigest;
+use openssl::sign::{Signer, Verifier};
+use openssl::{pkey::PKey, rsa::Rsa};
+use serde::{Deserialize, Serialize};
+use std::collections::BTreeMap;
 
 lazy_static! {
   static ref HTTP_SIG_CONFIG: Config = Config::new();
index 9db6755a2e2361dea44a2b2edd049479b5a21995..115ef6ff9378d04522cfeafc2a72450c6796f2b9 100644 (file)
@@ -89,7 +89,7 @@ pub fn search_by_apub_id(query: &str, conn: &PgConnection) -> Result<SearchRespo
       response.users = vec![UserView::read(conn, user.id)?];
     }
     SearchAcceptedObjects::Group(g) => {
-      let community_uri = g.base.base.object_props.get_id().unwrap().to_string();
+      let community_uri = g.base.base.base.object_props.get_id().unwrap().to_string();
       let community = get_or_fetch_and_upsert_remote_community(&community_uri, &conn)?;
       // TODO Maybe at some point in the future, fetch all the history of a community
       // fetch_community_outbox(&c, conn)?;
@@ -165,6 +165,7 @@ pub fn get_or_fetch_and_upsert_remote_community(
 
       // Also add the community moderators too
       let creator_and_moderator_uris = group
+        .base
         .base
         .base
         .object_props
index 3c6a00600185854dc92c5c033695d871a2488ace..8b4ceb79b58b33b0f5ec0be977ae65b935fbc54e 100644 (file)
@@ -2,11 +2,10 @@ pub mod activities;
 pub mod comment;
 pub mod community;
 pub mod community_inbox;
+pub mod extensions;
 pub mod fetcher;
-pub mod page_extension;
 pub mod post;
 pub mod shared_inbox;
-pub mod signatures;
 pub mod user;
 pub mod user_inbox;
 
@@ -15,11 +14,11 @@ use crate::websocket::server::SendCommunityRoomMessage;
 use activitystreams::object::kind::{NoteType, PageType};
 use activitystreams::{
   activity::{Accept, Create, Delete, Dislike, Follow, Like, Remove, Undo, Update},
-  actor::{kind::GroupType, properties::ApActorProperties, Actor, Group, Person},
+  actor::{kind::GroupType, properties::ApActorProperties, Group, Person},
   collection::UnorderedCollection,
   context,
   endpoint::EndpointProperties,
-  ext::{Ext, Extensible, Extension},
+  ext::{Ext, Extensible},
   object::{properties::ObjectProperties, Note, Page, Tombstone},
   public, BaseBox,
 };
@@ -30,16 +29,10 @@ use diesel::result::Error::NotFound;
 use diesel::PgConnection;
 use failure::Error;
 use failure::_core::fmt::Debug;
-use http::request::Builder;
-use http_signature_normalization::Config;
 use isahc::prelude::*;
 use itertools::Itertools;
 use log::debug;
-use openssl::hash::MessageDigest;
-use openssl::sign::{Signer, Verifier};
-use openssl::{pkey::PKey, rsa::Rsa};
 use serde::{Deserialize, Serialize};
-use std::collections::BTreeMap;
 use std::time::Duration;
 use url::Url;
 
@@ -66,15 +59,15 @@ use crate::websocket::{
 };
 use crate::{convert_datetime, naive_now, Settings};
 
-use crate::apub::page_extension::PageExtension;
+use crate::apub::extensions::group_extensions::GroupExtension;
+use crate::apub::extensions::page_extension::PageExtension;
 use activities::{populate_object_props, send_activity};
-use activitystreams::Base;
 use chrono::NaiveDateTime;
+use extensions::signatures::verify;
+use extensions::signatures::{sign, PublicKey, PublicKeyExtension};
 use fetcher::{get_or_fetch_and_upsert_remote_community, get_or_fetch_and_upsert_remote_user};
-use signatures::verify;
-use signatures::{sign, PublicKey, PublicKeyExtension};
 
-type GroupExt = Ext<Ext<Group, ApActorProperties>, PublicKeyExtension>;
+type GroupExt = Ext<Ext<Ext<Group, GroupExtension>, ApActorProperties>, PublicKeyExtension>;
 type PersonExt = Ext<Ext<Person, ApActorProperties>, PublicKeyExtension>;
 type PageExt = Ext<Page, PageExtension>;
 
index 605971996f56c06e331c48f1a6eee5fe0f940bf3..bdfc1a0d14d169c07c26264c06a9a4ec4ba2f88a 100644 (file)
@@ -4,7 +4,7 @@ use super::community::{Community, CommunityForm};
 use super::post::Post;
 use super::user::{UserForm, User_};
 use super::*;
-use crate::apub::signatures::generate_actor_keypair;
+use crate::apub::extensions::signatures::generate_actor_keypair;
 use crate::apub::{make_apub_endpoint, EndpointType};
 use crate::naive_now;
 use failure::Error;