it compiles!

This commit is contained in:
Felix Ableitner 2021-06-23 19:35:00 +02:00
parent a619a0d52a
commit d24f274cb7
5 changed files with 86 additions and 68 deletions

View File

@ -1,67 +1,78 @@
use url::Url; use crate::{
use crate::inbox::new_inbox_routing::{ReceiveActivity, Activity, verify_domains_match}; activities::receive::verify_activity_domains_valid,
use activitystreams::activity::kind::FollowType; inbox::new_inbox_routing::{verify_domains_match, Activity, ReceiveActivity},
use activitystreams::activity::kind::AcceptType; };
use crate::activities::receive::verify_activity_domains_valid; use activitystreams::{
use activitystreams::base::ExtendsExt; activity::kind::{AcceptType, FollowType},
base::ExtendsExt,
};
use anyhow::Context; use anyhow::Context;
use lemmy_apub::fetcher::community::get_or_fetch_and_upsert_community;
use lemmy_api_common::blocking; use lemmy_api_common::blocking;
use lemmy_db_schema::source::community::CommunityFollower; use lemmy_apub::fetcher::{
use lemmy_websocket::LemmyContext; community::get_or_fetch_and_upsert_community,
use lemmy_utils::LemmyError; person::get_or_fetch_and_upsert_person,
use lemmy_utils::location_info; };
use lemmy_db_queries::Followable; use lemmy_db_queries::Followable;
use lemmy_apub::fetcher::person::get_or_fetch_and_upsert_person; use lemmy_db_schema::source::community::CommunityFollower;
use lemmy_utils::{location_info, LemmyError};
use lemmy_websocket::LemmyContext;
use url::Url;
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Follow { pub struct Follow {
// todo: implement newtypes PersonUrl, GroupUrl etc (with deref function) // todo: implement newtypes PersonUrl, GroupUrl etc (with deref function)
actor: Url, actor: Url,
to: Url, to: Url,
object: Url, object: Url,
#[serde(rename = "type")] #[serde(rename = "type")]
kind: FollowType, kind: FollowType,
} }
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl ReceiveActivity for Follow { impl ReceiveActivity for Activity<Follow> {
type Kind = FollowType; async fn receive(
async fn receive(&self,activity: Activity<Self::Kind>, context: &LemmyContext, request_counter: &mut i32) -> Result<(), LemmyError> { &self,
println!("receive follow"); context: &LemmyContext,
todo!() request_counter: &mut i32,
} ) -> Result<(), LemmyError> {
println!("receive follow");
todo!()
}
} }
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Accept { pub struct Accept {
// todo: implement newtypes PersonUrl, GroupUrl etc (with deref function) // todo: implement newtypes PersonUrl, GroupUrl etc (with deref function)
actor: Url, actor: Url,
to: Url, to: Url,
object: Activity<Follow>, object: Activity<Follow>,
#[serde(rename = "type")] #[serde(rename = "type")]
kind: AcceptType, kind: AcceptType,
} }
/// Handle accepted follows /// Handle accepted follows
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl ReceiveActivity for Accept { impl ReceiveActivity for Activity<Accept> {
type Kind = AcceptType; async fn receive(
async fn receive(&self, activity: Activity<Self::Kind>, context: &LemmyContext, request_counter: &mut i32) -> Result<(), LemmyError> { &self,
verify_domains_match(&self.actor, &activity.id_unchecked())?; context: &LemmyContext,
verify_domains_match(&self.object.inner.actor, &self.object.id_unchecked())?; request_counter: &mut i32,
) -> Result<(), LemmyError> {
verify_domains_match(&self.inner.actor, self.id_unchecked())?;
let follow = &self.inner.object;
verify_domains_match(&follow.inner.actor, &follow.id_unchecked())?;
let community = let community =
get_or_fetch_and_upsert_community(&self.actor, context, request_counter).await?; get_or_fetch_and_upsert_community(&self.inner.actor, context, request_counter).await?;
let person = get_or_fetch_and_upsert_person(&self.to, context, request_counter).await?; let person = get_or_fetch_and_upsert_person(&self.inner.to, context, request_counter).await?;
// This will throw an error if no follow was requested // This will throw an error if no follow was requested
blocking(&context.pool(), move |conn| { blocking(&context.pool(), move |conn| {
CommunityFollower::follow_accepted(conn, community.id, person.id) CommunityFollower::follow_accepted(conn, community.id, person.id)
}) })
.await??; .await??;
Ok(()) Ok(())
} }
} }

View File

@ -1,12 +1,14 @@
use activitystreams::base::{AnyBase};
use lemmy_utils::{LemmyError};
use lemmy_websocket::LemmyContext;
use activitystreams::unparsed::Unparsed;
use activitystreams::primitives::{OneOrMany};
use url::Url;
use crate::activities_new::follow::Accept; use crate::activities_new::follow::Accept;
use activitystreams::{
base::AnyBase,
error::DomainError,
primitives::OneOrMany,
unparsed::Unparsed,
};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use std::marker::PhantomData; use std::marker::PhantomData;
use activitystreams::error::DomainError; use url::Url;
// for now, limit it to activity routing only, no http sigs, parsing or any of that // for now, limit it to activity routing only, no http sigs, parsing or any of that
// need to route in this order: // need to route in this order:
@ -43,17 +45,21 @@ pub fn verify_domains_match(a: &Url, b: &Url) -> Result<(), LemmyError> {
// todo: maybe add a separate method verify() // todo: maybe add a separate method verify()
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
pub trait ReceiveActivity { pub trait ReceiveActivity {
type Kind;
// todo: would be nice if we didnt have to pass Activity and Self separately
// todo: later handle request_counter completely inside library // todo: later handle request_counter completely inside library
async fn receive(&self, activity: Activity<Self::Kind>, context: &LemmyContext, request_counter: &mut i32) -> Result<(), LemmyError>; async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError>;
} }
// todo: instead of phantomdata, might use option<kind> to cache the fetched object (or just fetch on construction) // todo: instead of phantomdata, might use option<kind> to cache the fetched object (or just fetch on construction)
pub struct ObjectId<'a, Kind>(Url, &'a PhantomData<Kind>); pub struct ObjectId<'a, Kind>(Url, &'a PhantomData<Kind>);
impl<Kind> ObjectId<'_, Kind> { impl<Kind> ObjectId<'_, Kind> {
pub fn url(self) -> Url {self.0} pub fn url(self) -> Url {
self.0
}
pub fn dereference(self) -> Result<Kind, LemmyError> { pub fn dereference(self) -> Result<Kind, LemmyError> {
// todo: fetch object from http or database // todo: fetch object from http or database
todo!() todo!()
@ -92,11 +98,13 @@ pub enum PersonAcceptedActivitiesNew {
// todo: there should be a better way to do this (maybe needs a derive macro) // todo: there should be a better way to do this (maybe needs a derive macro)
#[async_trait::async_trait(?Send)] #[async_trait::async_trait(?Send)]
impl ReceiveActivity<Kind> for PersonAcceptedActivitiesNew { impl ReceiveActivity for PersonAcceptedActivitiesNew {
async fn receive(&self, activity: Activity<Kind>, context: &LemmyContext, request_counter: &mut i32) -> Result<(), LemmyError> { async fn receive(
&self,
context: &LemmyContext,
request_counter: &mut i32,
) -> Result<(), LemmyError> {
use PersonAcceptedActivitiesNew::*; use PersonAcceptedActivitiesNew::*;
match self { self.receive(context, request_counter).await
Accept(a) => a.receive(activity, context, request_counter)
}.await
} }
} }

View File

@ -23,6 +23,7 @@ use crate::{
is_activity_already_known, is_activity_already_known,
is_addressed_to_community_followers, is_addressed_to_community_followers,
is_addressed_to_local_person, is_addressed_to_local_person,
new_inbox_routing::{Activity, PersonAcceptedActivitiesNew, ReceiveActivity},
receive_for_community::{ receive_for_community::{
receive_add_for_community, receive_add_for_community,
receive_block_user_for_community, receive_block_user_for_community,
@ -66,7 +67,6 @@ use serde::{Deserialize, Serialize};
use std::fmt::Debug; use std::fmt::Debug;
use strum_macros::EnumString; use strum_macros::EnumString;
use url::Url; use url::Url;
use crate::inbox::new_inbox_routing::{PersonAcceptedActivitiesNew, ReceiveActivity, Activity};
/// Allowed activities for person inbox. /// Allowed activities for person inbox.
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)] #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
@ -154,8 +154,7 @@ pub(crate) async fn person_receive_message(
let kind = activity.kind().context(location_info!())?; let kind = activity.kind().context(location_info!())?;
let actor_url = actor.actor_id(); let actor_url = actor.actor_id();
match kind { match kind {
PersonValidTypes::Accept => { PersonValidTypes::Accept => {}
}
PersonValidTypes::Announce => { PersonValidTypes::Announce => {
Box::pin(receive_announce(&context, any_base, actor, request_counter)).await? Box::pin(receive_announce(&context, any_base, actor, request_counter)).await?
} }

View File

@ -1,5 +1,5 @@
mod activities; mod activities;
pub mod activities_new;
mod http; mod http;
mod inbox; mod inbox;
pub mod routes; pub mod routes;
pub mod activities_new;