Refactor mention_to_acct to return detailed actor address

This commit is contained in:
silverpill 2021-12-19 22:15:14 +00:00
parent 0fe8423031
commit fae3f5bc2f
3 changed files with 43 additions and 19 deletions

View file

@ -124,6 +124,23 @@ impl DbActorProfile {
}
}
pub struct ActorAddress {
pub username: String,
pub instance: String,
pub is_local: bool,
}
impl ActorAddress {
/// Returns acct string, as used in Mastodon
pub fn acct(&self) -> String {
if self.is_local {
self.username.clone()
} else {
format!("{}@{}", self.username, self.instance)
}
}
}
pub type ActorKeyError = rsa::pkcs8::Error;
pub fn get_local_actor(

View file

@ -9,7 +9,7 @@ use crate::config::{Config, Instance};
use crate::database::{Pool, get_database_client};
use crate::errors::{DatabaseError, HttpError, ValidationError};
use crate::models::attachments::queries::create_attachment;
use crate::models::posts::mentions::mention_to_acct;
use crate::models::posts::mentions::mention_to_address;
use crate::models::posts::queries::{
create_post,
get_post_by_id,
@ -243,8 +243,14 @@ pub async fn process_note(
};
} else if tag.tag_type == MENTION {
// Ignore invalid mentions
if let Ok(acct) = mention_to_acct(&instance.host(), &tag.name) {
let profile = get_profile_by_acct(db_client, &acct).await?;
if let Ok(actor_address) = mention_to_address(
&instance.host(),
&tag.name,
) {
let profile = get_profile_by_acct(
db_client,
&actor_address.acct(),
).await?;
if !mentions.contains(&profile.id) {
mentions.push(profile.id);
};

View file

@ -3,6 +3,7 @@ use std::collections::HashMap;
use regex::{Captures, Regex};
use tokio_postgres::GenericClient;
use crate::activitypub::actor::ActorAddress;
use crate::errors::{DatabaseError, ValidationError};
use crate::models::profiles::queries::get_profiles_by_accts;
use crate::models::profiles::types::DbActorProfile;
@ -10,11 +11,11 @@ use crate::models::profiles::types::DbActorProfile;
const MENTION_RE: &str = r"@?(?P<user>\w+)@(?P<instance>.+)";
const MENTION_SEARCH_RE: &str = r"(?m)(?P<space>^|\s)@(?P<user>\w+)@(?P<instance>\S+)";
fn pattern_to_acct(caps: &Captures, instance_host: &str) -> String {
if &caps["instance"] == instance_host {
caps["user"].to_string()
} else {
format!("{}@{}", &caps["user"], &caps["instance"])
fn pattern_to_address(caps: &Captures, instance_host: &str) -> ActorAddress {
ActorAddress {
username: caps["user"].to_string(),
instance: caps["instance"].to_string(),
is_local: &caps["instance"] == instance_host,
}
}
@ -26,7 +27,7 @@ fn find_mentions(
let mention_re = Regex::new(MENTION_SEARCH_RE).unwrap();
let mut mentions = vec![];
for caps in mention_re.captures_iter(text) {
let acct = pattern_to_acct(&caps, instance_host);
let acct = pattern_to_address(&caps, instance_host).acct();
if !mentions.contains(&acct) {
mentions.push(acct);
};
@ -56,7 +57,7 @@ pub fn replace_mentions(
) -> String {
let mention_re = Regex::new(MENTION_SEARCH_RE).unwrap();
let result = mention_re.replace_all(text, |caps: &Captures| {
let acct = pattern_to_acct(caps, instance_host);
let acct = pattern_to_address(caps, instance_host).acct();
match mention_map.get(&acct) {
Some(profile) => {
// Replace with a link to profile.
@ -76,15 +77,15 @@ pub fn replace_mentions(
result.to_string()
}
pub fn mention_to_acct(
pub fn mention_to_address(
instance_host: &str,
mention: &str,
) -> Result<String, ValidationError> {
) -> Result<ActorAddress, ValidationError> {
let mention_re = Regex::new(MENTION_RE).unwrap();
let mention_caps = mention_re.captures(mention)
.ok_or(ValidationError("invalid mention tag"))?;
let acct = pattern_to_acct(&mention_caps, instance_host);
Ok(acct)
let actor_address = pattern_to_address(&mention_caps, instance_host);
Ok(actor_address)
}
#[cfg(test)]
@ -146,12 +147,12 @@ mod tests {
}
#[test]
fn test_mention_to_acct() {
fn test_mention_to_address() {
let mention = "@user@example.com";
let acct_1 = mention_to_acct("example.com", mention).unwrap();
assert_eq!(acct_1, "user");
let address_1 = mention_to_address("example.com", mention).unwrap();
assert_eq!(address_1.acct(), "user");
let acct_2 = mention_to_acct("server.info", mention).unwrap();
assert_eq!(acct_2, "user@example.com");
let address_2 = mention_to_address("server.info", mention).unwrap();
assert_eq!(address_2.acct(), "user@example.com");
}
}