forked from alemi/upub
feat: add pubkey to actor
veeeeery crude impl, with hardcoded pubkey in faker cmd, but whatevs i want activitupub.academy to fetch meeee
This commit is contained in:
parent
fe36ed2a52
commit
de9c3498bc
7 changed files with 76 additions and 4 deletions
34
src/activitystream/key.rs
Normal file
34
src/activitystream/key.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// TODO technically this is not part of ActivityStreams
|
||||||
|
|
||||||
|
use crate::{getter, setter};
|
||||||
|
|
||||||
|
|
||||||
|
pub trait PublicKey : super::Base {
|
||||||
|
fn owner(&self) -> Option<&str> { None }
|
||||||
|
fn public_key_pem(&self) -> &str;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PublicKeyMut : super::BaseMut {
|
||||||
|
fn set_owner(self, val: Option<&str>) -> Self;
|
||||||
|
fn set_public_key_pem(self, val: &str) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PublicKey for serde_json::Value {
|
||||||
|
getter! { owner -> &str }
|
||||||
|
|
||||||
|
fn public_key_pem(&self) -> &str {
|
||||||
|
self.get("publicKeyPem").unwrap().as_str().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PublicKeyMut for serde_json::Value {
|
||||||
|
setter! { owner -> &str }
|
||||||
|
|
||||||
|
fn set_public_key_pem(mut self, val: &str) -> Self {
|
||||||
|
self.as_object_mut().unwrap().insert(
|
||||||
|
"publicKeyPem".to_string(),
|
||||||
|
serde_json::Value::String(val.to_string()),
|
||||||
|
);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ pub use node::Node;
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
||||||
|
pub mod key;
|
||||||
|
|
||||||
use crate::{getter, setter, strenum};
|
use crate::{getter, setter, strenum};
|
||||||
|
|
||||||
strenum! {
|
strenum! {
|
||||||
|
@ -30,6 +32,7 @@ pub trait Base {
|
||||||
fn underlying_json_object(self) -> serde_json::Value;
|
fn underlying_json_object(self) -> serde_json::Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn raw_object() -> serde_json::Value { serde_json::Value::Object(serde_json::Map::default()) }
|
||||||
pub fn object() -> serde_json::Value {
|
pub fn object() -> serde_json::Value {
|
||||||
let mut map = serde_json::Map::default();
|
let mut map = serde_json::Map::default();
|
||||||
map.insert(
|
map.insert(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{activitystream::Node, getter, setter, strenum};
|
use crate::{activitystream::Node, getter, setter, strenum};
|
||||||
|
|
||||||
use super::collection::Collection;
|
use super::collection::Collection;
|
||||||
|
use super::super::key::PublicKey;
|
||||||
|
|
||||||
strenum! {
|
strenum! {
|
||||||
pub enum ActorType {
|
pub enum ActorType {
|
||||||
|
@ -17,11 +18,12 @@ pub trait Actor : super::Object {
|
||||||
fn preferred_username(&self) -> Option<&str> { None }
|
fn preferred_username(&self) -> Option<&str> { None }
|
||||||
fn inbox(&self) -> Node<impl Collection>;
|
fn inbox(&self) -> Node<impl Collection>;
|
||||||
fn outbox(&self) -> Node<impl Collection>;
|
fn outbox(&self) -> Node<impl Collection>;
|
||||||
fn following(&self) -> Node<impl Collection> { Node::Empty::<serde_json::Value> }
|
fn following(&self) -> Node<impl Collection> { Node::empty() }
|
||||||
fn followers(&self) -> Node<impl Collection> { Node::Empty::<serde_json::Value> }
|
fn followers(&self) -> Node<impl Collection> { Node::empty() }
|
||||||
fn liked(&self) -> Node<impl Collection> { Node::Empty::<serde_json::Value> }
|
fn liked(&self) -> Node<impl Collection> { Node::empty() }
|
||||||
fn streams(&self) -> Node<impl Collection> { Node::Empty::<serde_json::Value> }
|
fn streams(&self) -> Node<impl Collection> { Node::empty() }
|
||||||
fn endpoints(&self) -> Option<serde_json::Map<String, String>> { None }
|
fn endpoints(&self) -> Option<serde_json::Map<String, String>> { None }
|
||||||
|
fn public_key(&self) -> Node<impl PublicKey> { Node::empty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ActorMut : super::ObjectMut {
|
pub trait ActorMut : super::ObjectMut {
|
||||||
|
@ -34,6 +36,7 @@ pub trait ActorMut : super::ObjectMut {
|
||||||
fn set_liked(self, val: Node<impl Collection>) -> Self;
|
fn set_liked(self, val: Node<impl Collection>) -> Self;
|
||||||
fn set_streams(self, val: Node<impl Collection>) -> Self;
|
fn set_streams(self, val: Node<impl Collection>) -> Self;
|
||||||
fn set_endpoints(self, val: Option<serde_json::Map<String, String>>) -> Self;
|
fn set_endpoints(self, val: Option<serde_json::Map<String, String>>) -> Self;
|
||||||
|
fn set_public_key(self, val: Node<impl PublicKey>) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Actor for serde_json::Value {
|
impl Actor for serde_json::Value {
|
||||||
|
@ -45,6 +48,7 @@ impl Actor for serde_json::Value {
|
||||||
getter! { followers -> node impl Collection }
|
getter! { followers -> node impl Collection }
|
||||||
getter! { liked -> node impl Collection }
|
getter! { liked -> node impl Collection }
|
||||||
getter! { streams -> node impl Collection }
|
getter! { streams -> node impl Collection }
|
||||||
|
getter! { public_key::publicKey -> node impl PublicKey }
|
||||||
|
|
||||||
fn endpoints(&self) -> Option<serde_json::Map<String, String>> {
|
fn endpoints(&self) -> Option<serde_json::Map<String, String>> {
|
||||||
todo!()
|
todo!()
|
||||||
|
@ -60,6 +64,7 @@ impl ActorMut for serde_json::Value {
|
||||||
setter! { followers -> node impl Collection }
|
setter! { followers -> node impl Collection }
|
||||||
setter! { liked -> node impl Collection }
|
setter! { liked -> node impl Collection }
|
||||||
setter! { streams -> node impl Collection }
|
setter! { streams -> node impl Collection }
|
||||||
|
setter! { public_key::publicKey -> node impl PublicKey }
|
||||||
|
|
||||||
fn set_endpoints(self, _val: Option<serde_json::Map<String, String>>) -> Self {
|
fn set_endpoints(self, _val: Option<serde_json::Map<String, String>>) -> Self {
|
||||||
todo!()
|
todo!()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pub use super::{
|
pub use super::{
|
||||||
Base as _, BaseMut as _,
|
Base as _, BaseMut as _,
|
||||||
|
key::{PublicKey as _, PublicKeyMut as _},
|
||||||
link::{Link as _, LinkMut as _},
|
link::{Link as _, LinkMut as _},
|
||||||
object::{
|
object::{
|
||||||
Object as _, ObjectMut as _,
|
Object as _, ObjectMut as _,
|
||||||
|
|
|
@ -29,6 +29,8 @@ impl MigrationTrait for Migration {
|
||||||
.col(ColumnDef::new(Users::Outbox).string().null())
|
.col(ColumnDef::new(Users::Outbox).string().null())
|
||||||
.col(ColumnDef::new(Users::Following).string().null())
|
.col(ColumnDef::new(Users::Following).string().null())
|
||||||
.col(ColumnDef::new(Users::Followers).string().null())
|
.col(ColumnDef::new(Users::Followers).string().null())
|
||||||
|
.col(ColumnDef::new(Users::PublicKey).string().not_null())
|
||||||
|
.col(ColumnDef::new(Users::PrivateKey).string().null())
|
||||||
.col(ColumnDef::new(Users::Created).date_time().not_null())
|
.col(ColumnDef::new(Users::Created).date_time().not_null())
|
||||||
.col(ColumnDef::new(Users::Updated).date_time().not_null())
|
.col(ColumnDef::new(Users::Updated).date_time().not_null())
|
||||||
.to_owned()
|
.to_owned()
|
||||||
|
@ -114,6 +116,8 @@ enum Users {
|
||||||
Outbox,
|
Outbox,
|
||||||
Following,
|
Following,
|
||||||
Followers,
|
Followers,
|
||||||
|
PublicKey,
|
||||||
|
PrivateKey,
|
||||||
Created,
|
Created,
|
||||||
Updated,
|
Updated,
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,17 @@ pub async fn faker(db: &sea_orm::DatabaseConnection, domain: String) -> Result<(
|
||||||
actor_type: super::activitystream::object::actor::ActorType::Person,
|
actor_type: super::activitystream::object::actor::ActorType::Person,
|
||||||
created: chrono::Utc::now(),
|
created: chrono::Utc::now(),
|
||||||
updated: chrono::Utc::now(),
|
updated: chrono::Utc::now(),
|
||||||
|
private_key: None,
|
||||||
|
// TODO generate a fresh one every time
|
||||||
|
public_key: "-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA01IkF1A8t7zUS7x3ZqIx
|
||||||
|
NvG/X43JEJTdgPOFufOKMBTK48uMqrODK3wflaK6cSOMWkoOYHyWNhw10vL53GR9
|
||||||
|
iOOGUHTaU7aoV7KBb5Fbh/tN9ZyN/S6FdCfpXze93CzpKQGNJa4SZ4FAFw2Ji1JJ
|
||||||
|
pdT7r+vaa5TkYTQuIgeHFisVEQAhmlz9xPbfPRPxSskroK7OnJSLMZ+aJvJHc9uX
|
||||||
|
kOq9wKgagV/I5ka7H3rRLTG1mBC97lrSfNdXfPRF//S4mFs095s+Pbnj0Hajf+qf
|
||||||
|
1Dryarmn6EmQi+diyhxFD3E8PWtMSBHrK+nmsiE58zjR/gd7G8SrXr4jtW+jcI6n
|
||||||
|
UQIDAQAB
|
||||||
|
-----END PUBLIC KEY-----".into()
|
||||||
};
|
};
|
||||||
|
|
||||||
user::Entity::insert(root.clone().into_active_model()).exec(db).await?;
|
user::Entity::insert(root.clone().into_active_model()).exec(db).await?;
|
||||||
|
|
|
@ -24,6 +24,9 @@ pub struct Model {
|
||||||
pub following: Option<String>,
|
pub following: Option<String>,
|
||||||
pub followers: Option<String>,
|
pub followers: Option<String>,
|
||||||
|
|
||||||
|
pub public_key: String,
|
||||||
|
pub private_key: Option<String>,
|
||||||
|
|
||||||
pub created: ChronoDateTimeUtc,
|
pub created: ChronoDateTimeUtc,
|
||||||
pub updated: ChronoDateTimeUtc,
|
pub updated: ChronoDateTimeUtc,
|
||||||
|
|
||||||
|
@ -79,6 +82,7 @@ impl crate::activitystream::Base for Model {
|
||||||
.set_outbox(self.outbox())
|
.set_outbox(self.outbox())
|
||||||
.set_following(self.following())
|
.set_following(self.following())
|
||||||
.set_followers(self.followers())
|
.set_followers(self.followers())
|
||||||
|
.set_public_key(self.public_key())
|
||||||
.underlying_json_object()
|
.underlying_json_object()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +139,14 @@ impl crate::activitystream::object::actor::Actor for Model {
|
||||||
fn followers(&self) -> Node<impl Collection> {
|
fn followers(&self) -> Node<impl Collection> {
|
||||||
Node::link(self.following.clone().unwrap_or(format!("https://{}/users/{}/followers", self.domain, self.name)))
|
Node::link(self.following.clone().unwrap_or(format!("https://{}/users/{}/followers", self.domain, self.name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn public_key(&self) -> Node<impl crate::activitystream::key::PublicKey> {
|
||||||
|
Node::object(
|
||||||
|
crate::activitystream::raw_object()
|
||||||
|
.set_public_key_pem(&self.public_key)
|
||||||
|
.set_owner(Some(&self.id))
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
|
@ -155,6 +167,8 @@ impl Model {
|
||||||
following: object.following().id().map(|x| x.to_string()),
|
following: object.following().id().map(|x| x.to_string()),
|
||||||
created: object.published().unwrap_or(chrono::Utc::now()),
|
created: object.published().unwrap_or(chrono::Utc::now()),
|
||||||
updated: chrono::Utc::now(),
|
updated: chrono::Utc::now(),
|
||||||
|
public_key: object.public_key().get().ok_or(super::FieldError("publicKey"))?.public_key_pem().to_string(),
|
||||||
|
private_key: None, // there's no way to transport privkey over AP json, must come from DB
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue