Add "aliases" column to actor profile table
It is used to store unverified aliases, and potentially can be used for verified aliases too.
This commit is contained in:
parent
c80bfccd6a
commit
b56e11e81d
8 changed files with 65 additions and 5 deletions
1
migrations/V0050__actor_profile__add_aliases.sql
Normal file
1
migrations/V0050__actor_profile__add_aliases.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE actor_profile ADD COLUMN aliases JSONB NOT NULL DEFAULT '[]';
|
|
@ -30,6 +30,7 @@ CREATE TABLE actor_profile (
|
||||||
identity_proofs JSONB NOT NULL DEFAULT '[]',
|
identity_proofs JSONB NOT NULL DEFAULT '[]',
|
||||||
payment_options JSONB NOT NULL DEFAULT '[]',
|
payment_options JSONB NOT NULL DEFAULT '[]',
|
||||||
extra_fields JSONB NOT NULL DEFAULT '[]',
|
extra_fields JSONB NOT NULL DEFAULT '[]',
|
||||||
|
aliases JSONB NOT NULL DEFAULT '[]',
|
||||||
follower_count INTEGER NOT NULL CHECK (follower_count >= 0) DEFAULT 0,
|
follower_count INTEGER NOT NULL CHECK (follower_count >= 0) DEFAULT 0,
|
||||||
following_count INTEGER NOT NULL CHECK (following_count >= 0) DEFAULT 0,
|
following_count INTEGER NOT NULL CHECK (following_count >= 0) DEFAULT 0,
|
||||||
subscriber_count INTEGER NOT NULL CHECK (subscriber_count >= 0) DEFAULT 0,
|
subscriber_count INTEGER NOT NULL CHECK (subscriber_count >= 0) DEFAULT 0,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::activitypub::{
|
||||||
actors::types::Actor,
|
actors::types::Actor,
|
||||||
fetcher::fetchers::fetch_file,
|
fetcher::fetchers::fetch_file,
|
||||||
handlers::create::handle_emoji,
|
handlers::create::handle_emoji,
|
||||||
receiver::HandlerError,
|
receiver::{parse_array, HandlerError},
|
||||||
vocabulary::{EMOJI, HASHTAG},
|
vocabulary::{EMOJI, HASHTAG},
|
||||||
};
|
};
|
||||||
use crate::database::DatabaseClient;
|
use crate::database::DatabaseClient;
|
||||||
|
@ -83,6 +83,21 @@ async fn fetch_actor_images(
|
||||||
(maybe_avatar, maybe_banner)
|
(maybe_avatar, maybe_banner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_aliases(actor: &Actor) -> Vec<String> {
|
||||||
|
// Aliases reported by server (not signed)
|
||||||
|
actor.also_known_as.as_ref()
|
||||||
|
.and_then(|value| {
|
||||||
|
match parse_array(value) {
|
||||||
|
Ok(array) => Some(array),
|
||||||
|
Err(_) => {
|
||||||
|
log::warn!("invalid alias list: {}", value);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
async fn parse_tags(
|
async fn parse_tags(
|
||||||
db_client: &impl DatabaseClient,
|
db_client: &impl DatabaseClient,
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
|
@ -136,6 +151,7 @@ pub async fn create_remote_profile(
|
||||||
).await;
|
).await;
|
||||||
let (identity_proofs, payment_options, extra_fields) =
|
let (identity_proofs, payment_options, extra_fields) =
|
||||||
actor.parse_attachments();
|
actor.parse_attachments();
|
||||||
|
let aliases = parse_aliases(&actor);
|
||||||
let emojis = parse_tags(
|
let emojis = parse_tags(
|
||||||
db_client,
|
db_client,
|
||||||
instance,
|
instance,
|
||||||
|
@ -153,6 +169,7 @@ pub async fn create_remote_profile(
|
||||||
identity_proofs,
|
identity_proofs,
|
||||||
payment_options,
|
payment_options,
|
||||||
extra_fields,
|
extra_fields,
|
||||||
|
aliases,
|
||||||
emojis,
|
emojis,
|
||||||
actor_json: Some(actor),
|
actor_json: Some(actor),
|
||||||
};
|
};
|
||||||
|
@ -193,6 +210,7 @@ pub async fn update_remote_profile(
|
||||||
).await;
|
).await;
|
||||||
let (identity_proofs, payment_options, extra_fields) =
|
let (identity_proofs, payment_options, extra_fields) =
|
||||||
actor.parse_attachments();
|
actor.parse_attachments();
|
||||||
|
let aliases = parse_aliases(&actor);
|
||||||
let emojis = parse_tags(
|
let emojis = parse_tags(
|
||||||
db_client,
|
db_client,
|
||||||
instance,
|
instance,
|
||||||
|
@ -209,6 +227,7 @@ pub async fn update_remote_profile(
|
||||||
identity_proofs,
|
identity_proofs,
|
||||||
payment_options,
|
payment_options,
|
||||||
extra_fields,
|
extra_fields,
|
||||||
|
aliases,
|
||||||
emojis,
|
emojis,
|
||||||
actor_json: Some(actor),
|
actor_json: Some(actor),
|
||||||
};
|
};
|
||||||
|
|
|
@ -74,12 +74,13 @@ pub async fn handle_move(
|
||||||
let new_actor = new_profile.actor_json.as_ref()
|
let new_actor = new_profile.actor_json.as_ref()
|
||||||
.expect("target should be a remote actor");
|
.expect("target should be a remote actor");
|
||||||
|
|
||||||
// Find aliases by DIDs
|
// Find aliases by DIDs (signed)
|
||||||
let mut aliases = find_aliases(db_client, &new_profile).await?
|
let mut aliases = find_aliases(db_client, &new_profile).await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|profile| profile.actor_id(&instance.url()))
|
.map(|profile| profile.actor_id(&instance.url()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
// Read aliases from alsoKnownAs property
|
// Read aliases from alsoKnownAs property
|
||||||
|
// TODO: use new_profile.aliases.into_actor_ids()
|
||||||
if let Some(ref value) = new_actor.also_known_as {
|
if let Some(ref value) = new_actor.also_known_as {
|
||||||
let also_known_as = parse_array(value)
|
let also_known_as = parse_array(value)
|
||||||
.map_err(|_| ValidationError("invalid alias list"))?;
|
.map_err(|_| ValidationError("invalid alias list"))?;
|
||||||
|
|
|
@ -372,6 +372,7 @@ impl AccountUpdateData {
|
||||||
identity_proofs,
|
identity_proofs,
|
||||||
payment_options,
|
payment_options,
|
||||||
extra_fields,
|
extra_fields,
|
||||||
|
aliases: vec![],
|
||||||
emojis: vec![],
|
emojis: vec![],
|
||||||
actor_json: None, // always None for local profiles
|
actor_json: None, // always None for local profiles
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,6 +25,7 @@ use crate::models::{
|
||||||
relationships::types::RelationshipType,
|
relationships::types::RelationshipType,
|
||||||
};
|
};
|
||||||
use super::types::{
|
use super::types::{
|
||||||
|
Aliases,
|
||||||
DbActorProfile,
|
DbActorProfile,
|
||||||
ExtraFields,
|
ExtraFields,
|
||||||
IdentityProofs,
|
IdentityProofs,
|
||||||
|
@ -145,9 +146,10 @@ pub async fn create_profile(
|
||||||
identity_proofs,
|
identity_proofs,
|
||||||
payment_options,
|
payment_options,
|
||||||
extra_fields,
|
extra_fields,
|
||||||
|
aliases,
|
||||||
actor_json
|
actor_json
|
||||||
)
|
)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
|
||||||
RETURNING actor_profile
|
RETURNING actor_profile
|
||||||
",
|
",
|
||||||
&[
|
&[
|
||||||
|
@ -163,6 +165,7 @@ pub async fn create_profile(
|
||||||
&IdentityProofs(profile_data.identity_proofs),
|
&IdentityProofs(profile_data.identity_proofs),
|
||||||
&PaymentOptions(profile_data.payment_options),
|
&PaymentOptions(profile_data.payment_options),
|
||||||
&ExtraFields(profile_data.extra_fields),
|
&ExtraFields(profile_data.extra_fields),
|
||||||
|
&Aliases::new(profile_data.aliases),
|
||||||
&profile_data.actor_json,
|
&profile_data.actor_json,
|
||||||
],
|
],
|
||||||
).await.map_err(catch_unique_violation("profile"))?;
|
).await.map_err(catch_unique_violation("profile"))?;
|
||||||
|
@ -198,9 +201,10 @@ pub async fn update_profile(
|
||||||
identity_proofs = $7,
|
identity_proofs = $7,
|
||||||
payment_options = $8,
|
payment_options = $8,
|
||||||
extra_fields = $9,
|
extra_fields = $9,
|
||||||
actor_json = $10,
|
aliases = $10,
|
||||||
|
actor_json = $11,
|
||||||
updated_at = CURRENT_TIMESTAMP
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = $11
|
WHERE id = $12
|
||||||
RETURNING actor_profile
|
RETURNING actor_profile
|
||||||
",
|
",
|
||||||
&[
|
&[
|
||||||
|
@ -213,6 +217,7 @@ pub async fn update_profile(
|
||||||
&IdentityProofs(profile_data.identity_proofs),
|
&IdentityProofs(profile_data.identity_proofs),
|
||||||
&PaymentOptions(profile_data.payment_options),
|
&PaymentOptions(profile_data.payment_options),
|
||||||
&ExtraFields(profile_data.extra_fields),
|
&ExtraFields(profile_data.extra_fields),
|
||||||
|
&Aliases::new(profile_data.aliases),
|
||||||
&profile_data.actor_json,
|
&profile_data.actor_json,
|
||||||
&profile_id,
|
&profile_id,
|
||||||
],
|
],
|
||||||
|
|
|
@ -307,6 +307,32 @@ impl ExtraFields {
|
||||||
json_from_sql!(ExtraFields);
|
json_from_sql!(ExtraFields);
|
||||||
json_to_sql!(ExtraFields);
|
json_to_sql!(ExtraFields);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Alias {
|
||||||
|
pub id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct Aliases(Vec<Alias>);
|
||||||
|
|
||||||
|
impl Aliases {
|
||||||
|
pub fn new(actor_ids: Vec<String>) -> Self {
|
||||||
|
// Not signed
|
||||||
|
let aliases = actor_ids.into_iter()
|
||||||
|
.map(|actor_id| Alias { id: actor_id })
|
||||||
|
.collect();
|
||||||
|
Self(aliases)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_actor_ids(self) -> Vec<String> {
|
||||||
|
let Self(aliases) = self;
|
||||||
|
aliases.into_iter().map(|alias| alias.id).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json_from_sql!(Aliases);
|
||||||
|
json_to_sql!(Aliases);
|
||||||
|
|
||||||
#[derive(Clone, Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
pub struct ProfileEmojis(Vec<DbEmoji>);
|
pub struct ProfileEmojis(Vec<DbEmoji>);
|
||||||
|
|
||||||
|
@ -337,6 +363,7 @@ pub struct DbActorProfile {
|
||||||
pub identity_proofs: IdentityProofs,
|
pub identity_proofs: IdentityProofs,
|
||||||
pub payment_options: PaymentOptions,
|
pub payment_options: PaymentOptions,
|
||||||
pub extra_fields: ExtraFields,
|
pub extra_fields: ExtraFields,
|
||||||
|
pub aliases: Aliases,
|
||||||
pub follower_count: i32,
|
pub follower_count: i32,
|
||||||
pub following_count: i32,
|
pub following_count: i32,
|
||||||
pub subscriber_count: i32,
|
pub subscriber_count: i32,
|
||||||
|
@ -426,6 +453,7 @@ impl Default for DbActorProfile {
|
||||||
identity_proofs: IdentityProofs(vec![]),
|
identity_proofs: IdentityProofs(vec![]),
|
||||||
payment_options: PaymentOptions(vec![]),
|
payment_options: PaymentOptions(vec![]),
|
||||||
extra_fields: ExtraFields(vec![]),
|
extra_fields: ExtraFields(vec![]),
|
||||||
|
aliases: Aliases(vec![]),
|
||||||
follower_count: 0,
|
follower_count: 0,
|
||||||
following_count: 0,
|
following_count: 0,
|
||||||
subscriber_count: 0,
|
subscriber_count: 0,
|
||||||
|
@ -452,6 +480,7 @@ pub struct ProfileCreateData {
|
||||||
pub identity_proofs: Vec<IdentityProof>,
|
pub identity_proofs: Vec<IdentityProof>,
|
||||||
pub payment_options: Vec<PaymentOption>,
|
pub payment_options: Vec<PaymentOption>,
|
||||||
pub extra_fields: Vec<ExtraField>,
|
pub extra_fields: Vec<ExtraField>,
|
||||||
|
pub aliases: Vec<String>,
|
||||||
pub emojis: Vec<Uuid>,
|
pub emojis: Vec<Uuid>,
|
||||||
pub actor_json: Option<Actor>,
|
pub actor_json: Option<Actor>,
|
||||||
}
|
}
|
||||||
|
@ -485,6 +514,7 @@ pub struct ProfileUpdateData {
|
||||||
pub identity_proofs: Vec<IdentityProof>,
|
pub identity_proofs: Vec<IdentityProof>,
|
||||||
pub payment_options: Vec<PaymentOption>,
|
pub payment_options: Vec<PaymentOption>,
|
||||||
pub extra_fields: Vec<ExtraField>,
|
pub extra_fields: Vec<ExtraField>,
|
||||||
|
pub aliases: Vec<String>,
|
||||||
pub emojis: Vec<Uuid>,
|
pub emojis: Vec<Uuid>,
|
||||||
pub actor_json: Option<Actor>,
|
pub actor_json: Option<Actor>,
|
||||||
}
|
}
|
||||||
|
@ -534,6 +564,7 @@ impl From<&DbActorProfile> for ProfileUpdateData {
|
||||||
identity_proofs: profile.identity_proofs.into_inner(),
|
identity_proofs: profile.identity_proofs.into_inner(),
|
||||||
payment_options: profile.payment_options.into_inner(),
|
payment_options: profile.payment_options.into_inner(),
|
||||||
extra_fields: profile.extra_fields.into_inner(),
|
extra_fields: profile.extra_fields.into_inner(),
|
||||||
|
aliases: profile.aliases.into_actor_ids(),
|
||||||
emojis: profile.emojis.into_inner().into_iter()
|
emojis: profile.emojis.into_inner().into_iter()
|
||||||
.map(|emoji| emoji.id)
|
.map(|emoji| emoji.id)
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|
|
@ -118,6 +118,7 @@ pub async fn create_user(
|
||||||
identity_proofs: vec![],
|
identity_proofs: vec![],
|
||||||
payment_options: vec![],
|
payment_options: vec![],
|
||||||
extra_fields: vec![],
|
extra_fields: vec![],
|
||||||
|
aliases: vec![],
|
||||||
emojis: vec![],
|
emojis: vec![],
|
||||||
actor_json: None,
|
actor_json: None,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue