Pass Actor object instead of Value when creating/updating profile
This commit is contained in:
parent
a9504de10d
commit
a97456d77a
5 changed files with 23 additions and 32 deletions
|
@ -18,7 +18,7 @@ use super::vocabulary::{IMAGE, PERSON, PROPERTY_VALUE, SERVICE};
|
||||||
|
|
||||||
const W3ID_CONTEXT: &str = "https://w3id.org/security/v1";
|
const W3ID_CONTEXT: &str = "https://w3id.org/security/v1";
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[cfg_attr(test, derive(Default))]
|
#[cfg_attr(test, derive(Default))]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct PublicKey {
|
pub struct PublicKey {
|
||||||
|
@ -27,7 +27,7 @@ pub struct PublicKey {
|
||||||
pub public_key_pem: String,
|
pub public_key_pem: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -35,14 +35,14 @@ pub struct Image {
|
||||||
pub url: String,
|
pub url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ActorCapabilities {
|
pub struct ActorCapabilities {
|
||||||
// Actpr accepts ChatMessage objects
|
// Actor accepts ChatMessage objects
|
||||||
accepts_chat_messages: Option<bool>,
|
accepts_chat_messages: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct ActorProperty {
|
pub struct ActorProperty {
|
||||||
name: String,
|
name: String,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
@ -50,8 +50,8 @@ pub struct ActorProperty {
|
||||||
value: Option<String>,
|
value: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone trait is required by FromSql
|
// Clone and Debug traits are required by FromSql
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[cfg_attr(test, derive(Default))]
|
#[cfg_attr(test, derive(Default))]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Actor {
|
pub struct Actor {
|
||||||
|
|
|
@ -144,8 +144,7 @@ pub async fn fetch_profile_by_actor_id(
|
||||||
return Err(FetchError::OtherError("trying to fetch local profile"));
|
return Err(FetchError::OtherError("trying to fetch local profile"));
|
||||||
};
|
};
|
||||||
let actor_json = send_request(instance, actor_url, &[]).await?;
|
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_str(&actor_json)?;
|
||||||
let actor: Actor = serde_json::from_value(actor_value.clone())?;
|
|
||||||
let (avatar, banner) = fetch_avatar_and_banner(&actor, media_dir).await?;
|
let (avatar, banner) = fetch_avatar_and_banner(&actor, media_dir).await?;
|
||||||
let extra_fields = actor.extra_fields();
|
let extra_fields = actor.extra_fields();
|
||||||
let actor_address = format!(
|
let actor_address = format!(
|
||||||
|
@ -154,14 +153,14 @@ pub async fn fetch_profile_by_actor_id(
|
||||||
actor_host,
|
actor_host,
|
||||||
);
|
);
|
||||||
let profile_data = ProfileCreateData {
|
let profile_data = ProfileCreateData {
|
||||||
username: actor.preferred_username,
|
username: actor.preferred_username.clone(),
|
||||||
display_name: actor.name,
|
display_name: actor.name.clone(),
|
||||||
acct: actor_address,
|
acct: actor_address,
|
||||||
bio: actor.summary,
|
bio: actor.summary.clone(),
|
||||||
avatar,
|
avatar,
|
||||||
banner,
|
banner,
|
||||||
extra_fields,
|
extra_fields,
|
||||||
actor_json: Some(actor_value),
|
actor_json: Some(actor),
|
||||||
};
|
};
|
||||||
Ok(profile_data)
|
Ok(profile_data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -690,7 +690,6 @@ pub async fn receive_activity(
|
||||||
},
|
},
|
||||||
(UPDATE, PERSON) => {
|
(UPDATE, PERSON) => {
|
||||||
require_actor_signature(&activity.actor, &signer_id)?;
|
require_actor_signature(&activity.actor, &signer_id)?;
|
||||||
let actor_value = activity.object.clone();
|
|
||||||
let actor: Actor = serde_json::from_value(activity.object)
|
let actor: Actor = serde_json::from_value(activity.object)
|
||||||
.map_err(|_| ValidationError("invalid actor data"))?;
|
.map_err(|_| ValidationError("invalid actor data"))?;
|
||||||
if actor.id != activity.actor {
|
if actor.id != activity.actor {
|
||||||
|
@ -716,13 +715,13 @@ pub async fn receive_activity(
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
let mut profile_data = ProfileUpdateData {
|
let mut profile_data = ProfileUpdateData {
|
||||||
display_name: actor.name,
|
display_name: actor.name.clone(),
|
||||||
bio: actor.summary.clone(),
|
bio: actor.summary.clone(),
|
||||||
bio_source: actor.summary,
|
bio_source: actor.summary.clone(),
|
||||||
avatar,
|
avatar,
|
||||||
banner,
|
banner,
|
||||||
extra_fields,
|
extra_fields,
|
||||||
actor_json: Some(actor_value),
|
actor_json: Some(actor),
|
||||||
};
|
};
|
||||||
profile_data.clean()?;
|
profile_data.clean()?;
|
||||||
update_profile(db_client, &profile.id, profile_data).await?;
|
update_profile(db_client, &profile.id, profile_data).await?;
|
||||||
|
|
|
@ -471,8 +471,8 @@ pub async fn update_post_count(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use serde_json::json;
|
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
use crate::activitypub::actor::Actor;
|
||||||
use crate::database::test_utils::create_test_database;
|
use crate::database::test_utils::create_test_database;
|
||||||
use crate::models::profiles::queries::create_profile;
|
use crate::models::profiles::queries::create_profile;
|
||||||
use crate::models::profiles::types::{ExtraField, ProfileCreateData};
|
use crate::models::profiles::types::{ExtraField, ProfileCreateData};
|
||||||
|
@ -497,27 +497,20 @@ mod tests {
|
||||||
async fn test_actor_id_unique() {
|
async fn test_actor_id_unique() {
|
||||||
let db_client = create_test_database().await;
|
let db_client = create_test_database().await;
|
||||||
let actor_id = "https://example.com/users/test";
|
let actor_id = "https://example.com/users/test";
|
||||||
let create_actor_value = |actor_id| {
|
let create_actor = |actor_id: &str| {
|
||||||
json!({
|
Actor { id: actor_id.to_string(), ..Default::default() }
|
||||||
"id": actor_id,
|
|
||||||
"type": "Person",
|
|
||||||
"preferredUsername": "test",
|
|
||||||
"inbox": "https://test",
|
|
||||||
"outbox": "https://test",
|
|
||||||
"publicKey": {"id": "test", "owner": "test", "publicKeyPem": "test"},
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
let profile_data_1 = ProfileCreateData {
|
let profile_data_1 = ProfileCreateData {
|
||||||
username: "test-1".to_string(),
|
username: "test-1".to_string(),
|
||||||
acct: "test-1@example.com".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()
|
..Default::default()
|
||||||
};
|
};
|
||||||
create_profile(&db_client, profile_data_1).await.unwrap();
|
create_profile(&db_client, profile_data_1).await.unwrap();
|
||||||
let profile_data_2 = ProfileCreateData {
|
let profile_data_2 = ProfileCreateData {
|
||||||
username: "test-2".to_string(),
|
username: "test-2".to_string(),
|
||||||
acct: "test-2@example.com".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()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let error = create_profile(&db_client, profile_data_2).await.err().unwrap();
|
let error = create_profile(&db_client, profile_data_2).await.err().unwrap();
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use postgres_types::FromSql;
|
use postgres_types::FromSql;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::activitypub::actor::Actor;
|
use crate::activitypub::actor::Actor;
|
||||||
|
@ -40,6 +39,7 @@ json_from_sql!(ExtraFields);
|
||||||
json_to_sql!(ExtraFields);
|
json_to_sql!(ExtraFields);
|
||||||
|
|
||||||
json_from_sql!(Actor);
|
json_from_sql!(Actor);
|
||||||
|
json_to_sql!(Actor);
|
||||||
|
|
||||||
#[derive(Clone, FromSql)]
|
#[derive(Clone, FromSql)]
|
||||||
#[postgres(name = "actor_profile")]
|
#[postgres(name = "actor_profile")]
|
||||||
|
@ -127,7 +127,7 @@ pub struct ProfileCreateData {
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<String>,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<String>,
|
||||||
pub extra_fields: Vec<ExtraField>,
|
pub extra_fields: Vec<ExtraField>,
|
||||||
pub actor_json: Option<Value>,
|
pub actor_json: Option<Actor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProfileCreateData {
|
impl ProfileCreateData {
|
||||||
|
@ -152,7 +152,7 @@ pub struct ProfileUpdateData {
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<String>,
|
||||||
pub banner: Option<String>,
|
pub banner: Option<String>,
|
||||||
pub extra_fields: Vec<ExtraField>,
|
pub extra_fields: Vec<ExtraField>,
|
||||||
pub actor_json: Option<Value>,
|
pub actor_json: Option<Actor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProfileUpdateData {
|
impl ProfileUpdateData {
|
||||||
|
|
Loading…
Reference in a new issue