forked from grumpydevelop/federator
initial rough support for sending follow to CN
we now send follows to CN to the api/profile/profileName/fedfollow endpoint, either with a post, or a delete. - commit also contains files where line-endings suddenly changed to crlf (now it's back to lf). - targetRequestType (post/delete) now depends on the activity - we now also set the id to username when fetching a user from CN
This commit is contained in:
parent
097f871ed6
commit
2ae81a3748
3 changed files with 118 additions and 14 deletions
|
@ -194,6 +194,8 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
}
|
||||
}
|
||||
|
||||
$users = array_unique($users); // remove duplicates
|
||||
|
||||
if (empty($users)) { // todo remove after proper implementation, debugging for now
|
||||
$rootDir = PROJECT_ROOT . '/';
|
||||
// Save the raw input and parsed JSON to a file for inspection
|
||||
|
@ -229,15 +231,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$articleId = \Federator\DIO\Posts::getOriginalArticleId($dbh, $inboxActivity);
|
||||
if ($articleId !== null) {
|
||||
$connector->sendActivity($user, $inboxActivity);
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
error_log("Inbox::postForUser Error sending activity to connector. Exception: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
$connector->sendActivity($user, $inboxActivity);
|
||||
|
||||
return "success";
|
||||
}
|
||||
|
@ -334,7 +328,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
$cache
|
||||
);
|
||||
if ($recipient === null || $recipient->id === null) {
|
||||
error_log("Inbox::postForUser couldn't find user: $_recipientId");
|
||||
error_log("Inbox::postForUser couldn't find recipient: $_recipientId");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -194,6 +194,9 @@ class NewContent implements \Federator\Api\APIInterface
|
|||
$users[] = $user->id;
|
||||
}
|
||||
}
|
||||
|
||||
$users = array_unique($users); // remove duplicates
|
||||
|
||||
if (empty($users)) { // todo remove after proper implementation, debugging for now
|
||||
$rootDir = PROJECT_ROOT . '/';
|
||||
// Save the raw input and parsed JSON to a file for inspection
|
||||
|
|
|
@ -314,6 +314,7 @@ class ContentNation implements Connector
|
|||
}
|
||||
$user = new \Federator\Data\User();
|
||||
$user->externalid = $_name;
|
||||
$user->id = $_name;
|
||||
$user->iconMediaType = $r['iconMediaType'];
|
||||
$user->iconURL = $r['iconURL'];
|
||||
$user->imageMediaType = $r['imageMediaType'];
|
||||
|
@ -675,8 +676,9 @@ class ContentNation implements Connector
|
|||
public function sendActivity($sender, $activity)
|
||||
{
|
||||
$targetUrl = $this->service;
|
||||
$targetRequestType = 'post'; // Default request type
|
||||
// Convert ActivityPub activity to ContentNation JSON format and retrieve target url
|
||||
$jsonData = self::activityToJson($this->main->getDatabase(), $this->service, $activity, $targetUrl);
|
||||
$jsonData = self::activityToJson($this->main->getDatabase(), $this->service, $activity, $targetUrl, $targetRequestType);
|
||||
|
||||
if ($jsonData === false) {
|
||||
error_log("ContentNation::sendActivity failed to convert activity to JSON");
|
||||
|
@ -702,7 +704,7 @@ class ContentNation implements Connector
|
|||
$path = $parsed['path'];
|
||||
|
||||
// Build the signature string
|
||||
$signatureString = "(request-target): post {$path}\n" .
|
||||
$signatureString = "(request-target): $targetRequestType {$path}\n" .
|
||||
"host: {$extHost}\n" .
|
||||
"date: {$date}\n" .
|
||||
"digest: {$digest}";
|
||||
|
@ -740,7 +742,16 @@ class ContentNation implements Connector
|
|||
];
|
||||
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
switch ($targetRequestType) {
|
||||
case 'post':
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
break;
|
||||
case 'delete':
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
||||
break;
|
||||
default:
|
||||
throw new \Exception("ContentNation::sendActivity Unsupported target request type: $targetRequestType");
|
||||
}
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
$response = curl_exec($ch);
|
||||
|
@ -765,11 +776,13 @@ class ContentNation implements Connector
|
|||
* @param string $serviceUrl the service URL
|
||||
* @param \Federator\Data\ActivityPub\Common\Activity $activity the activity
|
||||
* @param string $targetUrl the target URL for the activity
|
||||
* @param string $targetRequestType the target request type (e.g., 'post', 'delete', etc.)
|
||||
* @return array<string, mixed>|false the json data or false on failure
|
||||
*/
|
||||
private static function activityToJson($dbh, $serviceUrl, \Federator\Data\ActivityPub\Common\Activity $activity, string &$targetUrl)
|
||||
private function activityToJson($dbh, $serviceUrl, \Federator\Data\ActivityPub\Common\Activity $activity, string &$targetUrl, string &$targetRequestType)
|
||||
{
|
||||
$type = strtolower($activity->getType());
|
||||
$targetRequestType = 'post'; // Default request type
|
||||
switch ($type) {
|
||||
case 'create':
|
||||
case 'update':
|
||||
|
@ -820,6 +833,50 @@ class ContentNation implements Connector
|
|||
}
|
||||
break;
|
||||
|
||||
case 'follow':
|
||||
$profileUrl = $activity->getObject();
|
||||
if (!is_string($profileUrl)) {
|
||||
error_log("ContentNation::activityToJson Invalid profile URL: " . json_encode($profileUrl));
|
||||
return false;
|
||||
}
|
||||
$receiverName = basename((string) (parse_url($profileUrl, PHP_URL_PATH) ?? ''));
|
||||
$ourDomain = parse_url($profileUrl, PHP_URL_HOST);
|
||||
if ($receiverName === "" || $ourDomain === "") {
|
||||
error_log("ContentNation::activityToJson no profileName or domain found for object url: " . $profileUrl);
|
||||
return false;
|
||||
}
|
||||
$receiver = $receiverName;
|
||||
try {
|
||||
$localUser = \Federator\DIO\User::getUserByName(
|
||||
$dbh,
|
||||
$receiver,
|
||||
$this,
|
||||
null
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
error_log("ContentNation::activityToJson get user by name: " . $receiver . ". Exception: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
if ($localUser === null || $localUser->id === null) {
|
||||
error_log("ContentNation::activityToJson couldn't find user: $receiver");
|
||||
return false;
|
||||
}
|
||||
$targetUrl = $serviceUrl . '/api/profile/' . $localUser->id . '/fedfollow';
|
||||
$type = 'follow';
|
||||
$actor = $activity->getAActor();
|
||||
$fedUser = \Federator\DIO\FedUser::getUserByName(
|
||||
$dbh,
|
||||
$actor,
|
||||
null
|
||||
);
|
||||
$from = $fedUser->id;
|
||||
return [
|
||||
'type' => $type,
|
||||
'id' => $activity->getID(),
|
||||
'from' => $from,
|
||||
'to' => $localUser->id,
|
||||
];
|
||||
|
||||
case 'like':
|
||||
case 'dislike':
|
||||
$articleId = \Federator\DIO\Posts::getOriginalArticleId($dbh, $activity);
|
||||
|
@ -859,6 +916,56 @@ class ContentNation implements Connector
|
|||
if (is_object($object)) {
|
||||
$objType = strtolower($object->getType());
|
||||
switch ($objType) {
|
||||
case 'follow':
|
||||
$profileUrl = $object->getObject();
|
||||
if (!is_string($profileUrl)) {
|
||||
error_log("ContentNation::activityToJson Invalid profile URL: " . json_encode($profileUrl));
|
||||
return false;
|
||||
}
|
||||
$receiverName = basename((string) (parse_url($profileUrl, PHP_URL_PATH) ?? ''));
|
||||
$ourDomain = parse_url($profileUrl, PHP_URL_HOST);
|
||||
if ($receiverName === "" || $ourDomain === "") {
|
||||
error_log("ContentNation::activityToJson no profileName or domain found for object url: " . $profileUrl);
|
||||
return false;
|
||||
}
|
||||
$receiver = $receiverName;
|
||||
try {
|
||||
$localUser = \Federator\DIO\User::getUserByName(
|
||||
$dbh,
|
||||
$receiver,
|
||||
$this,
|
||||
null
|
||||
);
|
||||
} catch (\Throwable $e) {
|
||||
error_log("ContentNation::activityToJson get user by name: " . $receiver . ". Exception: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
if ($localUser === null || $localUser->id === null) {
|
||||
error_log("ContentNation::activityToJson couldn't find user: $receiver");
|
||||
return false;
|
||||
}
|
||||
$targetUrl = $serviceUrl . '/api/profile/' . $localUser->id . '/fedfollow';
|
||||
$type = 'follow';
|
||||
if ($object instanceof \Federator\Data\ActivityPub\Common\Activity) {
|
||||
$actor = $object->getAActor();
|
||||
if ($actor !== '') {
|
||||
$fedUser = \Federator\DIO\FedUser::getUserByName(
|
||||
$dbh,
|
||||
$actor,
|
||||
null
|
||||
);
|
||||
$from = $fedUser->id;
|
||||
$targetRequestType = 'delete';
|
||||
return [
|
||||
'type' => $type,
|
||||
'id' => $object->getID(),
|
||||
'from' => $from,
|
||||
'to' => $localUser->id,
|
||||
];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
case 'like':
|
||||
case 'dislike':
|
||||
$articleId = \Federator\DIO\Posts::getOriginalArticleId($dbh, $activity);
|
||||
|
|
Loading…
Add table
Reference in a new issue