From af332283edd7d07b23b3eff3b6dc40441d623384 Mon Sep 17 00:00:00 2001 From: silverpill Date: Tue, 10 Jan 2023 21:26:42 +0000 Subject: [PATCH] Move ActorAddress type to webfinger::types module --- src/activitypub/actors/types.rs | 54 +------------------------- src/activitypub/fetcher/fetchers.rs | 4 +- src/activitypub/fetcher/helpers.rs | 6 +-- src/mastodon_api/search/helpers.rs | 4 +- src/mastodon_api/settings/views.rs | 2 +- src/models/posts/mentions.rs | 4 +- src/models/profiles/types.rs | 3 +- src/webfinger/types.rs | 59 +++++++++++++++++++++++++++++ src/webfinger/views.rs | 6 +-- 9 files changed, 74 insertions(+), 68 deletions(-) diff --git a/src/activitypub/actors/types.rs b/src/activitypub/actors/types.rs index dd8fd88..98fcca4 100644 --- a/src/activitypub/actors/types.rs +++ b/src/activitypub/actors/types.rs @@ -1,7 +1,3 @@ -use std::fmt; -use std::str::FromStr; - -use regex::Regex; use serde::{ Deserialize, Deserializer, @@ -26,6 +22,7 @@ use crate::models::users::types::User; use crate::utils::crypto_rsa::{deserialize_private_key, get_public_key_pem}; use crate::utils::files::get_file_url; use crate::utils::urls::get_hostname; +use crate::webfinger::types::ActorAddress; use super::attachments::{ attach_extra_field, attach_identity_proof, @@ -217,46 +214,6 @@ impl Actor { } } -// See also: USERNAME_RE in models::profiles::validators -const ACTOR_ADDRESS_RE: &str = r"(?P[\w\.-]+)@(?P[\w\.-]+)"; - -pub struct ActorAddress { - pub username: String, - pub hostname: String, -} - -impl ActorAddress { - /// Returns acct string, as used in Mastodon - pub fn acct(&self, local_hostname: &str) -> String { - if self.hostname == local_hostname { - self.username.clone() - } else { - self.to_string() - } - } -} - -impl FromStr for ActorAddress { - type Err = ValidationError; - - fn from_str(value: &str) -> Result { - let actor_address_re = Regex::new(ACTOR_ADDRESS_RE).unwrap(); - let caps = actor_address_re.captures(value) - .ok_or(ValidationError("invalid actor address"))?; - let actor_address = Self { - username: caps["username"].to_string(), - hostname: caps["hostname"].to_string(), - }; - Ok(actor_address) - } -} - -impl fmt::Display for ActorAddress { - fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "{}@{}", self.username, self.hostname) - } -} - pub type ActorKeyError = rsa::pkcs8::Error; pub fn get_local_actor( @@ -394,15 +351,6 @@ mod tests { const INSTANCE_HOSTNAME: &str = "example.com"; const INSTANCE_URL: &str = "https://example.com"; - #[test] - fn test_actor_address_parse_address() { - let value = "user_1@example.com"; - let actor_address: ActorAddress = value.parse().unwrap(); - assert_eq!(actor_address.username, "user_1"); - assert_eq!(actor_address.hostname, "example.com"); - assert_eq!(actor_address.to_string(), value); - } - #[test] fn test_get_actor_address() { let actor = Actor { diff --git a/src/activitypub/fetcher/fetchers.rs b/src/activitypub/fetcher/fetchers.rs index 5263a55..a11fef4 100644 --- a/src/activitypub/fetcher/fetchers.rs +++ b/src/activitypub/fetcher/fetchers.rs @@ -5,7 +5,7 @@ use reqwest::{Client, Method, Proxy, RequestBuilder}; use serde_json::Value; use crate::activitypub::activity::Object; -use crate::activitypub::actors::types::{Actor, ActorAddress}; +use crate::activitypub::actors::types::Actor; use crate::activitypub::constants::AP_MEDIA_TYPE; use crate::config::Instance; use crate::http_signatures::create::{ @@ -14,7 +14,7 @@ use crate::http_signatures::create::{ }; use crate::utils::files::{save_file, sniff_media_type}; use crate::utils::urls::guess_protocol; -use crate::webfinger::types::JsonResourceDescriptor; +use crate::webfinger::types::{ActorAddress, JsonResourceDescriptor}; const FETCHER_CONNECTION_TIMEOUT: u64 = 30; diff --git a/src/activitypub/fetcher/helpers.rs b/src/activitypub/fetcher/helpers.rs index 411b642..3c9e2d6 100644 --- a/src/activitypub/fetcher/helpers.rs +++ b/src/activitypub/fetcher/helpers.rs @@ -5,10 +5,7 @@ use tokio_postgres::GenericClient; use crate::activitypub::{ activity::Object, - actors::{ - helpers::{create_remote_profile, update_remote_profile}, - types::ActorAddress, - }, + actors::helpers::{create_remote_profile, update_remote_profile}, handlers::create::handle_note, identifiers::parse_local_object_id, receiver::HandlerError, @@ -24,6 +21,7 @@ use crate::models::profiles::queries::{ get_profile_by_remote_actor_id, }; use crate::models::profiles::types::DbActorProfile; +use crate::webfinger::types::ActorAddress; use super::fetchers::{ fetch_actor, fetch_object, diff --git a/src/mastodon_api/search/helpers.rs b/src/mastodon_api/search/helpers.rs index c82ca5d..32ce0eb 100644 --- a/src/mastodon_api/search/helpers.rs +++ b/src/mastodon_api/search/helpers.rs @@ -5,7 +5,6 @@ use tokio_postgres::GenericClient; use url::Url; use crate::activitypub::{ - actors::types::ActorAddress, fetcher::helpers::{ get_or_import_profile_by_actor_id, import_post, @@ -36,6 +35,7 @@ use crate::models::users::{ types::User, }; use crate::utils::currencies::{validate_wallet_address, Currency}; +use crate::webfinger::types::ActorAddress; use super::types::SearchResults; enum SearchQuery { @@ -50,7 +50,7 @@ enum SearchQuery { fn parse_profile_query(query: &str) -> Result<(String, Option), ValidationError> { - // See also: ACTOR_ADDRESS_RE in activitypub::actors::types + // See also: ACTOR_ADDRESS_RE in webfinger::types let acct_query_re = Regex::new(r"^(@|!)?(?P[\w\.-]+)(@(?P[\w\.-]+))?$").unwrap(); let acct_query_caps = acct_query_re.captures(query) diff --git a/src/mastodon_api/settings/views.rs b/src/mastodon_api/settings/views.rs index db8a98a..4b24132 100644 --- a/src/mastodon_api/settings/views.rs +++ b/src/mastodon_api/settings/views.rs @@ -4,7 +4,6 @@ use actix_web::{get, post, web, HttpResponse, Scope}; use actix_web_httpauth::extractors::bearer::BearerAuth; use crate::activitypub::{ - actors::types::ActorAddress, builders::{ move_person::prepare_move_person, undo_follow::prepare_undo_follow, @@ -24,6 +23,7 @@ use crate::models::{ users::queries::set_user_password, }; use crate::utils::passwords::hash_password; +use crate::webfinger::types::ActorAddress; use super::helpers::{export_followers, export_follows}; use super::types::{MoveFollowersRequest, PasswordChangeRequest}; diff --git a/src/models/posts/mentions.rs b/src/models/posts/mentions.rs index 2a1551a..4fde4a3 100644 --- a/src/models/posts/mentions.rs +++ b/src/models/posts/mentions.rs @@ -3,14 +3,14 @@ use std::collections::HashMap; use regex::{Captures, Regex}; use tokio_postgres::GenericClient; -use crate::activitypub::actors::types::ActorAddress; use crate::database::DatabaseError; use crate::errors::ValidationError; use crate::models::profiles::queries::get_profiles_by_accts; use crate::models::profiles::types::DbActorProfile; +use crate::webfinger::types::ActorAddress; use super::links::is_inside_code_block; -// See also: ACTOR_ADDRESS_RE in activitypub::actors::types +// See also: ACTOR_ADDRESS_RE in webfinger::types const MENTION_SEARCH_RE: &str = r"(?m)(?P^|\s|>|[\(])@(?P[^\s<]+)"; const MENTION_SEARCH_SECONDARY_RE: &str = r"^(?P[\w\.-]+)(@(?P[\w\.-]+\w))?(?P[\.,:?\)]?)$"; diff --git a/src/models/profiles/types.rs b/src/models/profiles/types.rs index 9a7e67b..3ad601b 100644 --- a/src/models/profiles/types.rs +++ b/src/models/profiles/types.rs @@ -11,7 +11,7 @@ use serde::{ }; use uuid::Uuid; -use crate::activitypub::actors::types::{Actor, ActorAddress}; +use crate::activitypub::actors::types::Actor; use crate::activitypub::identifiers::local_actor_id; use crate::database::{ json_macro::{json_from_sql, json_to_sql}, @@ -23,6 +23,7 @@ use crate::identity::{ signatures::{PROOF_TYPE_ID_EIP191, PROOF_TYPE_ID_MINISIGN}, }; use crate::utils::caip2::ChainId; +use crate::webfinger::types::ActorAddress; use super::validators::{ validate_username, validate_display_name, diff --git a/src/webfinger/types.rs b/src/webfinger/types.rs index af00a67..97ec29f 100644 --- a/src/webfinger/types.rs +++ b/src/webfinger/types.rs @@ -1,7 +1,15 @@ /// https://webfinger.net/ +use std::fmt; +use std::str::FromStr; +use regex::Regex; use serde::{Serialize, Deserialize}; +use crate::errors::ValidationError; + +// See also: USERNAME_RE in models::profiles::validators +const ACTOR_ADDRESS_RE: &str = r"(?P[\w\.-]+)@(?P[\w\.-]+)"; + pub const JRD_CONTENT_TYPE: &str = "application/jrd+json"; #[derive(Deserialize)] @@ -9,6 +17,43 @@ pub struct WebfingerQueryParams { pub resource: String, } +pub struct ActorAddress { + pub username: String, + pub hostname: String, +} + +impl ActorAddress { + /// Returns acct string, as used in Mastodon + pub fn acct(&self, local_hostname: &str) -> String { + if self.hostname == local_hostname { + self.username.clone() + } else { + self.to_string() + } + } +} + +impl FromStr for ActorAddress { + type Err = ValidationError; + + fn from_str(value: &str) -> Result { + let actor_address_re = Regex::new(ACTOR_ADDRESS_RE).unwrap(); + let caps = actor_address_re.captures(value) + .ok_or(ValidationError("invalid actor address"))?; + let actor_address = Self { + username: caps["username"].to_string(), + hostname: caps["hostname"].to_string(), + }; + Ok(actor_address) + } +} + +impl fmt::Display for ActorAddress { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "{}@{}", self.username, self.hostname) + } +} + #[derive(Serialize, Deserialize)] pub struct Link { pub rel: String, @@ -25,3 +70,17 @@ pub struct JsonResourceDescriptor { pub subject: String, pub links: Vec, } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_actor_address_parse_address() { + let value = "user_1@example.com"; + let actor_address: ActorAddress = value.parse().unwrap(); + assert_eq!(actor_address.username, "user_1"); + assert_eq!(actor_address.hostname, "example.com"); + assert_eq!(actor_address.to_string(), value); + } +} diff --git a/src/webfinger/views.rs b/src/webfinger/views.rs index 75dfacf..227c27d 100644 --- a/src/webfinger/views.rs +++ b/src/webfinger/views.rs @@ -1,7 +1,6 @@ use actix_web::{get, web, HttpResponse}; use tokio_postgres::GenericClient; -use crate::activitypub::actors::types::ActorAddress; use crate::activitypub::constants::AP_MEDIA_TYPE; use crate::activitypub::identifiers::{ local_actor_id, @@ -12,10 +11,11 @@ use crate::database::{get_database_client, DbPool}; use crate::errors::{HttpError, ValidationError}; use crate::models::users::queries::is_registered_user; use super::types::{ - JRD_CONTENT_TYPE, - WebfingerQueryParams, + ActorAddress, Link, JsonResourceDescriptor, + WebfingerQueryParams, + JRD_CONTENT_TYPE, }; // https://datatracker.ietf.org/doc/html/rfc7565#section-7