feat: node.fetch() is now signed

This commit is contained in:
əlemi 2024-04-13 22:13:36 +02:00
parent 96462648ce
commit c9a20b4e65
Signed by: alemi
GPG key ID: A4895B84D311642C
3 changed files with 35 additions and 8 deletions

View file

@ -32,7 +32,7 @@ tokio = { version = "1.35", features = ["full"] } # TODO slim this down
sea-orm = { version = "0.12", features = ["macros", "sqlx-sqlite", "runtime-tokio-rustls"] } sea-orm = { version = "0.12", features = ["macros", "sqlx-sqlite", "runtime-tokio-rustls"] }
reqwest = { version = "0.12", features = ["json"] } reqwest = { version = "0.12", features = ["json"] }
axum = "0.7" axum = "0.7"
apb = { path = "apb", features = ["unstructured", "fetch", "orm"] } apb = { path = "apb", features = ["unstructured", "orm"] }
# nodeinfo = "0.0.2" # the version on crates.io doesn't re-export necessary types to build the struct!!! # nodeinfo = "0.0.2" # the version on crates.io doesn't re-export necessary types to build the struct!!!
nodeinfo = { git = "https://codeberg.org/thefederationinfo/nodeinfo-rs", rev = "e865094804" } nodeinfo = { git = "https://codeberg.org/thefederationinfo/nodeinfo-rs", rev = "e865094804" }
# migrations # migrations

View file

@ -15,6 +15,8 @@ use sea_orm::{ConnectOptions, Database, EntityTrait, IntoActiveModel};
pub use errors::UpubResult as Result; pub use errors::UpubResult as Result;
use crate::server::fetcher::Fetchable;
pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Parser)] #[derive(Parser)]
@ -92,7 +94,7 @@ async fn main() {
CliCommand::Faker { count } => model::faker::faker(&db, args.domain, count) CliCommand::Faker { count } => model::faker::faker(&db, args.domain, count)
.await.expect("error creating fake entities"), .await.expect("error creating fake entities"),
CliCommand::Fetch { uri, save } => fetch(&db, &uri, save) CliCommand::Fetch { uri, save } => fetch(db, args.domain, uri, save)
.await.expect("error fetching object"), .await.expect("error fetching object"),
CliCommand::Serve => { CliCommand::Serve => {
@ -119,12 +121,15 @@ async fn main() {
} }
async fn fetch(db: &sea_orm::DatabaseConnection, uri: &str, save: bool) -> reqwest::Result<()> { async fn fetch(db: sea_orm::DatabaseConnection, domain: String, uri: String, save: bool) -> crate::Result<()> {
use apb::{Base, Object}; use apb::{Base, Object};
let mut node = apb::Node::from(uri); let ctx = server::Context::new(db, domain)
.await.expect("failed creating server context");
let mut node = apb::Node::link(uri.to_string());
tracing::info!("fetching object"); tracing::info!("fetching object");
node.fetch().await?; node.fetch(&ctx).await?;
tracing::info!("fetched node"); tracing::info!("fetched node");
let obj = node.get().expect("node still empty after fetch?"); let obj = node.get().expect("node still empty after fetch?");
@ -136,17 +141,17 @@ async fn fetch(db: &sea_orm::DatabaseConnection, uri: &str, save: bool) -> reqwe
Some(apb::BaseType::Object(apb::ObjectType::Actor(_))) => { Some(apb::BaseType::Object(apb::ObjectType::Actor(_))) => {
model::user::Entity::insert( model::user::Entity::insert(
model::user::Model::new(obj).unwrap().into_active_model() model::user::Model::new(obj).unwrap().into_active_model()
).exec(db).await.unwrap(); ).exec(ctx.db()).await.unwrap();
}, },
Some(apb::BaseType::Object(apb::ObjectType::Activity(_))) => { Some(apb::BaseType::Object(apb::ObjectType::Activity(_))) => {
model::activity::Entity::insert( model::activity::Entity::insert(
model::activity::Model::new(obj).unwrap().into_active_model() model::activity::Model::new(obj).unwrap().into_active_model()
).exec(db).await.unwrap(); ).exec(ctx.db()).await.unwrap();
}, },
Some(apb::BaseType::Object(apb::ObjectType::Note)) => { Some(apb::BaseType::Object(apb::ObjectType::Note)) => {
model::object::Entity::insert( model::object::Entity::insert(
model::object::Model::new(obj).unwrap().into_active_model() model::object::Model::new(obj).unwrap().into_active_model()
).exec(db).await.unwrap(); ).exec(ctx.db()).await.unwrap();
}, },
Some(apb::BaseType::Object(t)) => tracing::warn!("not implemented: {:?}", t), Some(apb::BaseType::Object(t)) => tracing::warn!("not implemented: {:?}", t),
Some(apb::BaseType::Link(_)) => tracing::error!("fetched another link?"), Some(apb::BaseType::Link(_)) => tracing::error!("fetched another link?"),

View file

@ -122,3 +122,25 @@ impl Fetcher {
Ok(object_model) Ok(object_model)
} }
} }
#[axum::async_trait]
pub trait Fetchable : Sync + Send {
async fn fetch(&mut self, ctx: &crate::server::Context) -> crate::Result<&mut Self>;
}
#[axum::async_trait]
impl Fetchable for apb::Node<serde_json::Value> {
async fn fetch(&mut self, ctx: &crate::server::Context) -> crate::Result<&mut Self> {
if let apb::Node::Link(uri) = self {
let from = format!("{}{}", ctx.protocol(), ctx.base()); // TODO helper to avoid this?
let pkey = &ctx.app().private_key;
*self = Fetcher::request(Method::GET, uri.href(), None, &from, pkey, ctx.base())
.await?
.json::<serde_json::Value>()
.await?
.into();
}
Ok(self)
}
}