Make it work with Lemmy
This commit is contained in:
parent
6b3a4f8942
commit
29d040bcd3
6 changed files with 36 additions and 11 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -4,7 +4,7 @@ version = 3
|
|||
|
||||
[[package]]
|
||||
name = "activitypub_federation"
|
||||
version = "0.4.0-rc1"
|
||||
version = "0.4.0-rc2"
|
||||
dependencies = [
|
||||
"activitystreams-kinds",
|
||||
"actix-rt",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
error::Error,
|
||||
http_signatures::sign_request,
|
||||
reqwest_shim::ResponseExt,
|
||||
traits::ActivityHandler,
|
||||
traits::{ActivityHandler, Actor},
|
||||
APUB_JSON_CONTENT_TYPE,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
|
|
@ -40,9 +40,9 @@ use url::Url;
|
|||
/// signature. Generated with [crate::http_signatures::generate_actor_keypair].
|
||||
/// - `inboxes`: List of actor inboxes that should receive the activity. Should be built by calling
|
||||
/// [crate::traits::Actor::shared_inbox_or_inbox] for each target actor.
|
||||
pub async fn send_activity<Activity, Datatype>(
|
||||
pub async fn send_activity<Activity, Datatype, ActorType>(
|
||||
activity: Activity,
|
||||
private_key: String,
|
||||
actor: ActorType,
|
||||
inboxes: Vec<Url>,
|
||||
data: &RequestData<Datatype>,
|
||||
) -> Result<(), <Activity as ActivityHandler>::Error>
|
||||
|
|
@ -50,11 +50,14 @@ where
|
|||
Activity: ActivityHandler + Serialize,
|
||||
<Activity as ActivityHandler>::Error: From<anyhow::Error> + From<serde_json::Error>,
|
||||
Datatype: Clone,
|
||||
ActorType: Actor,
|
||||
for<'de2> ActorType::ApubType: Deserialize<'de2>,
|
||||
{
|
||||
let config = &data.config;
|
||||
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 inboxes: Vec<Url> = inboxes
|
||||
.into_iter()
|
||||
.unique()
|
||||
|
|
|
|||
|
|
@ -112,8 +112,8 @@ mod test {
|
|||
let request_builder =
|
||||
ClientWithMiddleware::from(Client::default()).post("https://example.com/inbox");
|
||||
let activity = Follow {
|
||||
actor: ObjectId::new("http://localhost:123").unwrap(),
|
||||
object: ObjectId::new("http://localhost:124").unwrap(),
|
||||
actor: ObjectId::parse("http://localhost:123").unwrap(),
|
||||
object: ObjectId::parse("http://localhost:124").unwrap(),
|
||||
kind: Default::default(),
|
||||
id: "http://localhost:123/1".try_into().unwrap(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,9 +5,21 @@ use serde::{Deserialize, Serialize};
|
|||
use std::{
|
||||
fmt::{Debug, Display, Formatter},
|
||||
marker::PhantomData,
|
||||
str::FromStr,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
impl<T> FromStr for ObjectId<T>
|
||||
where
|
||||
T: ApubObject + Send + 'static,
|
||||
for<'de2> <T as ApubObject>::ApubType: Deserialize<'de2>,
|
||||
{
|
||||
type Err = url::ParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
ObjectId::parse(s)
|
||||
}
|
||||
}
|
||||
/// Typed wrapper for Activitypub Object ID which helps with dereferencing and caching.
|
||||
///
|
||||
/// It provides convenient methods for fetching the object from remote server or local database.
|
||||
|
|
@ -32,7 +44,7 @@ use url::Url;
|
|||
/// .app_data(db_connection)
|
||||
/// .build()?;
|
||||
/// let request_data = config.to_request_data();
|
||||
/// let object_id = ObjectId::<DbUser>::new("https://lemmy.ml/u/nutomic")?;
|
||||
/// let object_id = ObjectId::<DbUser>::parse("https://lemmy.ml/u/nutomic")?;
|
||||
/// // Attempt to fetch object from local database or fall back to remote server
|
||||
/// let user = object_id.dereference(&request_data).await;
|
||||
/// assert!(user.is_ok());
|
||||
|
|
@ -55,7 +67,7 @@ where
|
|||
for<'de2> <Kind as ApubObject>::ApubType: serde::Deserialize<'de2>,
|
||||
{
|
||||
/// Construct a new objectid instance
|
||||
pub fn new<T>(url: T) -> Result<Self, url::ParseError>
|
||||
pub fn parse<T>(url: T) -> Result<Self, url::ParseError>
|
||||
where
|
||||
T: TryInto<Url>,
|
||||
url::ParseError: From<<T as TryInto<Url>>::Error>,
|
||||
|
|
@ -238,7 +250,7 @@ pub mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_deserialize() {
|
||||
let id = ObjectId::<DbUser>::new("http://test.com/").unwrap();
|
||||
let id = ObjectId::<DbUser>::parse("http://test.com/").unwrap();
|
||||
|
||||
let string = serde_json::to_string(&id).unwrap();
|
||||
assert_eq!("\"http://test.com/\"", string);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ impl PublicKey {
|
|||
/// Create a new [PublicKey] struct for the `owner` with `public_key_pem`.
|
||||
///
|
||||
/// It uses an standard key id of `{actor_id}#main-key`
|
||||
pub fn new(owner: Url, public_key_pem: String) -> Self {
|
||||
pub(crate) fn new(owner: Url, public_key_pem: String) -> Self {
|
||||
let id = main_key_id(&owner);
|
||||
PublicKey {
|
||||
id,
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ pub trait ActivityHandler {
|
|||
}
|
||||
|
||||
/// Trait to allow retrieving common Actor data.
|
||||
pub trait Actor: ApubObject {
|
||||
pub trait Actor: ApubObject + Send + 'static {
|
||||
/// `id` field of the actor
|
||||
fn id(&self) -> &Url;
|
||||
|
||||
|
|
@ -237,6 +237,12 @@ pub trait Actor: ApubObject {
|
|||
/// actor keypair.
|
||||
fn public_key_pem(&self) -> &str;
|
||||
|
||||
/// The actor's private key for signing outgoing activities.
|
||||
///
|
||||
/// Use [generate_actor_keypair](crate::http_signatures::generate_actor_keypair) to create the
|
||||
/// actor keypair.
|
||||
fn private_key_pem(&self) -> Option<String>;
|
||||
|
||||
/// The inbox where activities for this user should be sent to
|
||||
fn inbox(&self) -> Url;
|
||||
|
||||
|
|
@ -412,6 +418,10 @@ pub mod tests {
|
|||
&self.public_key
|
||||
}
|
||||
|
||||
fn private_key_pem(&self) -> Option<String> {
|
||||
self.private_key.clone()
|
||||
}
|
||||
|
||||
fn inbox(&self) -> Url {
|
||||
self.inbox.clone()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue