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 '[]',
|
||||
payment_options 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,
|
||||
following_count INTEGER NOT NULL CHECK (following_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,
|
||||
fetcher::fetchers::fetch_file,
|
||||
handlers::create::handle_emoji,
|
||||
receiver::HandlerError,
|
||||
receiver::{parse_array, HandlerError},
|
||||
vocabulary::{EMOJI, HASHTAG},
|
||||
};
|
||||
use crate::database::DatabaseClient;
|
||||
|
@ -83,6 +83,21 @@ async fn fetch_actor_images(
|
|||
(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(
|
||||
db_client: &impl DatabaseClient,
|
||||
instance: &Instance,
|
||||
|
@ -136,6 +151,7 @@ pub async fn create_remote_profile(
|
|||
).await;
|
||||
let (identity_proofs, payment_options, extra_fields) =
|
||||
actor.parse_attachments();
|
||||
let aliases = parse_aliases(&actor);
|
||||
let emojis = parse_tags(
|
||||
db_client,
|
||||
instance,
|
||||
|
@ -153,6 +169,7 @@ pub async fn create_remote_profile(
|
|||
identity_proofs,
|
||||
payment_options,
|
||||
extra_fields,
|
||||
aliases,
|
||||
emojis,
|
||||
actor_json: Some(actor),
|
||||
};
|
||||
|
@ -193,6 +210,7 @@ pub async fn update_remote_profile(
|
|||
).await;
|
||||
let (identity_proofs, payment_options, extra_fields) =
|
||||
actor.parse_attachments();
|
||||
let aliases = parse_aliases(&actor);
|
||||
let emojis = parse_tags(
|
||||
db_client,
|
||||
instance,
|
||||
|
@ -209,6 +227,7 @@ pub async fn update_remote_profile(
|
|||
identity_proofs,
|
||||
payment_options,
|
||||
extra_fields,
|
||||
aliases,
|
||||
emojis,
|
||||
actor_json: Some(actor),
|
||||
};
|
||||
|
|
|
@ -74,12 +74,13 @@ pub async fn handle_move(
|
|||
let new_actor = new_profile.actor_json.as_ref()
|
||||
.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?
|
||||
.into_iter()
|
||||
.map(|profile| profile.actor_id(&instance.url()))
|
||||
.collect::<Vec<_>>();
|
||||
// Read aliases from alsoKnownAs property
|
||||
// TODO: use new_profile.aliases.into_actor_ids()
|
||||
if let Some(ref value) = new_actor.also_known_as {
|
||||
let also_known_as = parse_array(value)
|
||||
.map_err(|_| ValidationError("invalid alias list"))?;
|
||||
|
|
|
@ -372,6 +372,7 @@ impl AccountUpdateData {
|
|||
identity_proofs,
|
||||
payment_options,
|
||||
extra_fields,
|
||||
aliases: vec![],
|
||||
emojis: vec![],
|
||||
actor_json: None, // always None for local profiles
|
||||
};
|
||||
|
|
|
@ -25,6 +25,7 @@ use crate::models::{
|
|||
relationships::types::RelationshipType,
|
||||
};
|
||||
use super::types::{
|
||||
Aliases,
|
||||
DbActorProfile,
|
||||
ExtraFields,
|
||||
IdentityProofs,
|
||||
|
@ -145,9 +146,10 @@ pub async fn create_profile(
|
|||
identity_proofs,
|
||||
payment_options,
|
||||
extra_fields,
|
||||
aliases,
|
||||
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
|
||||
",
|
||||
&[
|
||||
|
@ -163,6 +165,7 @@ pub async fn create_profile(
|
|||
&IdentityProofs(profile_data.identity_proofs),
|
||||
&PaymentOptions(profile_data.payment_options),
|
||||
&ExtraFields(profile_data.extra_fields),
|
||||
&Aliases::new(profile_data.aliases),
|
||||
&profile_data.actor_json,
|
||||
],
|
||||
).await.map_err(catch_unique_violation("profile"))?;
|
||||
|
@ -198,9 +201,10 @@ pub async fn update_profile(
|
|||
identity_proofs = $7,
|
||||
payment_options = $8,
|
||||
extra_fields = $9,
|
||||
actor_json = $10,
|
||||
aliases = $10,
|
||||
actor_json = $11,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $11
|
||||
WHERE id = $12
|
||||
RETURNING actor_profile
|
||||
",
|
||||
&[
|
||||
|
@ -213,6 +217,7 @@ pub async fn update_profile(
|
|||
&IdentityProofs(profile_data.identity_proofs),
|
||||
&PaymentOptions(profile_data.payment_options),
|
||||
&ExtraFields(profile_data.extra_fields),
|
||||
&Aliases::new(profile_data.aliases),
|
||||
&profile_data.actor_json,
|
||||
&profile_id,
|
||||
],
|
||||
|
|
|
@ -307,6 +307,32 @@ impl ExtraFields {
|
|||
json_from_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)]
|
||||
pub struct ProfileEmojis(Vec<DbEmoji>);
|
||||
|
||||
|
@ -337,6 +363,7 @@ pub struct DbActorProfile {
|
|||
pub identity_proofs: IdentityProofs,
|
||||
pub payment_options: PaymentOptions,
|
||||
pub extra_fields: ExtraFields,
|
||||
pub aliases: Aliases,
|
||||
pub follower_count: i32,
|
||||
pub following_count: i32,
|
||||
pub subscriber_count: i32,
|
||||
|
@ -426,6 +453,7 @@ impl Default for DbActorProfile {
|
|||
identity_proofs: IdentityProofs(vec![]),
|
||||
payment_options: PaymentOptions(vec![]),
|
||||
extra_fields: ExtraFields(vec![]),
|
||||
aliases: Aliases(vec![]),
|
||||
follower_count: 0,
|
||||
following_count: 0,
|
||||
subscriber_count: 0,
|
||||
|
@ -452,6 +480,7 @@ pub struct ProfileCreateData {
|
|||
pub identity_proofs: Vec<IdentityProof>,
|
||||
pub payment_options: Vec<PaymentOption>,
|
||||
pub extra_fields: Vec<ExtraField>,
|
||||
pub aliases: Vec<String>,
|
||||
pub emojis: Vec<Uuid>,
|
||||
pub actor_json: Option<Actor>,
|
||||
}
|
||||
|
@ -485,6 +514,7 @@ pub struct ProfileUpdateData {
|
|||
pub identity_proofs: Vec<IdentityProof>,
|
||||
pub payment_options: Vec<PaymentOption>,
|
||||
pub extra_fields: Vec<ExtraField>,
|
||||
pub aliases: Vec<String>,
|
||||
pub emojis: Vec<Uuid>,
|
||||
pub actor_json: Option<Actor>,
|
||||
}
|
||||
|
@ -534,6 +564,7 @@ impl From<&DbActorProfile> for ProfileUpdateData {
|
|||
identity_proofs: profile.identity_proofs.into_inner(),
|
||||
payment_options: profile.payment_options.into_inner(),
|
||||
extra_fields: profile.extra_fields.into_inner(),
|
||||
aliases: profile.aliases.into_actor_ids(),
|
||||
emojis: profile.emojis.into_inner().into_iter()
|
||||
.map(|emoji| emoji.id)
|
||||
.collect(),
|
||||
|
|
|
@ -118,6 +118,7 @@ pub async fn create_user(
|
|||
identity_proofs: vec![],
|
||||
payment_options: vec![],
|
||||
extra_fields: vec![],
|
||||
aliases: vec![],
|
||||
emojis: vec![],
|
||||
actor_json: None,
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue