Move fetch_profile_by_actor_id to fetcher::helpers module

This commit is contained in:
silverpill 2022-07-09 21:24:37 +00:00
parent a06f1b4aba
commit 145622e805
3 changed files with 55 additions and 52 deletions

View file

@ -8,15 +8,11 @@ use crate::activitypub::actor::{Actor, ActorAddress};
use crate::activitypub::constants::ACTIVITY_CONTENT_TYPE;
use crate::config::Instance;
use crate::http_signatures::create::{create_http_signature, SignatureError};
use crate::models::profiles::types::ProfileCreateData;
use crate::utils::files::{save_file, FileError};
use crate::webfinger::types::JsonResourceDescriptor;
#[derive(thiserror::Error, Debug)]
pub enum FetchError {
#[error("invalid URL")]
UrlError(#[from] url::ParseError),
#[error(transparent)]
SignatureError(#[from] SignatureError),
@ -150,40 +146,6 @@ pub async fn fetch_avatar_and_banner(
Ok((avatar, banner))
}
pub async fn fetch_profile_by_actor_id(
instance: &Instance,
actor_url: &str,
media_dir: &Path,
) -> Result<ProfileCreateData, FetchError> {
let actor = fetch_actor(instance, actor_url).await?;
let actor_host = url::Url::parse(&actor.id)?
.host_str()
.ok_or(url::ParseError::EmptyHost)?
.to_owned();
if actor_host == instance.host() {
return Err(FetchError::OtherError("trying to fetch local profile"));
};
let actor_address = format!(
"{}@{}",
actor.preferred_username,
actor_host,
);
let (avatar, banner) = fetch_avatar_and_banner(&actor, media_dir).await?;
let (identity_proofs, extra_fields) = actor.parse_attachments();
let profile_data = ProfileCreateData {
username: actor.preferred_username.clone(),
display_name: actor.name.clone(),
acct: actor_address,
bio: actor.summary.clone(),
avatar,
banner,
identity_proofs,
extra_fields,
actor_json: Some(actor),
};
Ok(profile_data)
}
pub async fn fetch_object(
instance: &Instance,
object_url: &str,

View file

@ -4,7 +4,7 @@ use std::path::Path;
use tokio_postgres::GenericClient;
use crate::activitypub::activity::Object;
use crate::activitypub::actor::ActorAddress;
use crate::activitypub::actor::{Actor, ActorAddress};
use crate::activitypub::handlers::{
create_note::handle_note,
update_person::update_actor,
@ -19,11 +19,11 @@ use crate::models::profiles::queries::{
get_profile_by_acct,
create_profile,
};
use crate::models::profiles::types::DbActorProfile;
use crate::models::profiles::types::{DbActorProfile, ProfileCreateData};
use super::fetchers::{
fetch_actor,
fetch_avatar_and_banner,
fetch_object,
fetch_profile_by_actor_id,
perform_webfinger_query,
FetchError,
};
@ -56,6 +56,45 @@ impl From<ImportError> for HttpError {
}
}
fn get_actor_host(actor_id: &str) -> Result<String, url::ParseError> {
let actor_host = url::Url::parse(actor_id)?
.host_str()
.ok_or(url::ParseError::EmptyHost)?
.to_owned();
Ok(actor_host)
}
async fn prepare_remote_profile_data(
instance: &Instance,
media_dir: &Path,
actor: Actor,
) -> Result<ProfileCreateData, ImportError> {
let actor_host = get_actor_host(&actor.id)
.map_err(|_| ValidationError("invalid actor ID"))?;
if actor_host == instance.host() {
return Err(ImportError::LocalObject);
};
let actor_address = format!(
"{}@{}",
actor.preferred_username,
actor_host,
);
let (avatar, banner) = fetch_avatar_and_banner(&actor, media_dir).await?;
let (identity_proofs, extra_fields) = actor.parse_attachments();
let profile_data = ProfileCreateData {
username: actor.preferred_username.clone(),
display_name: actor.name.clone(),
acct: actor_address,
bio: actor.summary.clone(),
avatar,
banner,
identity_proofs,
extra_fields,
actor_json: Some(actor),
};
Ok(profile_data)
}
pub async fn get_or_import_profile_by_actor_id(
db_client: &impl GenericClient,
instance: &Instance,
@ -77,14 +116,12 @@ pub async fn get_or_import_profile_by_actor_id(
}
},
Err(DatabaseError::NotFound(_)) => {
let mut profile_data = fetch_profile_by_actor_id(
instance, actor_id, media_dir,
)
.await
.map_err(|err| {
log::warn!("failed to fetch {} ({})", actor_id, err);
err
})?;
let actor = fetch_actor(instance, actor_id).await?;
let mut profile_data = prepare_remote_profile_data(
instance,
media_dir,
actor,
).await?;
log::info!("fetched profile {}", profile_data.acct);
profile_data.clean()?;
let profile = create_profile(db_client, profile_data).await?;
@ -106,10 +143,11 @@ pub async fn import_profile_by_actor_address(
return Err(ImportError::LocalObject);
};
let actor_id = perform_webfinger_query(instance, actor_address).await?;
let mut profile_data = fetch_profile_by_actor_id(
let actor = fetch_actor(instance, &actor_id).await?;
let mut profile_data = prepare_remote_profile_data(
instance,
&actor_id,
media_dir,
actor,
).await?;
if profile_data.acct != actor_address.acct() {
// Redirected to different server

View file

@ -106,7 +106,10 @@ pub async fn handle_note(
instance,
media_dir,
&author_id,
).await?;
).await.map_err(|err| {
log::warn!("failed to import {} ({})", author_id, err);
err
})?;
let content = get_note_content(&object)?;
let mut attachments: Vec<Uuid> = Vec::new();