main: try to get target from actor.object

https://github.com/astro/buzzrelay/issues/15
This commit is contained in:
Astro 2024-02-21 21:21:33 +01:00
parent 186d9f008e
commit d1a92f9f5e
2 changed files with 37 additions and 1 deletions

View file

@ -84,6 +84,28 @@ impl Actor {
Some(Actor { host, kind }) Some(Actor { host, kind })
} }
pub fn from_object(action: &activitypub::Action<serde_json::Value>) -> Option<Self> {
let action_object = action.object.as_ref()?;
let mut action_target: Option<String> = None;
if let Some(action_object) = action_object.as_str() {
action_target = Some(action_object.to_string());
}
if let Some(action_object_0) = action_object.as_array()
.and_then(|action_object| {
if action_object.len() == 1 {
action_object.first()
} else {
None
}
}).and_then(|action_object_0| action_object_0.as_str())
{
action_target = Some(action_object_0.to_string());
}
action_target.and_then(|action_target| Self::from_uri(&action_target))
}
pub fn uri(&self) -> String { pub fn uri(&self) -> String {
match &self.kind { match &self.kind {
ActorKind::TagRelay(tag) => ActorKind::TagRelay(tag) =>

View file

@ -148,7 +148,7 @@ async fn post_language_relay(
async fn post_relay( async fn post_relay(
state: State, state: State,
endpoint: endpoint::Endpoint<'_>, endpoint: endpoint::Endpoint<'_>,
target: actor::Actor mut target: actor::Actor
) -> Response { ) -> Response {
if let Some((redis, in_topic)) = &state.redis { if let Some((redis, in_topic)) = &state.redis {
if let Ok(data) = serde_json::to_vec(&endpoint.payload) { if let Ok(data) = serde_json::to_vec(&endpoint.payload) {
@ -188,6 +188,13 @@ async fn post_relay(
let Ok(remote_actor) = remote_actor else { let Ok(remote_actor) = remote_actor else {
return (StatusCode::BAD_REQUEST, "Invalid actor").into_response(); return (StatusCode::BAD_REQUEST, "Invalid actor").into_response();
}; };
if let Some(action_target) = Actor::from_object(&action) {
if action_target.host == state.hostname {
// A sharedInbox receives the actual follow target in the
// `object` field.
target = action_target;
}
}
let priv_key = state.priv_key.clone(); let priv_key = state.priv_key.clone();
let client = state.client.clone(); let client = state.client.clone();
tokio::spawn(async move { tokio::spawn(async move {
@ -243,6 +250,13 @@ async fn post_relay(
let Ok(remote_actor) = remote_actor else { let Ok(remote_actor) = remote_actor else {
return (StatusCode::BAD_REQUEST, "Invalid actor").into_response(); return (StatusCode::BAD_REQUEST, "Invalid actor").into_response();
}; };
if let Some(action_target) = Actor::from_object(&action) {
if action_target.host == state.hostname {
// A sharedInbox receives the actual follow target in the
// `object` field.
target = action_target;
}
}
match state.database.del_follow( match state.database.del_follow(
&remote_actor.id, &remote_actor.id,
&target.uri(), &target.uri(),