Sign Move() activity with server key

This commit is contained in:
silverpill 2023-01-08 23:21:31 +00:00
parent 8d41a94b94
commit 5fec0c187d
5 changed files with 23 additions and 71 deletions

View file

@ -738,7 +738,7 @@ paths:
user2@example.org user2@example.org
/api/v1/settings/move_followers: /api/v1/settings/move_followers:
post: post:
summary: Build Move(Person) activity for signing (experimental). summary: Move followers from remote alias.
requestBody: requestBody:
content: content:
application/json: application/json:
@ -761,15 +761,7 @@ paths:
content: content:
application/json: application/json:
schema: schema:
type: object $ref: '#/components/schemas/AccountWithSource'
properties:
params:
description: Activity parameters
$ref: '#/components/schemas/ActivityParameters'
message:
description: Canonical representation of activity.
type: string
example: '{"type":"Move"}'
400: 400:
description: Invalid data. description: Invalid data.
/api/v1/statuses: /api/v1/statuses:
@ -1332,7 +1324,6 @@ components:
description: Activity type description: Activity type
type: string type: string
enum: enum:
- move
- update - update
Attachment: Attachment:
type: object type: object

View file

@ -10,6 +10,7 @@ use crate::activitypub::{
}; };
use crate::config::Instance; use crate::config::Instance;
use crate::models::users::types::User; use crate::models::users::types::User;
use crate::utils::id::new_uuid;
#[derive(Serialize)] #[derive(Serialize)]
pub struct MovePerson { pub struct MovePerson {
@ -32,9 +33,11 @@ pub fn build_move_person(
sender: &User, sender: &User,
from_actor_id: &str, from_actor_id: &str,
followers: &[String], followers: &[String],
internal_activity_id: &Uuid, maybe_internal_activity_id: Option<&Uuid>,
) -> MovePerson { ) -> MovePerson {
let activity_id = local_object_id(instance_url, internal_activity_id); let internal_activity_id = maybe_internal_activity_id.copied()
.unwrap_or(new_uuid());
let activity_id = local_object_id(instance_url, &internal_activity_id);
let actor_id = local_actor_id(instance_url, &sender.profile.username); let actor_id = local_actor_id(instance_url, &sender.profile.username);
MovePerson { MovePerson {
context: AP_CONTEXT.to_string(), context: AP_CONTEXT.to_string(),
@ -47,12 +50,12 @@ pub fn build_move_person(
} }
} }
pub fn prepare_signed_move_person( pub fn prepare_move_person(
instance: &Instance, instance: &Instance,
sender: &User, sender: &User,
from_actor_id: &str, from_actor_id: &str,
followers: Vec<Actor>, followers: Vec<Actor>,
internal_activity_id: &Uuid, maybe_internal_activity_id: Option<&Uuid>,
) -> OutgoingActivity { ) -> OutgoingActivity {
let followers_ids: Vec<String> = followers.iter() let followers_ids: Vec<String> = followers.iter()
.map(|actor| actor.id.clone()) .map(|actor| actor.id.clone())
@ -62,7 +65,7 @@ pub fn prepare_signed_move_person(
sender, sender,
from_actor_id, from_actor_id,
&followers_ids, &followers_ids,
internal_activity_id, maybe_internal_activity_id,
); );
OutgoingActivity::new( OutgoingActivity::new(
instance, instance,
@ -100,7 +103,7 @@ mod tests {
&sender, &sender,
from_actor_id, from_actor_id,
&followers, &followers,
&internal_activity_id, Some(&internal_activity_id),
); );
assert_eq!( assert_eq!(

View file

@ -308,11 +308,6 @@ impl AccountUpdateData {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "kebab-case")] #[serde(tag = "type", rename_all = "kebab-case")]
pub enum ActivityParams { pub enum ActivityParams {
Move {
internal_activity_id: Uuid,
from_actor_id: String,
followers: Vec<String>,
},
Update { internal_activity_id: Uuid }, Update { internal_activity_id: Uuid },
} }

View file

@ -7,9 +7,6 @@ use uuid::Uuid;
use crate::activitypub::builders::{ use crate::activitypub::builders::{
follow::prepare_follow, follow::prepare_follow,
move_person::{
prepare_signed_move_person,
},
undo_follow::prepare_undo_follow, undo_follow::prepare_undo_follow,
update_person::{ update_person::{
build_update_person, build_update_person,
@ -49,7 +46,6 @@ use crate::models::posts::queries::get_posts_by_author;
use crate::models::profiles::queries::{ use crate::models::profiles::queries::{
get_profile_by_acct, get_profile_by_acct,
get_profile_by_id, get_profile_by_id,
get_profile_by_remote_actor_id,
search_profiles_by_did, search_profiles_by_did,
update_profile, update_profile,
}; };
@ -275,26 +271,6 @@ async fn send_signed_activity(
return Err(ValidationError("unknown signer").into()); return Err(ValidationError("unknown signer").into());
}; };
let mut outgoing_activity = match &data.params { let mut outgoing_activity = match &data.params {
ActivityParams::Move {
internal_activity_id,
from_actor_id,
followers: followers_ids,
} => {
let mut followers = vec![];
for actor_id in followers_ids {
let remote_actor = get_profile_by_remote_actor_id(db_client, actor_id)
.await?
.actor_json.ok_or(HttpError::InternalError)?;
followers.push(remote_actor);
};
prepare_signed_move_person(
&config.instance(),
&current_user,
from_actor_id,
followers,
internal_activity_id,
)
},
ActivityParams::Update { internal_activity_id } => { ActivityParams::Update { internal_activity_id } => {
prepare_update_person( prepare_update_person(
db_client, db_client,

View file

@ -6,7 +6,7 @@ use actix_web_httpauth::extractors::bearer::BearerAuth;
use crate::activitypub::{ use crate::activitypub::{
actors::types::ActorAddress, actors::types::ActorAddress,
builders::{ builders::{
move_person::build_move_person, move_person::prepare_move_person,
undo_follow::prepare_undo_follow, undo_follow::prepare_undo_follow,
}, },
}; };
@ -14,7 +14,7 @@ use crate::config::Config;
use crate::database::{get_database_client, DatabaseError, DbPool}; use crate::database::{get_database_client, DatabaseError, DbPool};
use crate::errors::{HttpError, ValidationError}; use crate::errors::{HttpError, ValidationError};
use crate::mastodon_api::{ use crate::mastodon_api::{
accounts::types::{Account, ActivityParams, UnsignedActivity}, accounts::types::Account,
oauth::auth::get_current_user, oauth::auth::get_current_user,
}; };
use crate::models::{ use crate::models::{
@ -23,11 +23,7 @@ use crate::models::{
relationships::queries::{follow, unfollow}, relationships::queries::{follow, unfollow},
users::queries::set_user_password, users::queries::set_user_password,
}; };
use crate::utils::{ use crate::utils::passwords::hash_password;
canonicalization::canonicalize_object,
id::new_uuid,
passwords::hash_password,
};
use super::helpers::{export_followers, export_follows}; use super::helpers::{export_followers, export_follows};
use super::types::{MoveFollowersRequest, PasswordChangeRequest}; use super::types::{MoveFollowersRequest, PasswordChangeRequest};
@ -121,7 +117,7 @@ async fn move_followers(
let follower = get_profile_by_acct(db_client, &follower_acct).await?; let follower = get_profile_by_acct(db_client, &follower_acct).await?;
if let Some(remote_actor) = follower.actor_json { if let Some(remote_actor) = follower.actor_json {
// Add remote actor to activity recipients list // Add remote actor to activity recipients list
followers.push(remote_actor.id); followers.push(remote_actor);
} else { } else {
// Immediately move local followers (only if alias can be verified) // 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 {
@ -152,25 +148,16 @@ async fn move_followers(
}; };
}; };
}; };
let internal_activity_id = new_uuid(); prepare_move_person(
let activity = build_move_person( &config.instance(),
&config.instance_url(),
&current_user, &current_user,
&request_data.from_actor_id, &request_data.from_actor_id,
&followers,
&internal_activity_id,
);
let canonical_json = canonicalize_object(&activity)
.map_err(|_| HttpError::InternalError)?;
let data = UnsignedActivity {
params: ActivityParams::Move {
internal_activity_id,
from_actor_id: request_data.from_actor_id.clone(),
followers, followers,
}, None,
message: canonical_json, ).enqueue(db_client).await?;
};
Ok(HttpResponse::Ok().json(data)) let account = Account::from_user(current_user, &config.instance_url());
Ok(HttpResponse::Ok().json(account))
} }
pub fn settings_api_scope() -> Scope { pub fn settings_api_scope() -> Scope {