Rename instance field in ActorAddress to hostname
This commit is contained in:
parent
0a62fdac2b
commit
81910f9591
8 changed files with 49 additions and 49 deletions
|
@ -119,14 +119,14 @@ impl Actor {
|
||||||
pub fn address(
|
pub fn address(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<ActorAddress, ValidationError> {
|
) -> Result<ActorAddress, ValidationError> {
|
||||||
let actor_host = url::Url::parse(&self.id)
|
let hostname = 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 actor_address = ActorAddress {
|
let actor_address = ActorAddress {
|
||||||
username: self.preferred_username.clone(),
|
username: self.preferred_username.clone(),
|
||||||
instance: actor_host,
|
hostname: hostname,
|
||||||
};
|
};
|
||||||
Ok(actor_address)
|
Ok(actor_address)
|
||||||
}
|
}
|
||||||
|
@ -179,12 +179,12 @@ impl Actor {
|
||||||
|
|
||||||
pub struct ActorAddress {
|
pub struct ActorAddress {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub instance: String,
|
pub hostname: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ActorAddress {
|
impl ActorAddress {
|
||||||
pub fn is_local(&self, instance_host: &str) -> bool {
|
pub fn is_local(&self, instance_host: &str) -> bool {
|
||||||
self.instance == instance_host
|
self.hostname == instance_host
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns acct string, as used in Mastodon
|
/// Returns acct string, as used in Mastodon
|
||||||
|
@ -198,7 +198,7 @@ impl ActorAddress {
|
||||||
}
|
}
|
||||||
|
|
||||||
// See also: USERNAME_RE in models::profiles::validators
|
// See also: USERNAME_RE in models::profiles::validators
|
||||||
pub const ACTOR_ADDRESS_RE: &str = r"(?P<username>[\w\.-]+)@(?P<instance>[\w\.-]+)";
|
pub const ACTOR_ADDRESS_RE: &str = r"(?P<username>[\w\.-]+)@(?P<hostname>[\w\.-]+)";
|
||||||
|
|
||||||
impl FromStr for ActorAddress {
|
impl FromStr for ActorAddress {
|
||||||
type Err = ValidationError;
|
type Err = ValidationError;
|
||||||
|
@ -209,7 +209,7 @@ impl FromStr for ActorAddress {
|
||||||
.ok_or(ValidationError("invalid actor address"))?;
|
.ok_or(ValidationError("invalid actor address"))?;
|
||||||
let actor_address = Self {
|
let actor_address = Self {
|
||||||
username: caps["username"].to_string(),
|
username: caps["username"].to_string(),
|
||||||
instance: caps["instance"].to_string(),
|
hostname: caps["hostname"].to_string(),
|
||||||
};
|
};
|
||||||
Ok(actor_address)
|
Ok(actor_address)
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ impl FromStr for ActorAddress {
|
||||||
|
|
||||||
impl fmt::Display for ActorAddress {
|
impl fmt::Display for ActorAddress {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(formatter, "{}@{}", self.username, self.instance)
|
write!(formatter, "{}@{}", self.username, self.hostname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +357,7 @@ mod tests {
|
||||||
let value = "user_1@example.com";
|
let value = "user_1@example.com";
|
||||||
let actor_address = value.parse::<ActorAddress>().unwrap();
|
let actor_address = value.parse::<ActorAddress>().unwrap();
|
||||||
assert_eq!(actor_address.username, "user_1");
|
assert_eq!(actor_address.username, "user_1");
|
||||||
assert_eq!(actor_address.instance, "example.com");
|
assert_eq!(actor_address.hostname, "example.com");
|
||||||
assert_eq!(actor_address.to_string(), value);
|
assert_eq!(actor_address.to_string(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ pub async fn perform_webfinger_query(
|
||||||
// TOOD: support http
|
// TOOD: support http
|
||||||
let webfinger_url = format!(
|
let webfinger_url = format!(
|
||||||
"https://{}/.well-known/webfinger",
|
"https://{}/.well-known/webfinger",
|
||||||
actor_address.instance,
|
actor_address.hostname,
|
||||||
);
|
);
|
||||||
let client = build_client()?;
|
let client = build_client()?;
|
||||||
let mut request_builder = client.get(&webfinger_url);
|
let mut request_builder = client.get(&webfinger_url);
|
||||||
|
|
|
@ -73,7 +73,7 @@ async fn create_remote_profile(
|
||||||
actor.parse_attachments();
|
actor.parse_attachments();
|
||||||
let mut profile_data = ProfileCreateData {
|
let mut profile_data = ProfileCreateData {
|
||||||
username: actor.preferred_username.clone(),
|
username: actor.preferred_username.clone(),
|
||||||
hostname: Some(actor_address.instance),
|
hostname: Some(actor_address.hostname),
|
||||||
display_name: actor.name.clone(),
|
display_name: actor.name.clone(),
|
||||||
bio: actor.summary.clone(),
|
bio: actor.summary.clone(),
|
||||||
avatar,
|
avatar,
|
||||||
|
@ -165,7 +165,7 @@ pub async fn import_profile_by_actor_address(
|
||||||
media_dir: &Path,
|
media_dir: &Path,
|
||||||
actor_address: &ActorAddress,
|
actor_address: &ActorAddress,
|
||||||
) -> Result<DbActorProfile, ImportError> {
|
) -> Result<DbActorProfile, ImportError> {
|
||||||
if actor_address.instance == instance.host() {
|
if actor_address.hostname == instance.host() {
|
||||||
return Err(ImportError::LocalObject);
|
return Err(ImportError::LocalObject);
|
||||||
};
|
};
|
||||||
let actor_id = perform_webfinger_query(instance, actor_address).await?;
|
let actor_id = perform_webfinger_query(instance, actor_address).await?;
|
||||||
|
|
|
@ -42,15 +42,15 @@ fn parse_profile_query(query: &str) ->
|
||||||
{
|
{
|
||||||
// See also: ACTOR_ADDRESS_RE in activitypub::actors::types
|
// See also: ACTOR_ADDRESS_RE in activitypub::actors::types
|
||||||
let acct_query_re =
|
let acct_query_re =
|
||||||
Regex::new(r"^(@|!)?(?P<user>[\w\.-]+)(@(?P<instance>[\w\.-]+))?$").unwrap();
|
Regex::new(r"^(@|!)?(?P<username>[\w\.-]+)(@(?P<hostname>[\w\.-]+))?$").unwrap();
|
||||||
let acct_query_caps = acct_query_re.captures(query)
|
let acct_query_caps = acct_query_re.captures(query)
|
||||||
.ok_or(ValidationError("invalid profile query"))?;
|
.ok_or(ValidationError("invalid profile query"))?;
|
||||||
let username = acct_query_caps.name("user")
|
let username = acct_query_caps.name("username")
|
||||||
.ok_or(ValidationError("invalid profile query"))?
|
.ok_or(ValidationError("invalid profile query"))?
|
||||||
.as_str().to_string();
|
.as_str().to_string();
|
||||||
let maybe_instance = acct_query_caps.name("instance")
|
let maybe_hostname = acct_query_caps.name("hostname")
|
||||||
.map(|val| val.as_str().to_string());
|
.map(|val| val.as_str().to_string());
|
||||||
Ok((username, maybe_instance))
|
Ok((username, maybe_hostname))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_query(query: &str) -> Result<String, ValidationError> {
|
fn parse_tag_query(query: &str) -> Result<String, ValidationError> {
|
||||||
|
@ -82,8 +82,8 @@ fn parse_search_query(search_query: &str) -> SearchQuery {
|
||||||
if let Ok(tag) = parse_tag_query(search_query) {
|
if let Ok(tag) = parse_tag_query(search_query) {
|
||||||
return SearchQuery::TagQuery(tag);
|
return SearchQuery::TagQuery(tag);
|
||||||
};
|
};
|
||||||
if let Ok((username, maybe_instance)) = parse_profile_query(search_query) {
|
if let Ok((username, maybe_hostname)) = parse_profile_query(search_query) {
|
||||||
return SearchQuery::ProfileQuery(username, maybe_instance);
|
return SearchQuery::ProfileQuery(username, maybe_hostname);
|
||||||
};
|
};
|
||||||
SearchQuery::Unknown
|
SearchQuery::Unknown
|
||||||
}
|
}
|
||||||
|
@ -92,25 +92,25 @@ async fn search_profiles_or_import(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
username: String,
|
username: String,
|
||||||
mut instance: Option<String>,
|
mut maybe_hostname: Option<String>,
|
||||||
limit: u16,
|
limit: u16,
|
||||||
) -> Result<Vec<DbActorProfile>, HttpError> {
|
) -> Result<Vec<DbActorProfile>, HttpError> {
|
||||||
if let Some(ref actor_host) = instance {
|
if let Some(ref hostname) = maybe_hostname {
|
||||||
if actor_host == &config.instance().host() {
|
if hostname == &config.instance().host() {
|
||||||
// This is a local profile
|
// This is a local profile
|
||||||
instance = None;
|
maybe_hostname = None;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
let mut profiles = search_profiles(
|
let mut profiles = search_profiles(
|
||||||
db_client,
|
db_client,
|
||||||
&username,
|
&username,
|
||||||
instance.as_ref(),
|
maybe_hostname.as_ref(),
|
||||||
limit,
|
limit,
|
||||||
).await?;
|
).await?;
|
||||||
if profiles.is_empty() && instance.is_some() {
|
if profiles.is_empty() && maybe_hostname.is_some() {
|
||||||
let actor_address = ActorAddress {
|
let actor_address = ActorAddress {
|
||||||
username: username,
|
username: username,
|
||||||
instance: instance.unwrap(),
|
hostname: maybe_hostname.unwrap(),
|
||||||
};
|
};
|
||||||
match import_profile_by_actor_address(
|
match import_profile_by_actor_address(
|
||||||
db_client,
|
db_client,
|
||||||
|
@ -160,12 +160,12 @@ pub async fn search(
|
||||||
let mut posts = vec![];
|
let mut posts = vec![];
|
||||||
let mut tags = vec![];
|
let mut tags = vec![];
|
||||||
match parse_search_query(search_query) {
|
match parse_search_query(search_query) {
|
||||||
SearchQuery::ProfileQuery(username, maybe_instance) => {
|
SearchQuery::ProfileQuery(username, maybe_hostname) => {
|
||||||
profiles = search_profiles_or_import(
|
profiles = search_profiles_or_import(
|
||||||
config,
|
config,
|
||||||
db_client,
|
db_client,
|
||||||
username,
|
username,
|
||||||
maybe_instance,
|
maybe_hostname,
|
||||||
limit,
|
limit,
|
||||||
).await?;
|
).await?;
|
||||||
},
|
},
|
||||||
|
@ -224,14 +224,14 @@ pub async fn search_profiles_only(
|
||||||
search_query: &str,
|
search_query: &str,
|
||||||
limit: u16,
|
limit: u16,
|
||||||
) -> Result<Vec<Account>, HttpError> {
|
) -> Result<Vec<Account>, HttpError> {
|
||||||
let (username, maybe_instance) = match parse_profile_query(search_query) {
|
let (username, maybe_hostname) = match parse_profile_query(search_query) {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(_) => return Ok(vec![]),
|
Err(_) => return Ok(vec![]),
|
||||||
};
|
};
|
||||||
let profiles = search_profiles(
|
let profiles = search_profiles(
|
||||||
db_client,
|
db_client,
|
||||||
&username,
|
&username,
|
||||||
maybe_instance.as_ref(),
|
maybe_hostname.as_ref(),
|
||||||
limit,
|
limit,
|
||||||
).await?;
|
).await?;
|
||||||
let accounts: Vec<Account> = profiles.into_iter()
|
let accounts: Vec<Account> = profiles.into_iter()
|
||||||
|
@ -247,17 +247,17 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_profile_query() {
|
fn test_parse_profile_query() {
|
||||||
let query = "@user";
|
let query = "@user";
|
||||||
let (username, maybe_instance) = parse_profile_query(query).unwrap();
|
let (username, maybe_hostname) = parse_profile_query(query).unwrap();
|
||||||
assert_eq!(username, "user");
|
assert_eq!(username, "user");
|
||||||
assert_eq!(maybe_instance, None);
|
assert_eq!(maybe_hostname, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_profile_query_group() {
|
fn test_parse_profile_query_group() {
|
||||||
let query = "!group@example.com";
|
let query = "!group@example.com";
|
||||||
let (username, maybe_instance) = parse_profile_query(query).unwrap();
|
let (username, maybe_hostname) = parse_profile_query(query).unwrap();
|
||||||
assert_eq!(username, "group");
|
assert_eq!(username, "group");
|
||||||
assert_eq!(maybe_instance.as_deref(), Some("example.com"));
|
assert_eq!(maybe_hostname.as_deref(), Some("example.com"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -9,9 +9,9 @@ use crate::models::profiles::queries::get_profiles_by_accts;
|
||||||
use crate::models::profiles::types::DbActorProfile;
|
use crate::models::profiles::types::DbActorProfile;
|
||||||
|
|
||||||
// See also: ACTOR_ADDRESS_RE in activitypub::actors::types
|
// See also: ACTOR_ADDRESS_RE in activitypub::actors::types
|
||||||
const MENTION_RE: &str = r"@?(?P<user>[\w\.-]+)@(?P<instance>.+)";
|
const MENTION_RE: &str = r"@?(?P<username>[\w\.-]+)@(?P<hostname>.+)";
|
||||||
const MENTION_SEARCH_RE: &str = r"(?m)(?P<before>^|\s|>|[\(])@(?P<mention>[^\s<]+)";
|
const MENTION_SEARCH_RE: &str = r"(?m)(?P<before>^|\s|>|[\(])@(?P<mention>[^\s<]+)";
|
||||||
const MENTION_SEARCH_SECONDARY_RE: &str = r"^(?P<user>[\w\.-]+)(@(?P<instance>[\w\.-]+\w))?(?P<after>[\.,:?\)]?)$";
|
const MENTION_SEARCH_SECONDARY_RE: &str = r"^(?P<username>[\w\.-]+)(@(?P<hostname>[\w\.-]+\w))?(?P<after>[\.,:?\)]?)$";
|
||||||
|
|
||||||
/// Finds everything that looks like a mention
|
/// Finds everything that looks like a mention
|
||||||
fn find_mentions(
|
fn find_mentions(
|
||||||
|
@ -23,12 +23,12 @@ fn find_mentions(
|
||||||
let mut mentions = vec![];
|
let mut mentions = vec![];
|
||||||
for caps in mention_re.captures_iter(text) {
|
for caps in mention_re.captures_iter(text) {
|
||||||
if let Some(secondary_caps) = mention_secondary_re.captures(&caps["mention"]) {
|
if let Some(secondary_caps) = mention_secondary_re.captures(&caps["mention"]) {
|
||||||
let username = secondary_caps["user"].to_string();
|
let username = secondary_caps["username"].to_string();
|
||||||
let instance = secondary_caps.name("instance")
|
let hostname = secondary_caps.name("hostname")
|
||||||
.map(|match_| match_.as_str())
|
.map(|match_| match_.as_str())
|
||||||
.unwrap_or(instance_host)
|
.unwrap_or(instance_host)
|
||||||
.to_string();
|
.to_string();
|
||||||
let actor_address = ActorAddress { username, instance };
|
let actor_address = ActorAddress { username, hostname };
|
||||||
let acct = actor_address.acct(instance_host);
|
let acct = actor_address.acct(instance_host);
|
||||||
if !mentions.contains(&acct) {
|
if !mentions.contains(&acct) {
|
||||||
mentions.push(acct);
|
mentions.push(acct);
|
||||||
|
@ -62,12 +62,12 @@ pub fn replace_mentions(
|
||||||
let mention_secondary_re = Regex::new(MENTION_SEARCH_SECONDARY_RE).unwrap();
|
let mention_secondary_re = Regex::new(MENTION_SEARCH_SECONDARY_RE).unwrap();
|
||||||
let result = mention_re.replace_all(text, |caps: &Captures| {
|
let result = mention_re.replace_all(text, |caps: &Captures| {
|
||||||
if let Some(secondary_caps) = mention_secondary_re.captures(&caps["mention"]) {
|
if let Some(secondary_caps) = mention_secondary_re.captures(&caps["mention"]) {
|
||||||
let username = secondary_caps["user"].to_string();
|
let username = secondary_caps["username"].to_string();
|
||||||
let instance = secondary_caps.name("instance")
|
let hostname = secondary_caps.name("hostname")
|
||||||
.map(|match_| match_.as_str())
|
.map(|match_| match_.as_str())
|
||||||
.unwrap_or(instance_host)
|
.unwrap_or(instance_host)
|
||||||
.to_string();
|
.to_string();
|
||||||
let actor_address = ActorAddress { username, instance };
|
let actor_address = ActorAddress { username, hostname };
|
||||||
let acct = actor_address.acct(instance_host);
|
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.
|
||||||
|
@ -97,8 +97,8 @@ pub fn mention_to_address(
|
||||||
let mention_caps = mention_re.captures(mention)
|
let mention_caps = mention_re.captures(mention)
|
||||||
.ok_or(ValidationError("invalid mention tag"))?;
|
.ok_or(ValidationError("invalid mention tag"))?;
|
||||||
let actor_address = ActorAddress {
|
let actor_address = ActorAddress {
|
||||||
username: mention_caps["user"].to_string(),
|
username: mention_caps["username"].to_string(),
|
||||||
instance: mention_caps["instance"].to_string(),
|
hostname: mention_caps["hostname"].to_string(),
|
||||||
};
|
};
|
||||||
Ok(actor_address)
|
Ok(actor_address)
|
||||||
}
|
}
|
||||||
|
|
|
@ -372,13 +372,13 @@ pub async fn delete_profile(
|
||||||
pub async fn search_profiles(
|
pub async fn search_profiles(
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
username: &str,
|
username: &str,
|
||||||
instance: Option<&String>,
|
maybe_hostname: Option<&String>,
|
||||||
limit: u16,
|
limit: u16,
|
||||||
) -> Result<Vec<DbActorProfile>, DatabaseError> {
|
) -> Result<Vec<DbActorProfile>, DatabaseError> {
|
||||||
let db_search_query = match instance {
|
let db_search_query = match maybe_hostname {
|
||||||
Some(instance) => {
|
Some(hostname) => {
|
||||||
// Search for exact actor address
|
// Search for exact actor address
|
||||||
format!("{}@{}", username, instance)
|
format!("{}@{}", username, hostname)
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
// Fuzzy search for username
|
// Fuzzy search for username
|
||||||
|
|
|
@ -276,7 +276,7 @@ impl DbActorProfile {
|
||||||
assert_eq!(self.hostname.is_none(), self.is_local());
|
assert_eq!(self.hostname.is_none(), self.is_local());
|
||||||
ActorAddress {
|
ActorAddress {
|
||||||
username: self.username.clone(),
|
username: self.username.clone(),
|
||||||
instance: self.hostname.as_deref()
|
hostname: self.hostname.as_deref()
|
||||||
.unwrap_or(instance_host)
|
.unwrap_or(instance_host)
|
||||||
.to_string(),
|
.to_string(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ fn parse_acct_uri(uri: &str) -> Result<ActorAddress, ValidationError> {
|
||||||
.ok_or(ValidationError("invalid query target"))?;
|
.ok_or(ValidationError("invalid query target"))?;
|
||||||
let actor_address = ActorAddress {
|
let actor_address = ActorAddress {
|
||||||
username: uri_caps["username"].to_string(),
|
username: uri_caps["username"].to_string(),
|
||||||
instance: uri_caps["instance"].to_string(),
|
hostname: uri_caps["hostname"].to_string(),
|
||||||
};
|
};
|
||||||
Ok(actor_address)
|
Ok(actor_address)
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,6 @@ mod tests {
|
||||||
let uri = "acct:user_1@example.com";
|
let uri = "acct:user_1@example.com";
|
||||||
let actor_address = parse_acct_uri(uri).unwrap();
|
let actor_address = parse_acct_uri(uri).unwrap();
|
||||||
assert_eq!(actor_address.username, "user_1");
|
assert_eq!(actor_address.username, "user_1");
|
||||||
assert_eq!(actor_address.instance, "example.com");
|
assert_eq!(actor_address.hostname, "example.com");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue