Refactor ActorAddress type

This commit is contained in:
silverpill 2022-10-03 21:21:20 +00:00
parent cde324c07d
commit 429f530a71
5 changed files with 29 additions and 35 deletions

View file

@ -114,18 +114,15 @@ pub struct Actor {
impl Actor { impl Actor {
pub fn address( pub fn address(
&self, &self,
this_instance_host: &str,
) -> Result<ActorAddress, ValidationError> { ) -> Result<ActorAddress, ValidationError> {
let actor_host = url::Url::parse(&self.id) let actor_host = url::Url::parse(&self.id)
.map_err(|_| ValidationError("invalid actor ID"))? .map_err(|_| ValidationError("invalid actor ID"))?
.host_str() .host_str()
.ok_or(ValidationError("invalid actor ID"))? .ok_or(ValidationError("invalid actor ID"))?
.to_owned(); .to_owned();
let is_local = actor_host == this_instance_host;
let actor_address = ActorAddress { let actor_address = ActorAddress {
username: self.preferred_username.clone(), username: self.preferred_username.clone(),
instance: actor_host, instance: actor_host,
is_local,
}; };
Ok(actor_address) Ok(actor_address)
} }
@ -179,7 +176,6 @@ impl Actor {
pub struct ActorAddress { pub struct ActorAddress {
pub username: String, pub username: String,
pub instance: String, pub instance: String,
pub is_local: bool,
} }
impl ToString for ActorAddress { impl ToString for ActorAddress {
@ -189,9 +185,13 @@ impl ToString for ActorAddress {
} }
impl ActorAddress { impl ActorAddress {
pub fn is_local(&self, instance_host: &str) -> bool {
self.instance == instance_host
}
/// Returns acct string, as used in Mastodon /// Returns acct string, as used in Mastodon
pub fn acct(&self) -> String { pub fn acct(&self, instance_host: &str) -> String {
if self.is_local { if self.is_local(instance_host) {
self.username.clone() self.username.clone()
} else { } else {
self.to_string() self.to_string()
@ -337,9 +337,9 @@ mod tests {
preferred_username: "test".to_string(), preferred_username: "test".to_string(),
..Default::default() ..Default::default()
}; };
let actor_address = actor.address(INSTANCE_HOST).unwrap(); let actor_address = actor.address().unwrap();
assert_eq!(actor_address.is_local, false); assert_eq!(actor_address.is_local(INSTANCE_HOST), false);
assert_eq!(actor_address.acct(), "test@test.org"); assert_eq!(actor_address.acct(INSTANCE_HOST), "test@test.org");
} }
#[test] #[test]

View file

@ -63,8 +63,8 @@ async fn create_remote_profile(
media_dir: &Path, media_dir: &Path,
actor: Actor, actor: Actor,
) -> Result<DbActorProfile, ImportError> { ) -> Result<DbActorProfile, ImportError> {
let actor_address = actor.address(&instance.host())?; let actor_address = actor.address()?;
if actor_address.is_local { if actor_address.is_local(&instance.host()) {
return Err(ImportError::LocalObject); return Err(ImportError::LocalObject);
}; };
let avatar = fetch_actor_avatar(&actor, media_dir, None).await; let avatar = fetch_actor_avatar(&actor, media_dir, None).await;
@ -74,7 +74,7 @@ async fn create_remote_profile(
let mut profile_data = ProfileCreateData { let mut profile_data = ProfileCreateData {
username: actor.preferred_username.clone(), username: actor.preferred_username.clone(),
display_name: actor.name.clone(), display_name: actor.name.clone(),
acct: actor_address.acct(), acct: actor_address.acct(&instance.host()),
bio: actor.summary.clone(), bio: actor.summary.clone(),
avatar, avatar,
banner, banner,
@ -126,8 +126,9 @@ pub async fn get_or_import_profile_by_actor_id(
}, },
Err(DatabaseError::NotFound(_)) => { Err(DatabaseError::NotFound(_)) => {
let actor = fetch_actor(instance, actor_id).await?; let actor = fetch_actor(instance, actor_id).await?;
let actor_address = actor.address(&instance.host())?; let actor_address = actor.address()?;
match get_profile_by_acct(db_client, &actor_address.acct()).await { let acct = actor_address.acct(&instance.host());
match get_profile_by_acct(db_client, &acct).await {
Ok(profile) => { Ok(profile) => {
// WARNING: Possible actor ID change // WARNING: Possible actor ID change
log::info!("re-fetched profile {}", profile.acct); log::info!("re-fetched profile {}", profile.acct);
@ -140,7 +141,7 @@ pub async fn get_or_import_profile_by_actor_id(
profile_updated profile_updated
}, },
Err(DatabaseError::NotFound(_)) => { Err(DatabaseError::NotFound(_)) => {
log::info!("fetched profile {}", actor_address.acct()); log::info!("fetched profile {}", acct);
let profile = create_remote_profile( let profile = create_remote_profile(
db_client, db_client,
instance, instance,
@ -169,8 +170,8 @@ pub async fn import_profile_by_actor_address(
}; };
let actor_id = perform_webfinger_query(instance, actor_address).await?; let actor_id = perform_webfinger_query(instance, actor_address).await?;
let actor = fetch_actor(instance, &actor_id).await?; let actor = fetch_actor(instance, &actor_id).await?;
let profile_acct = actor.address(&instance.host())?.acct(); let profile_acct = actor.address()?.acct(&instance.host());
if profile_acct != actor_address.acct() { if profile_acct != actor_address.acct(&instance.host()) {
// Redirected to different server // Redirected to different server
match get_profile_by_acct(db_client, &profile_acct).await { match get_profile_by_acct(db_client, &profile_acct).await {
Ok(profile) => return Ok(profile), Ok(profile) => return Ok(profile),

View file

@ -266,13 +266,11 @@ pub async fn handle_note(
continue; continue;
}, },
}; };
if let Ok(actor_address) = mention_to_address( if let Ok(actor_address) = mention_to_address(&tag_name) {
&instance.host(), let acct = actor_address.acct(&instance.host());
&tag_name,
) {
let profile = match get_profile_by_acct( let profile = match get_profile_by_acct(
db_client, db_client,
&actor_address.acct(), &acct,
).await { ).await {
Ok(profile) => profile, Ok(profile) => profile,
Err(DatabaseError::NotFound(_)) => { Err(DatabaseError::NotFound(_)) => {
@ -287,7 +285,7 @@ pub async fn handle_note(
// Ignore mention if fetcher fails // Ignore mention if fetcher fails
log::warn!( log::warn!(
"failed to find mentioned profile {}: {}", "failed to find mentioned profile {}: {}",
actor_address.acct(), acct,
error, error,
); );
continue; continue;

View file

@ -111,7 +111,6 @@ async fn search_profiles_or_import(
let actor_address = ActorAddress { let actor_address = ActorAddress {
username: username, username: username,
instance: instance.unwrap(), instance: instance.unwrap(),
is_local: false,
}; };
match import_profile_by_actor_address( match import_profile_by_actor_address(
db_client, db_client,

View file

@ -26,9 +26,8 @@ fn find_mentions(
let actor_address = ActorAddress { let actor_address = ActorAddress {
username: caps["user"].to_string(), username: caps["user"].to_string(),
instance: secondary_caps["instance"].to_string(), instance: secondary_caps["instance"].to_string(),
is_local: &secondary_caps["instance"] == instance_host,
}; };
let acct = actor_address.acct(); let acct = actor_address.acct(instance_host);
if !mentions.contains(&acct) { if !mentions.contains(&acct) {
mentions.push(acct); mentions.push(acct);
}; };
@ -64,9 +63,8 @@ pub fn replace_mentions(
let actor_address = ActorAddress { let actor_address = ActorAddress {
username: caps["user"].to_string(), username: caps["user"].to_string(),
instance: secondary_caps["instance"].to_string(), instance: secondary_caps["instance"].to_string(),
is_local: &secondary_caps["instance"] == instance_host,
}; };
let acct = actor_address.acct(); let acct = actor_address.acct(instance_host);
if let Some(profile) = mention_map.get(&acct) { if let Some(profile) = mention_map.get(&acct) {
// Replace with a link to profile. // Replace with a link to profile.
// Actor URL may differ from actor ID. // Actor URL may differ from actor ID.
@ -89,7 +87,6 @@ pub fn replace_mentions(
} }
pub fn mention_to_address( pub fn mention_to_address(
instance_host: &str,
mention: &str, mention: &str,
) -> Result<ActorAddress, ValidationError> { ) -> Result<ActorAddress, ValidationError> {
let mention_re = Regex::new(MENTION_RE).unwrap(); let mention_re = Regex::new(MENTION_RE).unwrap();
@ -98,7 +95,6 @@ pub fn mention_to_address(
let actor_address = ActorAddress { let actor_address = ActorAddress {
username: mention_caps["user"].to_string(), username: mention_caps["user"].to_string(),
instance: mention_caps["instance"].to_string(), instance: mention_caps["instance"].to_string(),
is_local: &mention_caps["instance"] == instance_host,
}; };
Ok(actor_address) Ok(actor_address)
} }
@ -182,14 +178,14 @@ mod tests {
#[test] #[test]
fn test_mention_to_address() { fn test_mention_to_address() {
let mention = "@user@example.com"; let mention = "@user@example.com";
let address_1 = mention_to_address("example.com", mention).unwrap(); let address_1 = mention_to_address(mention).unwrap();
assert_eq!(address_1.acct(), "user"); assert_eq!(address_1.acct("example.com"), "user");
let address_2 = mention_to_address("server.info", mention).unwrap(); let address_2 = mention_to_address(mention).unwrap();
assert_eq!(address_2.acct(), "user@example.com"); assert_eq!(address_2.acct("server.info"), "user@example.com");
let short_mention = "@user"; let short_mention = "@user";
let result = mention_to_address("example.com", short_mention); let result = mention_to_address(short_mention);
assert_eq!(result.is_err(), true); assert_eq!(result.is_err(), true);
} }
} }