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

View file

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

View file

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

View file

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

View file

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