summaryrefslogtreecommitdiffstats
path: root/src/entity
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2025-07-15 08:42:19 +0200
committerrtkay123 <dev@kanjala.com>2025-07-15 08:42:19 +0200
commita69c24e561c8ae16dc730f7713f8d8da0bd25e0e (patch)
tree32878bf97b1adf2da14c8e3da7265c8937b89650 /src/entity
parenta64eb6b08f2f8d22cf129fba39e1bb2c66bb3fad (diff)
downloadsellershut-a69c24e561c8ae16dc730f7713f8d8da0bd25e0e.tar.bz2
sellershut-a69c24e561c8ae16dc730f7713f8d8da0bd25e0e.zip
feat: persist with sqlx
Diffstat (limited to 'src/entity')
-rw-r--r--src/entity/user.rs64
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(),
})
}