Better logic for ignoring spurious posts

merge-requests/5/head
Terence Eden 2024-03-14 22:08:16 +00:00
rodzic 37368caf72
commit ccdcca3dae
1 zmienionych plików z 96 dodań i 80 usunięć

166
index.php
Wyświetl plik

@ -247,97 +247,113 @@
// Get the message, type, and ID // Get the message, type, and ID
$inbox_message = $body; $inbox_message = $body;
$inbox_type = $inbox_message["type"]; $inbox_type = $inbox_message["type"];
$inbox_id = $inbox_message["id"];
// If this is an Undo, Delete, or Update message, try to process it // This inbox only sends responses to follow requests.
if ( "Undo" == $inbox_type || "Delete" == $inbox_type || "Update" == $inbox_type ) { // A remote server sends the inbox a follow request which is a JSON file saying who they are.
undo( $inbox_message ); // The details of the remote user's server is saved to a file so that future messages can be delivered to the follower.
die(); // An accept request is cryptographically signed and POST'd back to the remote server.
} if ( "Follow" == $inbox_type ) {
// Validate HTTP Message Signature
if ( !verifyHTTPSignature() ) { die(); }
// Messages to ignore. // Get the parameters
// Some servers are very chatty. They send lots of irrelevant messages. $follower_id = $inbox_message["id"]; // E.g. https://mastodon.social/(unique id)
// Before even bothering to validate them, we can delete them. $follower_actor = $inbox_message["actor"]; // E.g. https://mastodon.social/users/Edent
// Messages from accounts which aren't being followed. // Get the actor's profile as JSON
// Some servers send delete messages about users we don't follow. $follower_actor_details = getDataFromURl( $follower_actor );
// Lemmy sends messages even after unfollowing or blocking a channel
// Get a list of every account we follow // Save the actor's data in `/data/followers/`
// Get all the files $follower_filename = urlencode( $follower_actor );
$following_files = glob( $directories["following"] . "/*.json"); file_put_contents( $directories["followers"] . "/{$follower_filename}.json", json_encode( $follower_actor_details ) );
// Create a list of all accounts being followed // Get the new follower's Inbox
$following_ids = array(); $follower_inbox = $follower_actor_details["inbox"];
foreach ( $following_files as $following_file ) {
$following = json_decode( file_get_contents( $following_file ), true );
$following_ids[] = $following["id"];
}
// Is this from someone we follow? // Response Message ID
in_array( $inbox_message["actor"], $following_ids ) ? $from_following = true: $from_following = false; // This isn't used for anything important so could just be a random number
$guid = uuid();
// Has the user has been specifically CC'd? // Create the Accept message to the new follower
if ( isset( $inbox_message["cc"] ) ) { $message = [
$reply = in_array( "https://{$server}/{$username}", $inbox_message["cc"] ); "@context" => "https://www.w3.org/ns/activitystreams",
"id" => "https://{$server}/{$guid}",
"type" => "Accept",
"actor" => "https://{$server}/{$username}",
"object" => [
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => $follower_id,
"type" => $inbox_type,
"actor" => $follower_actor,
"object" => "https://{$server}/{$username}",
]
];
// The Accept is POSTed to the inbox on the server of the user who requested the follow
sendMessageToSingle( $follower_inbox, $message );
} else { } else {
$reply = false; // Messages to ignore.
} // Some servers are very chatty. They send lots of irrelevant messages.
// Before even bothering to validate them, we can delete them.
if ( !$reply && !$from_following ) { // Messages from accounts which aren't being followed.
// Don't bother processing it at all. // Some servers send delete messages about users we don't follow.
die(); // Lemmy sends messages even after unfollowing or blocking a channel
}
// Validate HTTP Message Signature // Get a list of every account we follow
if ( !verifyHTTPSignature() ) { die(); } // Get all the files
$following_files = glob( $directories["following"] . "/*.json");
// Create a list of all accounts being followed
$following_ids = array();
foreach ( $following_files as $following_file ) {
$following = json_decode( file_get_contents( $following_file ), true );
$following_ids[] = $following["id"];
}
// Is this from someone we follow?
in_array( $inbox_message["actor"], $following_ids ) ? $from_following = true: $from_following = false;
// Get a list of every account following us
// Get all the files
$followers_files = glob( $directories["followers"] . "/*.json");
// Create a list of all accounts being followed
$followers_ids = array();
foreach ( $followers_files as $follower_file ) {
$follower = json_decode( file_get_contents( $follower_file ), true );
$followers_ids[] = $follower["id"];
}
// Is this from someone following us?
in_array( $inbox_message["actor"], $followers_ids ) ? $from_follower = true: $from_follower = false;
// Has the user has been specifically CC'd?
if ( isset( $inbox_message["cc"] ) ) {
$reply = in_array( "https://{$server}/{$username}", $inbox_message["cc"] );
} else {
$reply = false;
}
if ( !$reply && !$from_following && !$from_follower ) {
// Don't bother processing it at all.
die();
}
// If this is an Undo, Delete, or Update message, try to process it
if ( "Undo" == $inbox_type || "Delete" == $inbox_type || "Update" == $inbox_type ) {
undo( $inbox_message );
}
// Validate HTTP Message Signature
if ( !verifyHTTPSignature() ) { die(); }
}
// If the message is valid, save the message in `/data/inbox/` // If the message is valid, save the message in `/data/inbox/`
$uuid = uuid( $inbox_message ); $uuid = uuid( $inbox_message );
$inbox_filename = $uuid . "." . urlencode( $inbox_type ) . ".json"; $inbox_filename = $uuid . "." . urlencode( $inbox_type ) . ".json";
file_put_contents( $directories["inbox"] . "/{$inbox_filename}", json_encode( $inbox_message ) ); file_put_contents( $directories["inbox"] . "/{$inbox_filename}", json_encode( $inbox_message ) );
// This inbox only sends responses to follow requests.
// A remote server sends the inbox a follow request which is a JSON file saying who they are.
// The details of the remote user's server is saved to a file so that future messages can be delivered to the follower.
// An accept request is cryptographically signed and POST'd back to the remote server.
if ( "Follow" != $inbox_type ) { die(); }
// Get the parameters
$follower_id = $inbox_message["id"]; // E.g. https://mastodon.social/(unique id)
$follower_actor = $inbox_message["actor"]; // E.g. https://mastodon.social/users/Edent
// Get the actor's profile as JSON
$follower_actor_details = getDataFromURl( $follower_actor );
// Save the actor's data in `/data/followers/`
$follower_filename = urlencode( $follower_actor );
file_put_contents( $directories["followers"] . "/{$follower_filename}.json", json_encode( $follower_actor_details ) );
// Get the new follower's Inbox
$follower_inbox = $follower_actor_details["inbox"];
// Response Message ID
// This isn't used for anything important so could just be a random number
$guid = uuid();
// Create the Accept message to the new follower
$message = [
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => "https://{$server}/{$guid}",
"type" => "Accept",
"actor" => "https://{$server}/{$username}",
"object" => [
"@context" => "https://www.w3.org/ns/activitystreams",
"id" => $follower_id,
"type" => $inbox_type,
"actor" => $follower_actor,
"object" => "https://{$server}/{$username}",
]
];
// The Accept is POSTed to the inbox on the server of the user who requested the follow
sendMessageToSingle( $follower_inbox, $message );
die(); die();
} }