]> Untitled Git - lemmy.git/commitdiff
Serve post data in apub format, some cleanup
authorFelix Ableitner <me@nutomic.com>
Mon, 16 Mar 2020 18:19:04 +0000 (19:19 +0100)
committerFelix Ableitner <me@nutomic.com>
Mon, 16 Mar 2020 18:19:04 +0000 (19:19 +0100)
server/src/apub/community.rs
server/src/apub/mod.rs
server/src/apub/post.rs
server/src/apub/user.rs
server/src/routes/federation.rs

index 8c0fb16065e70e43906a28729b53d2e46a7bd965..31bf146afdaf6d496882e131000a7e4821daf21e 100644 (file)
@@ -1,4 +1,4 @@
-use crate::apub::{create_apub_response, make_apub_endpoint};
+use crate::apub::{create_apub_response, make_apub_endpoint, EndpointType};
 use crate::convert_datetime;
 use crate::db::community::Community;
 use crate::db::community_view::CommunityFollowerView;
@@ -28,7 +28,7 @@ pub async fn get_apub_community(
   db: web::Data<Pool<ConnectionManager<PgConnection>>>,
 ) -> Result<HttpResponse<Body>, Error> {
   let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
-  let base_url = make_apub_endpoint("c", &community.name);
+  let base_url = make_apub_endpoint(EndpointType::Community, &community.name);
 
   let mut group = Group::default();
   let oprops: &mut ObjectProperties = group.as_mut();
@@ -38,7 +38,10 @@ pub async fn get_apub_community(
     .set_id(base_url.to_owned())?
     .set_name_xsd_string(community.title.to_owned())?
     .set_published(convert_datetime(community.published))?
-    .set_attributed_to_xsd_any_uri(make_apub_endpoint("u", &community.creator_id))?;
+    .set_attributed_to_xsd_any_uri(make_apub_endpoint(
+      EndpointType::User,
+      &community.creator_id.to_string(),
+    ))?;
 
   if let Some(u) = community.updated.to_owned() {
     oprops.set_updated(convert_datetime(u))?;
@@ -61,7 +64,7 @@ pub async fn get_apub_community_followers(
   db: web::Data<Pool<ConnectionManager<PgConnection>>>,
 ) -> Result<HttpResponse<Body>, Error> {
   let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
-  let base_url = make_apub_endpoint("c", &community.name);
+  let base_url = make_apub_endpoint(EndpointType::Community, &community.name);
 
   let connection = establish_unpooled_connection();
   //As we are an object, we validated that the community id was valid
@@ -84,7 +87,7 @@ pub async fn get_apub_community_outbox(
   db: web::Data<Pool<ConnectionManager<PgConnection>>>,
 ) -> Result<HttpResponse<Body>, Error> {
   let community = Community::read_from_name(&&db.get()?, info.community_name.to_owned())?;
-  let base_url = make_apub_endpoint("c", &community.name);
+  let base_url = make_apub_endpoint(EndpointType::Community, &community.name);
 
   let connection = establish_unpooled_connection();
   //As we are an object, we validated that the community id was valid
index d648e902c4d34afe2a5aec290c92c3cfd144494e..c0e881af424133fbf6169a380c9cb78793fce67a 100644 (file)
@@ -6,7 +6,6 @@ use crate::Settings;
 
 use actix_web::body::Body;
 use actix_web::HttpResponse;
-use std::fmt::Display;
 use url::Url;
 
 fn create_apub_response(json_data: String) -> HttpResponse<Body> {
@@ -15,15 +14,25 @@ fn create_apub_response(json_data: String) -> HttpResponse<Body> {
     .body(json_data)
 }
 
-// TODO: this should take an enum community/user/post for `point`
-// TODO: also not sure what exactly `value` should be (numeric id, name string, ...)
-fn make_apub_endpoint<S: Display, T: Display>(point: S, value: T) -> Url {
+enum EndpointType {
+  Community,
+  User,
+  Post,
+}
+
+fn make_apub_endpoint(endpoint_type: EndpointType, name: &str) -> Url {
+  let point = match endpoint_type {
+    EndpointType::Community => "c",
+    EndpointType::User => "u",
+    EndpointType::Post => "p",
+  };
+
   Url::parse(&format!(
     "{}://{}/federation/{}/{}",
     get_apub_protocol_string(),
     Settings::get().hostname,
     point,
-    value
+    name
   ))
   .unwrap()
 }
index 61b5a78dae76fff95c610c897693f19d48109a04..06340396ed5dcc0d3d1780e071c7b90ebf4585f7 100644 (file)
@@ -1,12 +1,35 @@
-use crate::apub::make_apub_endpoint;
+use crate::apub::{create_apub_response, make_apub_endpoint, EndpointType};
 use crate::convert_datetime;
 use crate::db::post_view::PostView;
 use activitystreams::{object::apub::Page, object::properties::ObjectProperties};
+use actix_web::body::Body;
+use actix_web::web::Path;
+use actix_web::{web, HttpResponse};
+use diesel::r2d2::{ConnectionManager, Pool};
+use diesel::PgConnection;
 use failure::Error;
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+pub struct PostQuery {
+  post_id: String,
+}
+
+pub async fn get_apub_post(
+  info: Path<PostQuery>,
+  db: web::Data<Pool<ConnectionManager<PgConnection>>>,
+) -> Result<HttpResponse<Body>, Error> {
+  let id = info.post_id.parse::<i32>()?;
+  // TODO: shows error: missing field `user_name`
+  let post = PostView::read(&&db.get()?, id, None)?;
+  Ok(create_apub_response(serde_json::to_string(
+    &post.as_page()?,
+  )?))
+}
 
 impl PostView {
   pub fn as_page(&self) -> Result<Page, Error> {
-    let base_url = make_apub_endpoint("post", self.id);
+    let base_url = make_apub_endpoint(EndpointType::Post, &self.id.to_string());
     let mut page = Page::default();
     let oprops: &mut ObjectProperties = page.as_mut();
 
@@ -16,16 +39,20 @@ impl PostView {
       .set_id(base_url)?
       .set_name_xsd_string(self.name.to_owned())?
       .set_published(convert_datetime(self.published))?
-      .set_attributed_to_xsd_any_uri(make_apub_endpoint("u", &self.creator_id))?;
+      .set_attributed_to_xsd_any_uri(make_apub_endpoint(
+        EndpointType::User,
+        &self.creator_id.to_string(),
+      ))?;
 
     if let Some(body) = &self.body {
       oprops.set_content_xsd_string(body.to_owned())?;
     }
 
     // TODO: hacky code because we get self.url == Some("")
-    let url = self.url.as_ref();
-    if url.is_some() && !url.unwrap().is_empty() {
-      oprops.set_url_xsd_any_uri(url.unwrap().to_owned())?;
+    // https://github.com/dessalines/lemmy/issues/602
+    let url = self.url.as_ref().filter(|u| !u.is_empty());
+    if let Some(u) = url {
+      oprops.set_url_xsd_any_uri(u.to_owned())?;
     }
 
     if let Some(u) = self.updated {
@@ -35,5 +62,3 @@ impl PostView {
     Ok(page)
   }
 }
-
-// TODO: need to serve this via actix
index 005ca9de74ee43ff072dc1fdce755a4ef23b156a..0bc90b0ccce9c93cd4e6af6050d4092b9c33049e 100644 (file)
@@ -1,15 +1,15 @@
-use crate::apub::{make_apub_endpoint, create_apub_response};
+use crate::apub::{create_apub_response, make_apub_endpoint, EndpointType};
 use crate::convert_datetime;
 use crate::db::user::User_;
 use activitystreams::{actor::apub::Person, context, object::properties::ObjectProperties};
 use actix_web::body::Body;
 use actix_web::web::Path;
 use actix_web::HttpResponse;
-use failure::Error;
-use serde::Deserialize;
+use actix_web::{web, Result};
 use diesel::r2d2::{ConnectionManager, Pool};
 use diesel::PgConnection;
-use actix_web::{web, Result};
+use failure::Error;
+use serde::Deserialize;
 
 #[derive(Deserialize)]
 pub struct UserQuery {
@@ -18,16 +18,17 @@ pub struct UserQuery {
 
 pub async fn get_apub_user(
   info: Path<UserQuery>,
-  db: web::Data<Pool<ConnectionManager<PgConnection>>>,) -> Result<HttpResponse<Body>, Error> {
+  db: web::Data<Pool<ConnectionManager<PgConnection>>>,
+) -> Result<HttpResponse<Body>, Error> {
   let user = User_::find_by_email_or_username(&&db.get()?, &info.user_name)?;
-  let base_url = make_apub_endpoint("u", &user.name);
+  let base_url = make_apub_endpoint(EndpointType::User, &user.name);
 
   let mut person = Person::default();
   let oprops: &mut ObjectProperties = person.as_mut();
   oprops
-      .set_context_xsd_any_uri(context())?
-      .set_id(base_url.to_string())?
-      .set_published(convert_datetime(user.published))?;
+    .set_context_xsd_any_uri(context())?
+    .set_id(base_url.to_string())?
+    .set_published(convert_datetime(user.published))?;
 
   if let Some(u) = user.updated {
     oprops.set_updated(convert_datetime(u))?;
@@ -38,11 +39,11 @@ pub async fn get_apub_user(
   }
 
   person
-      .ap_actor_props
-      .set_inbox(format!("{}/inbox", &base_url))?
-      .set_outbox(format!("{}/outbox", &base_url))?
-      .set_following(format!("{}/following", &base_url))?
-      .set_liked(format!("{}/liked", &base_url))?;
+    .ap_actor_props
+    .set_inbox(format!("{}/inbox", &base_url))?
+    .set_outbox(format!("{}/outbox", &base_url))?
+    .set_following(format!("{}/following", &base_url))?
+    .set_liked(format!("{}/liked", &base_url))?;
 
   Ok(create_apub_response(serde_json::to_string(&person)?))
 }
index 99b4d2c0beed03d6d5234fd64338f919654c8f5d..fbe8d795a3849c793ec781f0ab9fc01ee0b652f0 100644 (file)
@@ -28,6 +28,10 @@ pub fn config(cfg: &mut web::ServiceConfig) {
         "/federation/u/{user_name}",
         web::get().to(apub::user::get_apub_user),
       )
+      .route(
+        "/federation/p/{post_id}",
+        web::get().to(apub::user::get_apub_user),
+      )
       // TODO: we should be able to remove this but somehow that breaks the remote community list
       .route(
         "/api/v1/communities/list",