Verify that actor alias exists before moving local followers
This commit is contained in:
parent
ff7c6724a0
commit
a3ec1e7b58
2 changed files with 47 additions and 11 deletions
|
@ -87,7 +87,7 @@ pub async fn handle_move_person(
|
||||||
.map_err(|_| ValidationError("invalid alias list"))?;
|
.map_err(|_| ValidationError("invalid alias list"))?;
|
||||||
aliases.extend(also_known_as);
|
aliases.extend(also_known_as);
|
||||||
};
|
};
|
||||||
if !aliases.iter().any(|actor_id| actor_id == &old_actor_id) {
|
if !aliases.contains(&old_actor_id) {
|
||||||
return Err(ValidationError("target ID is not an alias").into());
|
return Err(ValidationError("target ID is not an alias").into());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ use crate::models::profiles::queries::{
|
||||||
get_profile_by_id,
|
get_profile_by_id,
|
||||||
get_profile_by_remote_actor_id,
|
get_profile_by_remote_actor_id,
|
||||||
search_profiles_by_did,
|
search_profiles_by_did,
|
||||||
|
search_profiles_by_did_only,
|
||||||
update_profile,
|
update_profile,
|
||||||
};
|
};
|
||||||
use crate::models::profiles::types::{
|
use crate::models::profiles::types::{
|
||||||
|
@ -273,7 +274,8 @@ async fn move_followers(
|
||||||
) -> Result<HttpResponse, HttpError> {
|
) -> Result<HttpResponse, HttpError> {
|
||||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||||
let current_user = get_current_user(db_client, auth.token()).await?;
|
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||||
// Old profile could be deleted
|
// Existence of actor is not verified because
|
||||||
|
// the old profile could have been deleted
|
||||||
let maybe_from_profile = match get_profile_by_remote_actor_id(
|
let maybe_from_profile = match get_profile_by_remote_actor_id(
|
||||||
db_client,
|
db_client,
|
||||||
&request_data.from_actor_id,
|
&request_data.from_actor_id,
|
||||||
|
@ -282,6 +284,26 @@ async fn move_followers(
|
||||||
Err(DatabaseError::NotFound(_)) => None,
|
Err(DatabaseError::NotFound(_)) => None,
|
||||||
Err(other_error) => return Err(other_error.into()),
|
Err(other_error) => return Err(other_error.into()),
|
||||||
};
|
};
|
||||||
|
if maybe_from_profile.is_some() {
|
||||||
|
// Find known aliases of the current user
|
||||||
|
let mut aliases = vec![];
|
||||||
|
for identity_proof in current_user.profile.identity_proofs.inner() {
|
||||||
|
let profiles = search_profiles_by_did_only(
|
||||||
|
db_client,
|
||||||
|
&identity_proof.issuer,
|
||||||
|
).await?;
|
||||||
|
for profile in profiles {
|
||||||
|
if profile.id == current_user.id {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let actor_id = profile.actor_id(&config.instance_url());
|
||||||
|
aliases.push(actor_id);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if !aliases.contains(&request_data.from_actor_id) {
|
||||||
|
return Err(ValidationError("old profile is not an alias").into());
|
||||||
|
};
|
||||||
|
};
|
||||||
let mut followers = vec![];
|
let mut followers = vec![];
|
||||||
for follower_address in request_data.followers_csv.lines() {
|
for follower_address in request_data.followers_csv.lines() {
|
||||||
let follower_acct = ActorAddress::from_str(follower_address)?
|
let follower_acct = ActorAddress::from_str(follower_address)?
|
||||||
|
@ -292,19 +314,33 @@ async fn move_followers(
|
||||||
// Add remote actor to activity recipients list
|
// Add remote actor to activity recipients list
|
||||||
followers.push(remote_actor.id);
|
followers.push(remote_actor.id);
|
||||||
} else {
|
} else {
|
||||||
// Immediately move local followers
|
// Immediately move local followers (only if alias can be verified)
|
||||||
if let Some(ref from_profile) = maybe_from_profile {
|
if let Some(ref from_profile) = maybe_from_profile {
|
||||||
match unfollow(db_client, &follower.id, &from_profile.id).await {
|
match unfollow(db_client, &follower.id, &from_profile.id).await {
|
||||||
Ok(_) => (),
|
Ok(maybe_follow_request_id) => {
|
||||||
Err(DatabaseError::NotFound(_)) => (),
|
// Send Undo(Follow) to a remote actor
|
||||||
|
let remote_actor = from_profile.actor_json.as_ref()
|
||||||
|
.expect("actor data must be present");
|
||||||
|
let follow_request_id = maybe_follow_request_id
|
||||||
|
.expect("follow request must exist");
|
||||||
|
// TODO: send in a batch
|
||||||
|
prepare_undo_follow(
|
||||||
|
&config.instance(),
|
||||||
|
¤t_user,
|
||||||
|
remote_actor,
|
||||||
|
&follow_request_id,
|
||||||
|
).spawn_deliver();
|
||||||
|
},
|
||||||
|
// Not a follower, ignore
|
||||||
|
Err(DatabaseError::NotFound(_)) => continue,
|
||||||
|
Err(other_error) => return Err(other_error.into()),
|
||||||
|
};
|
||||||
|
match follow(db_client, &follower.id, ¤t_user.id).await {
|
||||||
|
Ok(_) => (),
|
||||||
|
// Ignore if already following
|
||||||
|
Err(DatabaseError::AlreadyExists(_)) => (),
|
||||||
Err(other_error) => return Err(other_error.into()),
|
Err(other_error) => return Err(other_error.into()),
|
||||||
};
|
};
|
||||||
};
|
|
||||||
match follow(db_client, &follower.id, ¤t_user.id).await {
|
|
||||||
Ok(_) => (),
|
|
||||||
// Ignore if already following
|
|
||||||
Err(DatabaseError::AlreadyExists(_)) => (),
|
|
||||||
Err(other_error) => return Err(other_error.into()),
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue