almost everything working
This commit is contained in:
parent
b83640ae60
commit
471f113dbe
4 changed files with 57 additions and 31 deletions
|
|
@ -56,7 +56,9 @@ where
|
|||
let actor_id = activity.actor();
|
||||
let activity_id = activity.id();
|
||||
let activity_serialized = serde_json::to_string_pretty(&activity)?;
|
||||
let private_key = actor.private_key_pem().unwrap();
|
||||
let private_key = actor
|
||||
.private_key_pem()
|
||||
.expect("Actor for sending activity has private key");
|
||||
let inboxes: Vec<Url> = inboxes
|
||||
.into_iter()
|
||||
.unique()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{error::Error, traits::ApubCollection};
|
||||
use crate::{config::Data, error::Error, fetch::fetch_object_http, traits::ApubCollection};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
fmt::{Debug, Display, Formatter},
|
||||
|
|
@ -6,16 +6,19 @@ use std::{
|
|||
};
|
||||
use url::Url;
|
||||
|
||||
/// TODO: implement and document this, update trait docs
|
||||
/// TODO: which handlers need to receive owner, and should it be simply an url or what?
|
||||
/// TODO: current trait impl without read_from_apub_id() method wont work for http handlers
|
||||
/// -> maybe remove method into_apub() and instead add read_local() (reads from db and
|
||||
/// directly returns serialized collection)
|
||||
/// Typed wrapper for Activitypub Collection ID which helps with dereferencing.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct CollectionId<Kind>(Box<Url>, PhantomData<Kind>);
|
||||
pub struct CollectionId<Kind>(Box<Url>, PhantomData<Kind>)
|
||||
where
|
||||
Kind: ApubCollection,
|
||||
for<'de2> <Kind as ApubCollection>::ApubType: Deserialize<'de2>;
|
||||
|
||||
impl<Kind> CollectionId<Kind> {
|
||||
impl<Kind> CollectionId<Kind>
|
||||
where
|
||||
Kind: ApubCollection,
|
||||
for<'de2> <Kind as ApubCollection>::ApubType: Deserialize<'de2>,
|
||||
{
|
||||
/// Construct a new CollectionId instance
|
||||
pub fn parse<T>(url: T) -> Result<Self, url::ParseError>
|
||||
where
|
||||
|
|
@ -25,14 +28,30 @@ impl<Kind> CollectionId<Kind> {
|
|||
Ok(Self(Box::new(url.try_into()?), PhantomData::<Kind>))
|
||||
}
|
||||
|
||||
/// TODO
|
||||
pub async fn dereference<T>(&self, _: T) -> Result<Kind, Error> {
|
||||
todo!()
|
||||
/// Fetches collection over HTTP
|
||||
///
|
||||
/// Unlike [ObjectId::fetch](crate::fetch::object_id::ObjectId::fetch) this method doesn't do
|
||||
/// any caching.
|
||||
pub async fn dereference(
|
||||
&self,
|
||||
owner: &<Kind as ApubCollection>::Owner,
|
||||
data: &Data<<Kind as ApubCollection>::DataType>,
|
||||
) -> Result<Kind, <Kind as ApubCollection>::Error>
|
||||
where
|
||||
<Kind as ApubCollection>::Error: From<Error>,
|
||||
{
|
||||
let apub = fetch_object_http(&self.0, data).await?;
|
||||
Kind::verify(&apub, &self.0, data).await?;
|
||||
Kind::from_apub(apub, owner, data).await
|
||||
}
|
||||
}
|
||||
|
||||
/// Need to implement clone manually, to avoid requiring Kind to be Clone
|
||||
impl<Kind> Clone for CollectionId<Kind> {
|
||||
impl<Kind> Clone for CollectionId<Kind>
|
||||
where
|
||||
Kind: ApubCollection,
|
||||
for<'de2> <Kind as ApubCollection>::ApubType: serde::Deserialize<'de2>,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
CollectionId(self.0.clone(), self.1)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,3 +79,15 @@ where
|
|||
self.inner.receive(data).await
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for WithContext<T>
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
context: self.context.clone(),
|
||||
inner: self.inner.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
use crate::{config::Data, protocol::public_key::PublicKey};
|
||||
use async_trait::async_trait;
|
||||
use chrono::NaiveDateTime;
|
||||
use serde::Deserialize;
|
||||
use std::{fmt::Debug, ops::Deref};
|
||||
use url::Url;
|
||||
|
||||
|
|
@ -151,8 +152,8 @@ pub trait ApubObject: Sized {
|
|||
/// Convert object from ActivityPub type to database type.
|
||||
///
|
||||
/// Called when an object is received from HTTP fetch or as part of an activity. This method
|
||||
/// should do verification and write the received object to database. Note that there is no
|
||||
/// distinction between create and update, so an `upsert` operation should be used.
|
||||
/// should write the received object to database. Note that there is no distinction between
|
||||
/// create and update, so an `upsert` operation should be used.
|
||||
async fn from_apub(
|
||||
apub: Self::ApubType,
|
||||
data: &Data<Self::DataType>,
|
||||
|
|
@ -252,7 +253,7 @@ pub trait Actor: ApubObject + Send + 'static {
|
|||
|
||||
/// Generates a public key struct for use in the actor json representation
|
||||
fn public_key(&self) -> PublicKey {
|
||||
PublicKey::new(self.id().clone(), self.public_key_pem().to_string())
|
||||
PublicKey::new(self.id(), self.public_key_pem().to_string())
|
||||
}
|
||||
|
||||
/// The actor's shared inbox, if any
|
||||
|
|
@ -301,17 +302,13 @@ pub trait ApubCollection: Sized {
|
|||
/// [crate::config::FederationConfigBuilder::app_data] type.
|
||||
type DataType: Clone + Send + Sync;
|
||||
/// The type of protocol struct which gets sent over network to federate this database struct.
|
||||
type ApubType;
|
||||
type ApubType: for<'de2> Deserialize<'de2>;
|
||||
/// Error type returned by handler methods
|
||||
type Error;
|
||||
|
||||
/// Convert database type to Activitypub type.
|
||||
///
|
||||
/// Called when a local object gets fetched by another instance over HTTP, or when an object
|
||||
/// gets sent in an activity.
|
||||
async fn into_apub(
|
||||
self,
|
||||
owner: Self::Owner,
|
||||
/// Reads local collection from database and returns it as Activitypub JSON.
|
||||
async fn read_local(
|
||||
owner: &Self::Owner,
|
||||
data: &Data<Self::DataType>,
|
||||
) -> Result<Self::ApubType, Self::Error>;
|
||||
|
||||
|
|
@ -319,12 +316,8 @@ pub trait ApubCollection: Sized {
|
|||
///
|
||||
/// You should check here that the domain of id matches `expected_domain`. Additionally you
|
||||
/// should perform any application specific checks.
|
||||
///
|
||||
/// It is necessary to use a separate method for this, because it might be used for activities
|
||||
/// like `Delete/Note`, which shouldn't perform any database write for the inner `Note`.
|
||||
async fn verify(
|
||||
apub: &Self::ApubType,
|
||||
owner: Self::Owner,
|
||||
expected_domain: &Url,
|
||||
data: &Data<Self::DataType>,
|
||||
) -> Result<(), Self::Error>;
|
||||
|
|
@ -332,11 +325,11 @@ pub trait ApubCollection: Sized {
|
|||
/// Convert object from ActivityPub type to database type.
|
||||
///
|
||||
/// Called when an object is received from HTTP fetch or as part of an activity. This method
|
||||
/// should do verification and write the received object to database. Note that there is no
|
||||
/// distinction between create and update, so an `upsert` operation should be used.
|
||||
/// should also write the received object to database. Note that there is no distinction
|
||||
/// between create and update, so an `upsert` operation should be used.
|
||||
async fn from_apub(
|
||||
apub: Self::ApubType,
|
||||
owner: Self::Owner,
|
||||
owner: &Self::Owner,
|
||||
data: &Data<Self::DataType>,
|
||||
) -> Result<Self, Self::Error>;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue