From d831eb79e41dae5c85e66cb482c850df46f7ebdc Mon Sep 17 00:00:00 2001 From: silverpill Date: Sun, 10 Jul 2022 19:41:27 +0000 Subject: [PATCH] Add address() method to Actor type Returns ActorAddress object. --- src/activitypub/actor.rs | 29 +++++++++++++++++++++++++++++ src/activitypub/fetcher/helpers.rs | 19 +++---------------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/activitypub/actor.rs b/src/activitypub/actor.rs index 8321e32..061ffca 100644 --- a/src/activitypub/actor.rs +++ b/src/activitypub/actor.rs @@ -162,6 +162,22 @@ fn parse_extra_field( } impl Actor { + pub fn address( + &self, + this_instance_host: &str, + ) -> Result { + let actor_host = url::Url::parse(&self.id)? + .host_str() + .ok_or(url::ParseError::EmptyHost)? + .to_owned(); + let is_local = actor_host == this_instance_host; + let actor_address = ActorAddress { + username: self.preferred_username.clone(), + instance: actor_host, + is_local, + }; + Ok(actor_address) + } pub fn parse_attachments(&self) -> (Vec, Vec) { let mut identity_proofs = vec![]; @@ -365,8 +381,21 @@ mod tests { }; use super::*; + const INSTANCE_HOST: &str = "example.com"; const INSTANCE_URL: &str = "https://example.com"; + #[test] + fn test_get_actor_address() { + let actor = Actor { + id: "https://test.org/users/1".to_string(), + preferred_username: "test".to_string(), + ..Default::default() + }; + let actor_address = actor.address(INSTANCE_HOST).unwrap(); + assert_eq!(actor_address.is_local, false); + assert_eq!(actor_address.acct(), "test@test.org"); + } + #[test] fn test_local_actor() { let private_key = generate_weak_private_key().unwrap(); diff --git a/src/activitypub/fetcher/helpers.rs b/src/activitypub/fetcher/helpers.rs index c82b6ca..adaef24 100644 --- a/src/activitypub/fetcher/helpers.rs +++ b/src/activitypub/fetcher/helpers.rs @@ -56,35 +56,22 @@ impl From for HttpError { } } -fn get_actor_host(actor_id: &str) -> Result { - let actor_host = url::Url::parse(actor_id)? - .host_str() - .ok_or(url::ParseError::EmptyHost)? - .to_owned(); - Ok(actor_host) -} - async fn prepare_remote_profile_data( instance: &Instance, media_dir: &Path, actor: Actor, ) -> Result { - let actor_host = get_actor_host(&actor.id) + let actor_address = actor.address(&instance.host()) .map_err(|_| ValidationError("invalid actor ID"))?; - if actor_host == instance.host() { + if actor_address.is_local { return Err(ImportError::LocalObject); }; - let actor_address = format!( - "{}@{}", - actor.preferred_username, - actor_host, - ); let (avatar, banner) = fetch_avatar_and_banner(&actor, media_dir).await?; let (identity_proofs, extra_fields) = actor.parse_attachments(); let profile_data = ProfileCreateData { username: actor.preferred_username.clone(), display_name: actor.name.clone(), - acct: actor_address, + acct: actor_address.acct(), bio: actor.summary.clone(), avatar, banner,