diff options
author | rtkay123 <dev@kanjala.com> | 2025-07-15 08:42:19 +0200 |
---|---|---|
committer | rtkay123 <dev@kanjala.com> | 2025-07-15 08:42:19 +0200 |
commit | a69c24e561c8ae16dc730f7713f8d8da0bd25e0e (patch) | |
tree | 32878bf97b1adf2da14c8e3da7265c8937b89650 /src/entity/user.rs | |
parent | a64eb6b08f2f8d22cf129fba39e1bb2c66bb3fad (diff) | |
download | sellershut-a69c24e561c8ae16dc730f7713f8d8da0bd25e0e.tar.bz2 sellershut-a69c24e561c8ae16dc730f7713f8d8da0bd25e0e.zip |
feat: persist with sqlx
Diffstat (limited to 'src/entity/user.rs')
-rw-r--r-- | src/entity/user.rs | 64 |
1 files changed, 54 insertions, 10 deletions
diff --git a/src/entity/user.rs b/src/entity/user.rs index e136cb3..da22f00 100644 --- a/src/entity/user.rs +++ b/src/entity/user.rs @@ -8,36 +8,77 @@ use activitypub_federation::{ }; use async_trait::async_trait; use serde::{Deserialize, Serialize}; +use stack_up::Services; use tracing::trace; use url::Url; +use uuid::Uuid; use crate::{error::AppError, state::AppHandle}; #[derive(PartialEq, Clone, Debug)] pub(crate) struct User { + pub id: String, pub username: String, pub ap_id: ObjectId<User>, pub private_key: Option<String>, pub public_key: String, pub inbox: Url, + pub outbox: Option<Url>, } -impl User { - pub fn new(username: &str) -> Result<Self, AppError> { - trace!("creating a new user"); - let keys = generate_actor_keypair()?; - let stub = &format!("http://localhost/users/{username}"); +pub struct DbUser { + pub id: String, + pub username: String, + pub ap_id: String, + pub private_key: Option<String>, + pub public_key: String, + pub inbox: String, + pub outbox: Option<String>, + pub local: bool, +} +impl TryFrom<DbUser> for User { + type Error = AppError; + fn try_from(value: DbUser) -> Result<Self, Self::Error> { Ok(Self { - username: username.to_owned(), - ap_id: Url::parse(stub)?.into(), - private_key: Some(keys.private_key), - public_key: keys.public_key, - inbox: Url::parse(&format!("{stub}/inbox"))?, + id: value.id, + username: value.username, + ap_id: Url::parse(&value.ap_id)?.into(), + private_key: value.private_key, + public_key: value.public_key, + inbox: Url::parse(&value.inbox)?, + outbox: match value.outbox { + Some(ref url) => Some(Url::parse(url)?), + None => None, + }, }) } } +impl User { + pub async fn new(username: &str, services: &Services) -> Result<Self, AppError> { + trace!("creating keypair for new user"); + let keys = generate_actor_keypair()?; + let stub = &format!("http://localhost/users/{username}"); + let id = Uuid::now_v7(); + + trace!(id = ?id, "creating a new user"); + let user = sqlx::query_as!( + DbUser, + "insert into account (id, username, ap_id, private_key, public_key, inbox, outbox, local) values ($1, $2, $3, $4, $5, $6, $7, $8) returning *", + id, + username, + stub, + keys.private_key, + keys.public_key, + &format!("{stub}/inbox"), + &format!("{stub}/outbox"), + true + ).fetch_one(&services.postgres).await?; + Self::try_from(user) + } +} + #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct Person { @@ -47,6 +88,8 @@ pub struct Person { id: ObjectId<User>, inbox: Url, public_key: PublicKey, + #[serde(skip_serializing_if = "Option::is_none")] + outbox: Option<Url>, } #[async_trait] @@ -85,6 +128,7 @@ impl Object for User { id: self.ap_id.clone(), inbox: self.inbox.clone(), public_key: self.public_key(), + outbox: self.outbox.clone(), }) } |