Pass Actor object instead of Value when creating/updating profile

This commit is contained in:
silverpill 2022-04-21 22:52:28 +00:00
parent a9504de10d
commit a97456d77a
5 changed files with 23 additions and 32 deletions

View file

@ -18,7 +18,7 @@ use super::vocabulary::{IMAGE, PERSON, PROPERTY_VALUE, SERVICE};
const W3ID_CONTEXT: &str = "https://w3id.org/security/v1";
#[derive(Clone, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(test, derive(Default))]
#[serde(rename_all = "camelCase")]
pub struct PublicKey {
@ -27,7 +27,7 @@ pub struct PublicKey {
pub public_key_pem: String,
}
#[derive(Clone, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Image {
#[serde(rename = "type")]
@ -35,14 +35,14 @@ pub struct Image {
pub url: String,
}
#[derive(Clone, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ActorCapabilities {
// Actpr accepts ChatMessage objects
// Actor accepts ChatMessage objects
accepts_chat_messages: Option<bool>,
}
#[derive(Clone, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ActorProperty {
name: String,
#[serde(rename = "type")]
@ -50,8 +50,8 @@ pub struct ActorProperty {
value: Option<String>,
}
// Clone trait is required by FromSql
#[derive(Clone, Deserialize, Serialize)]
// Clone and Debug traits are required by FromSql
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(test, derive(Default))]
#[serde(rename_all = "camelCase")]
pub struct Actor {

View file

@ -144,8 +144,7 @@ pub async fn fetch_profile_by_actor_id(
return Err(FetchError::OtherError("trying to fetch local profile"));
};
let actor_json = send_request(instance, actor_url, &[]).await?;
let actor_value: Value = serde_json::from_str(&actor_json)?;
let actor: Actor = serde_json::from_value(actor_value.clone())?;
let actor: Actor = serde_json::from_str(&actor_json)?;
let (avatar, banner) = fetch_avatar_and_banner(&actor, media_dir).await?;
let extra_fields = actor.extra_fields();
let actor_address = format!(
@ -154,14 +153,14 @@ pub async fn fetch_profile_by_actor_id(
actor_host,
);
let profile_data = ProfileCreateData {
username: actor.preferred_username,
display_name: actor.name,
username: actor.preferred_username.clone(),
display_name: actor.name.clone(),
acct: actor_address,
bio: actor.summary,
bio: actor.summary.clone(),
avatar,
banner,
extra_fields,
actor_json: Some(actor_value),
actor_json: Some(actor),
};
Ok(profile_data)
}

View file

@ -690,7 +690,6 @@ pub async fn receive_activity(
},
(UPDATE, PERSON) => {
require_actor_signature(&activity.actor, &signer_id)?;
let actor_value = activity.object.clone();
let actor: Actor = serde_json::from_value(activity.object)
.map_err(|_| ValidationError("invalid actor data"))?;
if actor.id != activity.actor {
@ -716,13 +715,13 @@ pub async fn receive_activity(
);
};
let mut profile_data = ProfileUpdateData {
display_name: actor.name,
display_name: actor.name.clone(),
bio: actor.summary.clone(),
bio_source: actor.summary,
bio_source: actor.summary.clone(),
avatar,
banner,
extra_fields,
actor_json: Some(actor_value),
actor_json: Some(actor),
};
profile_data.clean()?;
update_profile(db_client, &profile.id, profile_data).await?;

View file

@ -471,8 +471,8 @@ pub async fn update_post_count(
#[cfg(test)]
mod tests {
use serde_json::json;
use serial_test::serial;
use crate::activitypub::actor::Actor;
use crate::database::test_utils::create_test_database;
use crate::models::profiles::queries::create_profile;
use crate::models::profiles::types::{ExtraField, ProfileCreateData};
@ -497,27 +497,20 @@ mod tests {
async fn test_actor_id_unique() {
let db_client = create_test_database().await;
let actor_id = "https://example.com/users/test";
let create_actor_value = |actor_id| {
json!({
"id": actor_id,
"type": "Person",
"preferredUsername": "test",
"inbox": "https://test",
"outbox": "https://test",
"publicKey": {"id": "test", "owner": "test", "publicKeyPem": "test"},
})
let create_actor = |actor_id: &str| {
Actor { id: actor_id.to_string(), ..Default::default() }
};
let profile_data_1 = ProfileCreateData {
username: "test-1".to_string(),
acct: "test-1@example.com".to_string(),
actor_json: Some(create_actor_value(actor_id)),
actor_json: Some(create_actor(actor_id)),
..Default::default()
};
create_profile(&db_client, profile_data_1).await.unwrap();
let profile_data_2 = ProfileCreateData {
username: "test-2".to_string(),
acct: "test-2@example.com".to_string(),
actor_json: Some(create_actor_value(actor_id)),
actor_json: Some(create_actor(actor_id)),
..Default::default()
};
let error = create_profile(&db_client, profile_data_2).await.err().unwrap();

View file

@ -1,7 +1,6 @@
use chrono::{DateTime, Utc};
use postgres_types::FromSql;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use uuid::Uuid;
use crate::activitypub::actor::Actor;
@ -40,6 +39,7 @@ json_from_sql!(ExtraFields);
json_to_sql!(ExtraFields);
json_from_sql!(Actor);
json_to_sql!(Actor);
#[derive(Clone, FromSql)]
#[postgres(name = "actor_profile")]
@ -127,7 +127,7 @@ pub struct ProfileCreateData {
pub avatar: Option<String>,
pub banner: Option<String>,
pub extra_fields: Vec<ExtraField>,
pub actor_json: Option<Value>,
pub actor_json: Option<Actor>,
}
impl ProfileCreateData {
@ -152,7 +152,7 @@ pub struct ProfileUpdateData {
pub avatar: Option<String>,
pub banner: Option<String>,
pub extra_fields: Vec<ExtraField>,
pub actor_json: Option<Value>,
pub actor_json: Option<Actor>,
}
impl ProfileUpdateData {