]> Untitled Git - lemmy.git/blobdiff - server/src/apub/user.rs
Merge branch 'main' into federation-authorisation
[lemmy.git] / server / src / apub / user.rs
index e60e469a9b364e02587e3b9483fc9108f4f6ed93..58338ab4da3c93d77a25e6679fd9724af7fd9c39 100644 (file)
@@ -1,7 +1,8 @@
 use crate::{
-  api::claims::Claims,
+  api::{check_slurs, check_slurs_opt},
   apub::{
-    activities::send_activity,
+    activities::{generate_activity_id, send_activity},
+    check_actor_domain,
     create_apub_response,
     insert_activity,
     ActorType,
@@ -14,14 +15,18 @@ use crate::{
   DbPool,
   LemmyError,
 };
-use activitystreams_ext::Ext1;
-use activitystreams_new::{
-  activity::{Follow, Undo},
+use activitystreams::{
+  activity::{
+    kind::{FollowType, UndoType},
+    Follow,
+    Undo,
+  },
   actor::{ApActor, Endpoints, Person},
   context,
   object::{Image, Tombstone},
   prelude::*,
 };
+use activitystreams_ext::Ext1;
 use actix_web::{body::Body, client::Client, web, HttpResponse};
 use lemmy_db::{
   naive_now,
@@ -60,9 +65,19 @@ impl ToApub for User_ {
       person.set_icon(image.into_any_base()?);
     }
 
-    let mut ap_actor = ApActor::new(self.get_inbox_url().parse()?, person);
+    if let Some(banner_url) = &self.banner {
+      let mut image = Image::new();
+      image.set_url(banner_url.to_owned());
+      person.set_image(image.into_any_base()?);
+    }
+
+    if let Some(bio) = &self.bio {
+      person.set_summary(bio.to_owned());
+    }
+
+    let mut ap_actor = ApActor::new(self.get_inbox_url()?, person);
     ap_actor
-      .set_outbox(self.get_outbox_url().parse()?)
+      .set_outbox(self.get_outbox_url()?)
       .set_followers(self.get_followers_url().parse()?)
       .set_following(self.get_following_url().parse()?)
       .set_liked(self.get_liked_url().parse()?)
@@ -103,9 +118,10 @@ impl ActorType for User_ {
     client: &Client,
     pool: &DbPool,
   ) -> Result<(), LemmyError> {
-    let id = format!("{}/follow/{}", self.actor_id, uuid::Uuid::new_v4());
     let mut follow = Follow::new(self.actor_id.to_owned(), follow_actor_id);
-    follow.set_context(context()).set_id(id.parse()?);
+    follow
+      .set_context(context())
+      .set_id(generate_activity_id(FollowType::Follow)?);
     let to = format!("{}/inbox", follow_actor_id);
 
     insert_activity(self.id, follow.clone(), true, pool).await?;
@@ -120,17 +136,18 @@ impl ActorType for User_ {
     client: &Client,
     pool: &DbPool,
   ) -> Result<(), LemmyError> {
-    let id = format!("{}/follow/{}", self.actor_id, uuid::Uuid::new_v4());
     let mut follow = Follow::new(self.actor_id.to_owned(), follow_actor_id);
-    follow.set_context(context()).set_id(id.parse()?);
+    follow
+      .set_context(context())
+      .set_id(generate_activity_id(FollowType::Follow)?);
 
     let to = format!("{}/inbox", follow_actor_id);
 
-    // TODO
     // Undo that fake activity
-    let undo_id = format!("{}/undo/follow/{}", self.actor_id, uuid::Uuid::new_v4());
     let mut undo = Undo::new(Url::parse(&self.actor_id)?, follow.into_any_base()?);
-    undo.set_context(context()).set_id(undo_id.parse()?);
+    undo
+      .set_context(context())
+      .set_id(generate_activity_id(UndoType::Undo)?);
 
     insert_activity(self.id, undo.clone(), true, pool).await?;
 
@@ -200,34 +217,60 @@ impl FromApub for UserForm {
     person: &PersonExt,
     _: &Client,
     _: &DbPool,
-    actor_id: &Url,
+    expected_domain: Option<Url>,
   ) -> Result<Self, LemmyError> {
     let avatar = match person.icon() {
-      Some(any_image) => Image::from_any_base(any_image.as_one().unwrap().clone())
-        .unwrap()
-        .unwrap()
-        .url()
-        .unwrap()
-        .as_single_xsd_any_uri()
-        .map(|u| u.to_string()),
+      Some(any_image) => Some(
+        Image::from_any_base(any_image.as_one().unwrap().clone())
+          .unwrap()
+          .unwrap()
+          .url()
+          .unwrap()
+          .as_single_xsd_any_uri()
+          .map(|u| u.to_string()),
+      ),
       None => None,
     };
 
+    let banner = match person.image() {
+      Some(any_image) => Some(
+        Image::from_any_base(any_image.as_one().unwrap().clone())
+          .unwrap()
+          .unwrap()
+          .url()
+          .unwrap()
+          .as_single_xsd_any_uri()
+          .map(|u| u.to_string()),
+      ),
+      None => None,
+    };
+
+    let name = person
+      .name()
+      .unwrap()
+      .one()
+      .unwrap()
+      .as_xsd_string()
+      .unwrap()
+      .to_string();
+    let preferred_username = person.inner.preferred_username().map(|u| u.to_string());
+    let bio = person
+      .inner
+      .summary()
+      .map(|s| s.as_single_xsd_string().unwrap().into());
+    check_slurs(&name)?;
+    check_slurs_opt(&preferred_username)?;
+    check_slurs_opt(&bio)?;
+
     Ok(UserForm {
-      name: person
-        .name()
-        .unwrap()
-        .one()
-        .unwrap()
-        .as_xsd_string()
-        .unwrap()
-        .to_string(),
-      preferred_username: person.inner.preferred_username().map(|u| u.to_string()),
+      name,
+      preferred_username,
       password_encrypted: "".to_string(),
       admin: false,
       banned: false,
       email: None,
       avatar,
+      banner,
       updated: person.updated().map(|u| u.to_owned().naive_local()),
       show_nsfw: false,
       theme: "".to_string(),
@@ -237,11 +280,8 @@ impl FromApub for UserForm {
       show_avatars: false,
       send_notifications_to_email: false,
       matrix_user_id: None,
-      actor_id: person.id(actor_id.domain().unwrap())?.unwrap().to_string(),
-      bio: person
-        .inner
-        .summary()
-        .map(|s| s.as_single_xsd_string().unwrap().into()),
+      actor_id: check_actor_domain(person, expected_domain)?,
+      bio,
       local: false,
       private_key: None,
       public_key: Some(person.ext_one.public_key.to_owned().public_key_pem),
@@ -257,7 +297,7 @@ pub async fn get_apub_user_http(
 ) -> Result<HttpResponse<Body>, LemmyError> {
   let user_name = info.into_inner().user_name;
   let user = blocking(&db, move |conn| {
-    Claims::find_by_email_or_username(conn, &user_name)
+    User_::find_by_email_or_username(conn, &user_name)
   })
   .await??;
   let u = user.to_apub(&db).await?;