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::activitypub::constants::ACTIVITY_CONTENT_TYPE;
|
||||||
use crate::config::Instance;
|
use crate::config::Instance;
|
||||||
use crate::http_signatures::create::{create_http_signature, SignatureError};
|
use crate::http_signatures::create::{create_http_signature, SignatureError};
|
||||||
use crate::models::profiles::types::ProfileCreateData;
|
|
||||||
use crate::utils::files::{save_file, FileError};
|
use crate::utils::files::{save_file, FileError};
|
||||||
use crate::webfinger::types::JsonResourceDescriptor;
|
use crate::webfinger::types::JsonResourceDescriptor;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum FetchError {
|
pub enum FetchError {
|
||||||
#[error("invalid URL")]
|
|
||||||
UrlError(#[from] url::ParseError),
|
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
SignatureError(#[from] SignatureError),
|
SignatureError(#[from] SignatureError),
|
||||||
|
|
||||||
|
@ -150,40 +146,6 @@ pub async fn fetch_avatar_and_banner(
|
||||||
Ok((avatar, 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(
|
pub async fn fetch_object(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
object_url: &str,
|
object_url: &str,
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::path::Path;
|
||||||
use tokio_postgres::GenericClient;
|
use tokio_postgres::GenericClient;
|
||||||
|
|
||||||
use crate::activitypub::activity::Object;
|
use crate::activitypub::activity::Object;
|
||||||
use crate::activitypub::actor::ActorAddress;
|
use crate::activitypub::actor::{Actor, ActorAddress};
|
||||||
use crate::activitypub::handlers::{
|
use crate::activitypub::handlers::{
|
||||||
create_note::handle_note,
|
create_note::handle_note,
|
||||||
update_person::update_actor,
|
update_person::update_actor,
|
||||||
|
@ -19,11 +19,11 @@ use crate::models::profiles::queries::{
|
||||||
get_profile_by_acct,
|
get_profile_by_acct,
|
||||||
create_profile,
|
create_profile,
|
||||||
};
|
};
|
||||||
use crate::models::profiles::types::DbActorProfile;
|
use crate::models::profiles::types::{DbActorProfile, ProfileCreateData};
|
||||||
use super::fetchers::{
|
use super::fetchers::{
|
||||||
fetch_actor,
|
fetch_actor,
|
||||||
|
fetch_avatar_and_banner,
|
||||||
fetch_object,
|
fetch_object,
|
||||||
fetch_profile_by_actor_id,
|
|
||||||
perform_webfinger_query,
|
perform_webfinger_query,
|
||||||
FetchError,
|
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(
|
pub async fn get_or_import_profile_by_actor_id(
|
||||||
db_client: &impl GenericClient,
|
db_client: &impl GenericClient,
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
|
@ -77,14 +116,12 @@ pub async fn get_or_import_profile_by_actor_id(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(DatabaseError::NotFound(_)) => {
|
Err(DatabaseError::NotFound(_)) => {
|
||||||
let mut profile_data = fetch_profile_by_actor_id(
|
let actor = fetch_actor(instance, actor_id).await?;
|
||||||
instance, actor_id, media_dir,
|
let mut profile_data = prepare_remote_profile_data(
|
||||||
)
|
instance,
|
||||||
.await
|
media_dir,
|
||||||
.map_err(|err| {
|
actor,
|
||||||
log::warn!("failed to fetch {} ({})", actor_id, err);
|
).await?;
|
||||||
err
|
|
||||||
})?;
|
|
||||||
log::info!("fetched profile {}", profile_data.acct);
|
log::info!("fetched profile {}", profile_data.acct);
|
||||||
profile_data.clean()?;
|
profile_data.clean()?;
|
||||||
let profile = create_profile(db_client, profile_data).await?;
|
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);
|
return Err(ImportError::LocalObject);
|
||||||
};
|
};
|
||||||
let actor_id = perform_webfinger_query(instance, actor_address).await?;
|
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,
|
instance,
|
||||||
&actor_id,
|
|
||||||
media_dir,
|
media_dir,
|
||||||
|
actor,
|
||||||
).await?;
|
).await?;
|
||||||
if profile_data.acct != actor_address.acct() {
|
if profile_data.acct != actor_address.acct() {
|
||||||
// Redirected to different server
|
// Redirected to different server
|
||||||
|
|
|
@ -106,7 +106,10 @@ pub async fn handle_note(
|
||||||
instance,
|
instance,
|
||||||
media_dir,
|
media_dir,
|
||||||
&author_id,
|
&author_id,
|
||||||
).await?;
|
).await.map_err(|err| {
|
||||||
|
log::warn!("failed to import {} ({})", author_id, err);
|
||||||
|
err
|
||||||
|
})?;
|
||||||
let content = get_note_content(&object)?;
|
let content = get_note_content(&object)?;
|
||||||
|
|
||||||
let mut attachments: Vec<Uuid> = Vec::new();
|
let mut attachments: Vec<Uuid> = Vec::new();
|
||||||
|
|
Loading…
Reference in a new issue