Add verify methods back in, some more fixes (#28)
This commit is contained in:
parent
8f2b9634b6
commit
6b3a4f8942
17 changed files with 164 additions and 18 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -4,7 +4,7 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "activitypub_federation"
|
name = "activitypub_federation"
|
||||||
version = "0.3.4"
|
version = "0.4.0-rc1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitystreams-kinds",
|
"activitystreams-kinds",
|
||||||
"actix-rt",
|
"actix-rt",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "activitypub_federation"
|
name = "activitypub_federation"
|
||||||
version = "0.4.0-rc1"
|
version = "0.4.0-rc2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "High-level Activitypub framework"
|
description = "High-level Activitypub framework"
|
||||||
keywords = ["activitypub", "activitystreams", "federation", "fediverse"]
|
keywords = ["activitypub", "activitystreams", "federation", "fediverse"]
|
||||||
|
|
|
@ -36,6 +36,10 @@ impl ActivityHandler for Follow {
|
||||||
fn actor(&self) -> &Url {
|
fn actor(&self) -> &Url {
|
||||||
self.actor.inner()
|
self.actor.inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(&self, _data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
let actor = self.actor.dereference(data).await?;
|
let actor = self.actor.dereference(data).await?;
|
||||||
|
|
|
@ -44,6 +44,10 @@ impl ApubObject for SearchableDbObjects {
|
||||||
) -> Result<Self::ApubType, Self::Error> {
|
) -> Result<Self::ApubType, Self::Error> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(apub: &Self::ApubType, expected_domain: &Url, _data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
apub: Self::ApubType,
|
apub: Self::ApubType,
|
||||||
|
|
|
@ -65,6 +65,11 @@ impl ActivityHandler for CreatePost {
|
||||||
self.actor.inner()
|
self.actor.inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(&self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
DbPost::verify(&self.object, &self.id, data).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
DbPost::from_apub(self.object, data).await?;
|
DbPost::from_apub(self.object, data).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -4,7 +4,7 @@ use activitypub_federation::{
|
||||||
fetch::object_id::ObjectId,
|
fetch::object_id::ObjectId,
|
||||||
http_signatures::generate_actor_keypair,
|
http_signatures::generate_actor_keypair,
|
||||||
kinds::actor::PersonType,
|
kinds::actor::PersonType,
|
||||||
protocol::public_key::PublicKey,
|
protocol::{public_key::PublicKey, verification::verify_domains_match},
|
||||||
traits::{ActivityHandler, Actor, ApubObject},
|
traits::{ActivityHandler, Actor, ApubObject},
|
||||||
};
|
};
|
||||||
use chrono::{Local, NaiveDateTime};
|
use chrono::{Local, NaiveDateTime};
|
||||||
|
@ -99,6 +99,15 @@ impl ApubObject for DbUser {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(
|
||||||
|
apub: &Self::ApubType,
|
||||||
|
expected_domain: &Url,
|
||||||
|
_data: &RequestData<Self::DataType>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
verify_domains_match(apub.id.inner(), expected_domain)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
apub: Self::ApubType,
|
apub: Self::ApubType,
|
||||||
_data: &RequestData<Self::DataType>,
|
_data: &RequestData<Self::DataType>,
|
||||||
|
@ -117,11 +126,15 @@ impl ApubObject for DbUser {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Actor for DbUser {
|
impl Actor for DbUser {
|
||||||
fn public_key(&self) -> &str {
|
fn public_key_pem(&self) -> &str {
|
||||||
&self.public_key
|
&self.public_key
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inbox(&self) -> Url {
|
fn inbox(&self) -> Url {
|
||||||
self.inbox.clone()
|
self.inbox.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn id(&self) -> &Url {
|
||||||
|
self.ap_id.inner()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use activitypub_federation::{
|
||||||
config::RequestData,
|
config::RequestData,
|
||||||
fetch::object_id::ObjectId,
|
fetch::object_id::ObjectId,
|
||||||
kinds::{object::NoteType, public},
|
kinds::{object::NoteType, public},
|
||||||
protocol::helpers::deserialize_one_or_many,
|
protocol::{helpers::deserialize_one_or_many, verification::verify_domains_match},
|
||||||
traits::{Actor, ApubObject},
|
traits::{Actor, ApubObject},
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::link::MentionType;
|
use activitystreams_kinds::link::MentionType;
|
||||||
|
@ -65,6 +65,15 @@ impl ApubObject for DbPost {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(
|
||||||
|
apub: &Self::ApubType,
|
||||||
|
expected_domain: &Url,
|
||||||
|
_data: &RequestData<Self::DataType>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
verify_domains_match(apub.id.inner(), expected_domain)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
apub: Self::ApubType,
|
apub: Self::ApubType,
|
||||||
data: &RequestData<Self::DataType>,
|
data: &RequestData<Self::DataType>,
|
||||||
|
|
|
@ -42,6 +42,10 @@ impl ActivityHandler for Accept {
|
||||||
self.actor.inner()
|
self.actor.inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(&self, _data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn receive(self, _data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
async fn receive(self, _data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,11 @@ impl ActivityHandler for CreatePost {
|
||||||
self.actor.inner()
|
self.actor.inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(&self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
DbPost::verify(&self.object, &self.id, data).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
DbPost::from_apub(self.object, data).await?;
|
DbPost::from_apub(self.object, data).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -47,6 +47,10 @@ impl ActivityHandler for Follow {
|
||||||
self.actor.inner()
|
self.actor.inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(&self, _data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore clippy false positive: https://github.com/rust-lang/rust-clippy/issues/6446
|
// Ignore clippy false positive: https://github.com/rust-lang/rust-clippy/issues/6446
|
||||||
#[allow(clippy::await_holding_lock)]
|
#[allow(clippy::await_holding_lock)]
|
||||||
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use activitypub_federation::{
|
||||||
fetch::{object_id::ObjectId, webfinger::webfinger_resolve_actor},
|
fetch::{object_id::ObjectId, webfinger::webfinger_resolve_actor},
|
||||||
http_signatures::generate_actor_keypair,
|
http_signatures::generate_actor_keypair,
|
||||||
kinds::actor::PersonType,
|
kinds::actor::PersonType,
|
||||||
protocol::{context::WithContext, public_key::PublicKey},
|
protocol::{context::WithContext, public_key::PublicKey, verification::verify_domains_match},
|
||||||
traits::{ActivityHandler, Actor, ApubObject},
|
traits::{ActivityHandler, Actor, ApubObject},
|
||||||
};
|
};
|
||||||
use chrono::{Local, NaiveDateTime};
|
use chrono::{Local, NaiveDateTime};
|
||||||
|
@ -171,6 +171,15 @@ impl ApubObject for DbUser {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(
|
||||||
|
apub: &Self::ApubType,
|
||||||
|
expected_domain: &Url,
|
||||||
|
_data: &RequestData<Self::DataType>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
verify_domains_match(apub.id.inner(), expected_domain)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
apub: Self::ApubType,
|
apub: Self::ApubType,
|
||||||
data: &RequestData<Self::DataType>,
|
data: &RequestData<Self::DataType>,
|
||||||
|
@ -192,7 +201,11 @@ impl ApubObject for DbUser {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Actor for DbUser {
|
impl Actor for DbUser {
|
||||||
fn public_key(&self) -> &str {
|
fn id(&self) -> &Url {
|
||||||
|
self.ap_id.inner()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn public_key_pem(&self) -> &str {
|
||||||
&self.public_key
|
&self.public_key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use activitypub_federation::{
|
||||||
config::RequestData,
|
config::RequestData,
|
||||||
fetch::object_id::ObjectId,
|
fetch::object_id::ObjectId,
|
||||||
kinds::{object::NoteType, public},
|
kinds::{object::NoteType, public},
|
||||||
protocol::helpers::deserialize_one_or_many,
|
protocol::{helpers::deserialize_one_or_many, verification::verify_domains_match},
|
||||||
traits::ApubObject,
|
traits::ApubObject,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -73,6 +73,15 @@ impl ApubObject for DbPost {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(
|
||||||
|
apub: &Self::ApubType,
|
||||||
|
expected_domain: &Url,
|
||||||
|
_data: &RequestData<Self::DataType>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
verify_domains_match(apub.id.inner(), expected_domain)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
apub: Self::ApubType,
|
apub: Self::ApubType,
|
||||||
data: &RequestData<Self::DataType>,
|
data: &RequestData<Self::DataType>,
|
||||||
|
|
|
@ -42,10 +42,11 @@ where
|
||||||
request.headers(),
|
request.headers(),
|
||||||
request.method(),
|
request.method(),
|
||||||
request.uri(),
|
request.uri(),
|
||||||
actor.public_key(),
|
actor.public_key_pem(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
debug!("Receiving activity {}", activity.id().to_string());
|
debug!("Receiving activity {}", activity.id().to_string());
|
||||||
|
activity.verify(data).await?;
|
||||||
activity.receive(data).await?;
|
activity.receive(data).await?;
|
||||||
Ok(HttpResponse::Ok().finish())
|
Ok(HttpResponse::Ok().finish())
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,15 +44,15 @@ where
|
||||||
.dereference(data)
|
.dereference(data)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// TODO: why do errors here not get returned over http?
|
|
||||||
verify_signature(
|
verify_signature(
|
||||||
&activity_data.headers,
|
&activity_data.headers,
|
||||||
&activity_data.method,
|
&activity_data.method,
|
||||||
&activity_data.uri,
|
&activity_data.uri,
|
||||||
actor.public_key(),
|
actor.public_key_pem(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
debug!("Receiving activity {}", activity.id().to_string());
|
debug!("Receiving activity {}", activity.id().to_string());
|
||||||
|
activity.verify(data).await?;
|
||||||
activity.receive(data).await?;
|
activity.receive(data).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,7 @@ where
|
||||||
|
|
||||||
let res2 = res?;
|
let res2 = res?;
|
||||||
|
|
||||||
|
Kind::verify(&res2, self.inner(), data).await?;
|
||||||
Kind::from_apub(res2, data).await
|
Kind::from_apub(res2, data).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl<T> WithContext<T> {
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl<T> ActivityHandler for WithContext<T>
|
impl<T> ActivityHandler for WithContext<T>
|
||||||
where
|
where
|
||||||
T: ActivityHandler + Send,
|
T: ActivityHandler + Send + Sync,
|
||||||
{
|
{
|
||||||
type DataType = <T as ActivityHandler>::DataType;
|
type DataType = <T as ActivityHandler>::DataType;
|
||||||
type Error = <T as ActivityHandler>::Error;
|
type Error = <T as ActivityHandler>::Error;
|
||||||
|
@ -75,6 +75,10 @@ where
|
||||||
self.inner.actor()
|
self.inner.actor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(&self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
self.inner.verify(data).await
|
||||||
|
}
|
||||||
|
|
||||||
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
self.inner.receive(data).await
|
self.inner.receive(data).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Traits which need to be implemented for federated data types
|
//! Traits which need to be implemented for federated data types
|
||||||
|
|
||||||
use crate::config::RequestData;
|
use crate::{config::RequestData, protocol::public_key::PublicKey};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -13,6 +13,7 @@ use url::Url;
|
||||||
/// # use url::Url;
|
/// # use url::Url;
|
||||||
/// # use activitypub_federation::protocol::public_key::PublicKey;
|
/// # use activitypub_federation::protocol::public_key::PublicKey;
|
||||||
/// # use activitypub_federation::config::RequestData;
|
/// # use activitypub_federation::config::RequestData;
|
||||||
|
/// use activitypub_federation::protocol::verification::verify_domains_match;
|
||||||
/// # use activitypub_federation::traits::ApubObject;
|
/// # use activitypub_federation::traits::ApubObject;
|
||||||
/// # use activitypub_federation::traits::tests::{DbConnection, Person};
|
/// # use activitypub_federation::traits::tests::{DbConnection, Person};
|
||||||
/// # pub struct DbUser {
|
/// # pub struct DbUser {
|
||||||
|
@ -53,7 +54,13 @@ use url::Url;
|
||||||
/// })
|
/// })
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// async fn from_apub(apub: Self::ApubType, data: &RequestData<Self::DataType>) -> Result<Self, Self::Error> {
|
/// async fn verify(apub: &Self::ApubType, expected_domain: &Url, data: &RequestData<Self::DataType>,) -> Result<(), Self::Error> {
|
||||||
|
/// verify_domains_match(apub.id.inner(), expected_domain)?;
|
||||||
|
/// // additional application specific checks
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// async fn from_apub(apub: Self::ApubType, data: &RequestData<Self::DataType>) -> Result<Self, Self::Error> {
|
||||||
/// // Called when a remote object gets received over Activitypub. Validate and insert it
|
/// // Called when a remote object gets received over Activitypub. Validate and insert it
|
||||||
/// // into the database.
|
/// // into the database.
|
||||||
///
|
///
|
||||||
|
@ -124,6 +131,19 @@ pub trait ApubObject: Sized {
|
||||||
data: &RequestData<Self::DataType>,
|
data: &RequestData<Self::DataType>,
|
||||||
) -> Result<Self::ApubType, Self::Error>;
|
) -> Result<Self::ApubType, Self::Error>;
|
||||||
|
|
||||||
|
/// Verifies that the received object is valid.
|
||||||
|
///
|
||||||
|
/// 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,
|
||||||
|
expected_domain: &Url,
|
||||||
|
data: &RequestData<Self::DataType>,
|
||||||
|
) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
/// Convert object from ActivityPub type to database type.
|
/// 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
|
/// Called when an object is received from HTTP fetch or as part of an activity. This method
|
||||||
|
@ -166,6 +186,10 @@ pub trait ApubObject: Sized {
|
||||||
/// self.actor.inner()
|
/// self.actor.inner()
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
|
/// async fn verify(&self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
///
|
||||||
/// async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
/// async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
/// let local_user = self.object.dereference(data).await?;
|
/// let local_user = self.object.dereference(data).await?;
|
||||||
/// let follower = self.actor.dereference(data).await?;
|
/// let follower = self.actor.dereference(data).await?;
|
||||||
|
@ -189,6 +213,12 @@ pub trait ActivityHandler {
|
||||||
/// `actor` field of activity
|
/// `actor` field of activity
|
||||||
fn actor(&self) -> &Url;
|
fn actor(&self) -> &Url;
|
||||||
|
|
||||||
|
/// Verifies that the received activity is valid.
|
||||||
|
///
|
||||||
|
/// This needs to be a separate method, because it might be used for activities
|
||||||
|
/// like `Undo/Follow`, which shouldn't perform any database write for the inner `Follow`.
|
||||||
|
async fn verify(&self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error>;
|
||||||
|
|
||||||
/// Called when an activity is received.
|
/// Called when an activity is received.
|
||||||
///
|
///
|
||||||
/// Should perform validation and possibly write action to the database. In case the activity
|
/// Should perform validation and possibly write action to the database. In case the activity
|
||||||
|
@ -198,12 +228,23 @@ pub trait ActivityHandler {
|
||||||
|
|
||||||
/// Trait to allow retrieving common Actor data.
|
/// Trait to allow retrieving common Actor data.
|
||||||
pub trait Actor: ApubObject {
|
pub trait Actor: ApubObject {
|
||||||
|
/// `id` field of the actor
|
||||||
|
fn id(&self) -> &Url;
|
||||||
|
|
||||||
/// The actor's public key for verifying signatures of incoming activities.
|
/// The actor's public key for verifying signatures of incoming activities.
|
||||||
fn public_key(&self) -> &str;
|
///
|
||||||
|
/// Use [generate_actor_keypair](crate::http_signatures::generate_actor_keypair) to create the
|
||||||
|
/// actor keypair.
|
||||||
|
fn public_key_pem(&self) -> &str;
|
||||||
|
|
||||||
/// The inbox where activities for this user should be sent to
|
/// The inbox where activities for this user should be sent to
|
||||||
fn inbox(&self) -> Url;
|
fn inbox(&self) -> Url;
|
||||||
|
|
||||||
|
/// 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())
|
||||||
|
}
|
||||||
|
|
||||||
/// The actor's shared inbox, if any
|
/// The actor's shared inbox, if any
|
||||||
fn shared_inbox(&self) -> Option<Url> {
|
fn shared_inbox(&self) -> Option<Url> {
|
||||||
None
|
None
|
||||||
|
@ -219,7 +260,7 @@ pub trait Actor: ApubObject {
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T> ActivityHandler for Box<T>
|
impl<T> ActivityHandler for Box<T>
|
||||||
where
|
where
|
||||||
T: ActivityHandler + Send,
|
T: ActivityHandler + Send + Sync,
|
||||||
{
|
{
|
||||||
type DataType = T::DataType;
|
type DataType = T::DataType;
|
||||||
type Error = T::Error;
|
type Error = T::Error;
|
||||||
|
@ -232,6 +273,10 @@ where
|
||||||
self.deref().actor()
|
self.deref().actor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(&self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
(*self).verify(data).await
|
||||||
|
}
|
||||||
|
|
||||||
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
async fn receive(self, data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
(*self).receive(data).await
|
(*self).receive(data).await
|
||||||
}
|
}
|
||||||
|
@ -247,7 +292,7 @@ pub mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
fetch::object_id::ObjectId,
|
fetch::object_id::ObjectId,
|
||||||
http_signatures::{generate_actor_keypair, Keypair},
|
http_signatures::{generate_actor_keypair, Keypair},
|
||||||
protocol::public_key::PublicKey,
|
protocol::{public_key::PublicKey, verification::verify_domains_match},
|
||||||
};
|
};
|
||||||
use activitystreams_kinds::{activity::FollowType, actor::PersonType};
|
use activitystreams_kinds::{activity::FollowType, actor::PersonType};
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
|
@ -333,6 +378,15 @@ pub mod tests {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(
|
||||||
|
apub: &Self::ApubType,
|
||||||
|
expected_domain: &Url,
|
||||||
|
_data: &RequestData<Self::DataType>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
verify_domains_match(apub.id.inner(), expected_domain)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
apub: Self::ApubType,
|
apub: Self::ApubType,
|
||||||
_data: &RequestData<Self::DataType>,
|
_data: &RequestData<Self::DataType>,
|
||||||
|
@ -350,7 +404,11 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Actor for DbUser {
|
impl Actor for DbUser {
|
||||||
fn public_key(&self) -> &str {
|
fn id(&self) -> &Url {
|
||||||
|
&self.apub_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn public_key_pem(&self) -> &str {
|
||||||
&self.public_key
|
&self.public_key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,6 +440,10 @@ pub mod tests {
|
||||||
self.actor.inner()
|
self.actor.inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(&self, _: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn receive(self, _data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
async fn receive(self, _data: &RequestData<Self::DataType>) -> Result<(), Self::Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -413,6 +475,14 @@ pub mod tests {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn verify(
|
||||||
|
_: &Self::ApubType,
|
||||||
|
_: &Url,
|
||||||
|
_: &RequestData<Self::DataType>,
|
||||||
|
) -> Result<(), Self::Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
async fn from_apub(
|
async fn from_apub(
|
||||||
_: Self::ApubType,
|
_: Self::ApubType,
|
||||||
_: &RequestData<Self::DataType>,
|
_: &RequestData<Self::DataType>,
|
||||||
|
|
Loading…
Reference in a new issue