Move fetch_profile_by_actor_id to fetcher::helpers module
This commit is contained in:
parent
a06f1b4aba
commit
145622e805
3 changed files with 55 additions and 52 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue