forked from grumpydevelop/federator
fix phan errors
fix lots of phan errors, now we only have phan errors left from temporary implementations. These will be fixed in the next commits as we properly re-integrate and remove temporary-code
This commit is contained in:
parent
957b4f5266
commit
d9b02bd95b
9 changed files with 232 additions and 114 deletions
|
@ -367,5 +367,7 @@ return [
|
|||
// A list of individual files to include in analysis
|
||||
// with a path relative to the root directory of the
|
||||
// project.
|
||||
'file_list' => [],
|
||||
'file_list' => [
|
||||
'phan-stubs.php',
|
||||
],
|
||||
];
|
||||
|
|
10
phan-stubs.php
Normal file
10
phan-stubs.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
if (!function_exists('getallheaders')) {
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
function getallheaders(): array {
|
||||
return [];
|
||||
}
|
||||
}
|
|
@ -198,12 +198,13 @@ class Api extends Main
|
|||
* @param string[] $headers
|
||||
* permission(s) to check for
|
||||
* @throws Exceptions\PermissionDenied
|
||||
* @return string|Exceptions\PermissionDenied
|
||||
*/
|
||||
public function checkSignature($headers)
|
||||
public static function checkSignature($headers)
|
||||
{
|
||||
$signatureHeader = $headers['Signature'] ?? null;
|
||||
|
||||
if (!$signatureHeader) {
|
||||
if (!isset($signatureHeader)) {
|
||||
http_response_code(400);
|
||||
throw new Exceptions\PermissionDenied("Missing Signature header");
|
||||
}
|
||||
|
@ -219,15 +220,20 @@ class Api extends Main
|
|||
// Fetch public key from `keyId` (usually actor URL + #main-key)
|
||||
[$publicKeyData, $info] = \Federator\Main::getFromRemote($keyId, ['Accept: application/activity+json']);
|
||||
|
||||
if ($info['http_code'] !== 200) {
|
||||
if ($info['http_code'] != 200) {
|
||||
http_response_code(500);
|
||||
throw new Exceptions\PermissionDenied("Failed to fetch public key from keyId: $keyId");
|
||||
}
|
||||
|
||||
$actor = json_decode($publicKeyData, true);
|
||||
|
||||
if (!is_array($actor) || !isset($actor['id'])) {
|
||||
throw new Exceptions\PermissionDenied("Invalid actor data");
|
||||
}
|
||||
|
||||
$publicKeyPem = $actor['publicKey']['publicKeyPem'] ?? null;
|
||||
|
||||
if (!$publicKeyPem) {
|
||||
if (!isset($publicKeyPem)) {
|
||||
http_response_code(500);
|
||||
throw new Exceptions\PermissionDenied("Invalid public key format from actor with keyId: $keyId");
|
||||
}
|
||||
|
@ -235,8 +241,6 @@ class Api extends Main
|
|||
// Reconstruct the signed string
|
||||
$signedString = '';
|
||||
foreach ($signedHeaders as $header) {
|
||||
$headerValue = '';
|
||||
|
||||
if ($header === '(request-target)') {
|
||||
$method = strtolower($_SERVER['REQUEST_METHOD']);
|
||||
$path = $_SERVER['REQUEST_URI'];
|
||||
|
@ -252,16 +256,17 @@ class Api extends Main
|
|||
// Verify the signature
|
||||
$pubkeyRes = openssl_pkey_get_public($publicKeyPem);
|
||||
$verified = false;
|
||||
if ($pubkeyRes) {
|
||||
if ($pubkeyRes instanceof \OpenSSLAsymmetricKey && is_string($signature)) {
|
||||
$verified = openssl_verify($signedString, $signature, $pubkeyRes, OPENSSL_ALGO_SHA256);
|
||||
}
|
||||
if ($verified !== 1) {
|
||||
if ($verified != 1) {
|
||||
http_response_code(500);
|
||||
throw new Exceptions\PermissionDenied("Signature verification failed for publicKey with keyId: $keyId");
|
||||
}
|
||||
|
||||
$actorId = $actor['id'];
|
||||
// Signature is valid!
|
||||
return "Signature verified from actor: " . $actor['id'];
|
||||
return "Signature verified from actor: " . $actorId;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,7 +16,7 @@ class FedUsers implements APIInterface
|
|||
/**
|
||||
* main instance
|
||||
*
|
||||
* @var \Federator\Main $main
|
||||
* @var \Federator\Api $main
|
||||
*/
|
||||
private $main;
|
||||
|
||||
|
@ -49,6 +49,7 @@ class FedUsers implements APIInterface
|
|||
{
|
||||
$method = $_SERVER["REQUEST_METHOD"];
|
||||
$handler = null;
|
||||
$username = '';
|
||||
switch (sizeof($paths)) {
|
||||
case 2:
|
||||
if ($method === 'GET') {
|
||||
|
@ -75,8 +76,8 @@ class FedUsers implements APIInterface
|
|||
break;
|
||||
case 'inbox':
|
||||
$handler = new FedUsers\Inbox($this->main);
|
||||
$user = $paths[1];
|
||||
if (!preg_match("#^([^@]+)@([^/]+)#", $user, $matches) === 1) {
|
||||
$username = $paths[1];
|
||||
if (preg_match("#^([^@]+)@([^/]+)#", $username, $matches) != 1) {
|
||||
$hostUrl = $this->main->getHost();
|
||||
if ($hostUrl !== false) {
|
||||
$host = parse_url($hostUrl, PHP_URL_HOST);
|
||||
|
@ -84,14 +85,14 @@ class FedUsers implements APIInterface
|
|||
if ($port !== null) {
|
||||
$host .= `:$port`;
|
||||
}
|
||||
$user = `$user@$host`;
|
||||
$username = `$username@$host`;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'outbox':
|
||||
$handler = new FedUsers\Outbox($this->main);
|
||||
$user = $paths[1];
|
||||
if (!preg_match("#^([^@]+)@([^/]+)#", $user, $matches) === 1) {
|
||||
$username = $paths[1];
|
||||
if (preg_match("#^([^@]+)@([^/]+)#", $username, $matches) != 1) {
|
||||
$hostUrl = $this->main->getHost();
|
||||
if ($hostUrl !== false) {
|
||||
$host = parse_url($hostUrl, PHP_URL_HOST);
|
||||
|
@ -99,7 +100,7 @@ class FedUsers implements APIInterface
|
|||
if ($port !== null) {
|
||||
$host .= `:$port`;
|
||||
}
|
||||
$user = `$user@$host`;
|
||||
$username = `$username@$host`;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -114,10 +115,10 @@ class FedUsers implements APIInterface
|
|||
$ret = false;
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
$ret = $handler->get($user);
|
||||
$ret = $handler->get($username);
|
||||
break;
|
||||
case 'POST':
|
||||
$ret = $handler->post($user);
|
||||
$ret = $handler->post($username);
|
||||
break;
|
||||
}
|
||||
if ($ret !== false) {
|
||||
|
|
|
@ -16,7 +16,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
/**
|
||||
* main instance
|
||||
*
|
||||
* @var \Federator\Main $main
|
||||
* @var \Federator\Api $main
|
||||
*/
|
||||
private $main;
|
||||
|
||||
|
@ -32,7 +32,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
/**
|
||||
* handle get call
|
||||
*
|
||||
* @param string $_user user to fetch inbox for @unused-param
|
||||
* @param string|null $_user user to fetch inbox for @unused-param
|
||||
* @return string|false response
|
||||
*/
|
||||
public function get($_user)
|
||||
|
@ -43,7 +43,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
/**
|
||||
* handle post call
|
||||
*
|
||||
* @param string $_user user to add data to inbox
|
||||
* @param string|null $_user user to add data to inbox
|
||||
* @return string|false response
|
||||
*/
|
||||
public function post($_user)
|
||||
|
@ -60,10 +60,12 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
exit("Access denied");
|
||||
}
|
||||
|
||||
$activity = json_decode($_rawInput, true);
|
||||
$activity = is_string($_rawInput) ? json_decode($_rawInput, true) : null;
|
||||
$host = $_SERVER['SERVER_NAME'];
|
||||
|
||||
$sendTo = [];
|
||||
if (!is_array($activity)) {
|
||||
throw new \RuntimeException('Invalid activity format.');
|
||||
}
|
||||
|
||||
switch ($activity['type']) {
|
||||
case 'Create':
|
||||
|
@ -72,11 +74,12 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
}
|
||||
|
||||
$obj = $activity['object'];
|
||||
$published = strtotime($activity['published'] ?? $obj['published'] ?? 'now');
|
||||
$create = new \Federator\Data\ActivityPub\Common\Create();
|
||||
$create->setID($activity['id'])
|
||||
$create->setAActor($activity['actor'])
|
||||
->setID($activity['id'])
|
||||
->setURL($activity['id'])
|
||||
->setPublished(strtotime($activity['published'] ?? $obj['published'] ?? 'now'))
|
||||
->setAActor($activity['actor']);
|
||||
->setPublished($published !== false ? $published : time());
|
||||
|
||||
if (array_key_exists('cc', $activity)) {
|
||||
foreach ($activity['cc'] as $cc) {
|
||||
|
@ -92,9 +95,10 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
|
||||
switch ($obj['type']) {
|
||||
case 'Note':
|
||||
$published = strtotime($obj['published'] ?? 'now');
|
||||
$apNote = new \Federator\Data\ActivityPub\Common\Note();
|
||||
$apNote->setID($obj['id'])
|
||||
->setPublished(strtotime($obj['published'] ?? 'now'))
|
||||
->setPublished($published !== false ? $published : time())
|
||||
->setContent($obj['content'] ?? '')
|
||||
->setSummary($obj['summary'])
|
||||
->setURL($obj['url'])
|
||||
|
@ -168,11 +172,12 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
break;
|
||||
}
|
||||
|
||||
$published = strtotime((string) $activity['published']);
|
||||
$announce = new \Federator\Data\ActivityPub\Common\Announce();
|
||||
$announce->setID($activity['id'])
|
||||
->setURL($activity['id'])
|
||||
->setPublished(strtotime($activity['published'] ?? 'now'))
|
||||
->setAActor($activity['actor']);
|
||||
$announce->setAActor((string) $activity['actor'])
|
||||
->setPublished($published !== false ? $published : time())
|
||||
->setID((string) $activity['id'])
|
||||
->setURL((string) $activity['id']);
|
||||
|
||||
if (array_key_exists('cc', $activity)) {
|
||||
foreach ($activity['cc'] as $cc) {
|
||||
|
@ -188,11 +193,12 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
// Parse the shared object as a Note or something else
|
||||
switch ($objData['type']) {
|
||||
case 'Note':
|
||||
$published = strtotime($objData['published'] ?? 'now');
|
||||
$note = new \Federator\Data\ActivityPub\Common\Note();
|
||||
$note->setID($objData['id'])
|
||||
$note->setPublished($published !== false ? $published : time())
|
||||
->setID($objData['id'])
|
||||
->setSummary($objData['summary'])
|
||||
->setContent($objData['content'] ?? '')
|
||||
->setPublished(strtotime($objData['published'] ?? 'now'))
|
||||
->setURL($objData['url'] ?? $objData['id'])
|
||||
->setAttributedTo($objData['attributedTo'] ?? null)
|
||||
->addTo("https://www.w3.org/ns/activitystreams#Public");
|
||||
|
@ -220,9 +226,9 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
}
|
||||
|
||||
$undo = new \Federator\Data\ActivityPub\Common\Undo();
|
||||
$undo->setID($activity['id'] ?? "test")
|
||||
->setURL($activity['url'] ?? $activity['id'])
|
||||
->setActor($activity['actor'] ?? null);
|
||||
$undo->setActor($activity['actor'] ?? null)
|
||||
->setID($activity['id'] ?? "test")
|
||||
->setURL($activity['url'] ?? $activity['id']);
|
||||
|
||||
if (array_key_exists('cc', $activity)) {
|
||||
foreach ($activity['cc'] as $cc) {
|
||||
|
@ -240,11 +246,12 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
if (is_array($undone) && isset($undone['type'])) {
|
||||
switch ($undone['type']) {
|
||||
case 'Announce':
|
||||
$published = strtotime($undone['published'] ?? 'now');
|
||||
$announce = new \Federator\Data\ActivityPub\Common\Announce();
|
||||
$announce->setID($undone['id'] ?? null)
|
||||
->setAActor($undone['actor'] ?? null)
|
||||
->setURL($undone['url'] ?? $undone['id'])
|
||||
->setPublished(strtotime($undone['published'] ?? 'now'));
|
||||
$announce->setAActor($undone['actor'] ?? null)
|
||||
->setPublished($published !== false ? $published : time())
|
||||
->setID($undone['id'] ?? null)
|
||||
->setURL($undone['url'] ?? $undone['id']);
|
||||
|
||||
if (array_key_exists('cc', $undone)) {
|
||||
foreach ($undone['cc'] as $cc) {
|
||||
|
@ -269,11 +276,14 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
break;
|
||||
default:
|
||||
error_log("Inbox::post we currently don't support the activity type " . $activity['type'] . "\n");
|
||||
$apObject = new \Federator\Data\ActivityPub\Common\Activity($activity['type']);
|
||||
$apObject->setID($activity['id'] ?? null);
|
||||
$inboxActivity = $apObject;
|
||||
break;
|
||||
}
|
||||
|
||||
// Shared inbox
|
||||
if (!$_user) {
|
||||
if (!isset($_user)) {
|
||||
$rootDir = $_SERVER['DOCUMENT_ROOT'] . '../';
|
||||
file_put_contents(
|
||||
$rootDir . 'logs/inbox.log',
|
||||
|
@ -289,28 +299,40 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
);
|
||||
}
|
||||
|
||||
if (!isset($inboxActivity)) {
|
||||
error_log("Inbox::post couldn't create inboxActivity, aborting");
|
||||
return false;
|
||||
}
|
||||
|
||||
$sendTo = $inboxActivity->getCC();
|
||||
if ($inboxActivity->getType() === 'Undo') {
|
||||
$sendTo = $inboxActivity->getObject()->getCC();
|
||||
$object = $inboxActivity->getObject();
|
||||
if ($object !== null) {
|
||||
$sendTo = $object->getCC();
|
||||
}
|
||||
}
|
||||
|
||||
$users = [];
|
||||
|
||||
foreach ($sendTo as $receiver) {
|
||||
if (!$receiver || !is_string($receiver)) {
|
||||
if ($receiver === '' || !is_string($receiver)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_ends_with($receiver, '/followers')) {
|
||||
$users = array_merge($users, $this->fetchAllFollowers($receiver, $host));
|
||||
$followers = $this->fetchAllFollowers($receiver, $host);
|
||||
if (is_array($followers)) {
|
||||
$users = array_merge($users, $followers);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($_user !== false && !in_array($_user, $users)) {
|
||||
if ($_user !== false && !in_array($_user, $users, true)) {
|
||||
$users[] = $_user;
|
||||
}
|
||||
foreach ($users as $user) {
|
||||
if (!$user)
|
||||
if (!isset($user)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->postForUser($user, $inboxActivity);
|
||||
}
|
||||
|
@ -322,11 +344,11 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
*
|
||||
* @param string $_user user to add data to inbox
|
||||
* @param \Federator\Data\ActivityPub\Common\Activity $inboxActivity the activity that we received
|
||||
* @return string|false response
|
||||
* @return boolean response
|
||||
*/
|
||||
private function postForUser($_user, $inboxActivity)
|
||||
{
|
||||
if ($_user) {
|
||||
if (isset($_user)) {
|
||||
$dbh = $this->main->getDatabase();
|
||||
$cache = $this->main->getCache();
|
||||
$connector = $this->main->getConnector();
|
||||
|
@ -360,14 +382,14 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
*
|
||||
* @param string $collectionUrl The url of f.e. the posters followers
|
||||
* @param string $host our current host-url
|
||||
* @return array|false the names of the followers that are hosted on our server
|
||||
* @return string[] the names of the followers that are hosted on our server
|
||||
*/
|
||||
private function fetchAllFollowers(string $collectionUrl, string $host): array
|
||||
private static function fetchAllFollowers(string $collectionUrl, string $host): array
|
||||
{
|
||||
$users = [];
|
||||
|
||||
[$collectionResponse, $collectionInfo] = \Federator\Main::getFromRemote($collectionUrl, ['Accept: application/activity+json']);
|
||||
if ($collectionInfo['http_code'] !== 200) {
|
||||
if ($collectionInfo['http_code'] != 200) {
|
||||
error_log("Inbox::fetchAllFollowers Failed to fetch follower collection metadata from $collectionUrl");
|
||||
return [];
|
||||
}
|
||||
|
@ -375,7 +397,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
$collectionData = json_decode($collectionResponse, true);
|
||||
$nextPage = $collectionData['first'] ?? $collectionData['current'] ?? null;
|
||||
|
||||
if (!$nextPage) {
|
||||
if (!isset($nextPage)) {
|
||||
error_log("Inbox::fetchAllFollowers No 'first' or 'current' page in collection at $collectionUrl");
|
||||
return [];
|
||||
}
|
||||
|
@ -383,7 +405,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
// Loop through all pages
|
||||
while ($nextPage) {
|
||||
[$pageResponse, $pageInfo] = \Federator\Main::getFromRemote($nextPage, ['Accept: application/activity+json']);
|
||||
if ($pageInfo['http_code'] !== 200) {
|
||||
if ($pageInfo['http_code'] != 200) {
|
||||
error_log("Inbox::fetchAllFollowers Failed to fetch follower page at $nextPage");
|
||||
break;
|
||||
}
|
||||
|
@ -398,7 +420,7 @@ class Inbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
}
|
||||
|
||||
[$actorResponse, $actorInfo] = \Federator\Main::getFromRemote($followerUrl, ['Accept: application/activity+json']);
|
||||
if ($actorInfo['http_code'] !== 200) {
|
||||
if ($actorInfo['http_code'] != 200) {
|
||||
error_log("Inbox::fetchAllFollowers Failed to fetch actor data for follower: $followerUrl");
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
/**
|
||||
* main instance
|
||||
*
|
||||
* @var \Federator\Main $main
|
||||
* @var \Federator\Api $main
|
||||
*/
|
||||
private $main;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param \Federator\Main $main main instance
|
||||
* @param \Federator\Api $main main instance
|
||||
*/
|
||||
public function __construct($main)
|
||||
{
|
||||
|
@ -32,11 +32,14 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
/**
|
||||
* handle get call
|
||||
*
|
||||
* @param string $_user user to fetch outbox for
|
||||
* @param string|null $_user user to fetch outbox for
|
||||
* @return string|false response
|
||||
*/
|
||||
public function get($_user)
|
||||
{
|
||||
if (!isset($_user)) {
|
||||
return false;
|
||||
}
|
||||
$dbh = $this->main->getDatabase();
|
||||
$cache = $this->main->getCache();
|
||||
$connector = $this->main->getConnector();
|
||||
|
@ -87,7 +90,7 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
/**
|
||||
* handle post call
|
||||
*
|
||||
* @param string $_user user to add data to outbox
|
||||
* @param string|null $_user user to add data to outbox
|
||||
* @return string|false response
|
||||
*/
|
||||
public function post($_user)
|
||||
|
@ -104,10 +107,12 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
exit("Access denied");
|
||||
}
|
||||
|
||||
$activity = json_decode($_rawInput, true);
|
||||
$activity = is_string($_rawInput) ? json_decode($_rawInput, true) : null;
|
||||
$host = $_SERVER['SERVER_NAME'];
|
||||
|
||||
$sendTo = [];
|
||||
if (!is_array($activity)) {
|
||||
throw new \RuntimeException('Invalid activity format.');
|
||||
}
|
||||
|
||||
switch ($activity['type']) {
|
||||
case 'Create':
|
||||
|
@ -116,11 +121,12 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
}
|
||||
|
||||
$obj = $activity['object'];
|
||||
$published = strtotime($activity['published'] ?? $obj['published'] ?? 'now');
|
||||
$create = new \Federator\Data\ActivityPub\Common\Create();
|
||||
$create->setID($activity['id'])
|
||||
$create->setAActor($activity['actor'])
|
||||
->setID($activity['id'])
|
||||
->setURL($activity['id'])
|
||||
->setPublished(published: strtotime($activity['published'] ?? $obj['published'] ?? 'now'))
|
||||
->setAActor($activity['actor']);
|
||||
->setPublished($published !== false ? $published : time());
|
||||
|
||||
if (array_key_exists('cc', $activity)) {
|
||||
foreach ($activity['cc'] as $cc) {
|
||||
|
@ -136,9 +142,10 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
|
||||
switch ($obj['type']) {
|
||||
case 'Note':
|
||||
$published = strtotime($obj['published'] ?? 'now');
|
||||
$apNote = new \Federator\Data\ActivityPub\Common\Note();
|
||||
$apNote->setID($obj['id'])
|
||||
->setPublished(strtotime($obj['published'] ?? 'now'))
|
||||
->setPublished($published !== false ? $published : time())
|
||||
->setContent($obj['content'] ?? '')
|
||||
->setSummary($obj['summary'])
|
||||
->setURL($obj['url'])
|
||||
|
@ -212,11 +219,12 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
break;
|
||||
}
|
||||
|
||||
$published = strtotime((string) $activity['published']);
|
||||
$announce = new \Federator\Data\ActivityPub\Common\Announce();
|
||||
$announce->setID($activity['id'])
|
||||
->setURL($activity['id'])
|
||||
->setPublished(strtotime($activity['published'] ?? 'now'))
|
||||
->setAActor($activity['actor']);
|
||||
$announce->setAActor((string) $activity['actor'])
|
||||
->setPublished($published !== false ? $published : time())
|
||||
->setID((string) $activity['id'])
|
||||
->setURL((string) $activity['id']);
|
||||
|
||||
if (array_key_exists('cc', $activity)) {
|
||||
foreach ($activity['cc'] as $cc) {
|
||||
|
@ -232,11 +240,12 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
// Parse the shared object as a Note or something else
|
||||
switch ($objData['type']) {
|
||||
case 'Note':
|
||||
$published = strtotime($objData['published'] ?? 'now');
|
||||
$note = new \Federator\Data\ActivityPub\Common\Note();
|
||||
$note->setID($objData['id'])
|
||||
$note->setPublished($published !== false ? $published : time())
|
||||
->setID($objData['id'])
|
||||
->setSummary($objData['summary'])
|
||||
->setContent($objData['content'] ?? '')
|
||||
->setPublished(strtotime($objData['published'] ?? 'now'))
|
||||
->setURL($objData['url'] ?? $objData['id'])
|
||||
->setAttributedTo($objData['attributedTo'] ?? null)
|
||||
->addTo("https://www.w3.org/ns/activitystreams#Public");
|
||||
|
@ -264,9 +273,9 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
}
|
||||
|
||||
$undo = new \Federator\Data\ActivityPub\Common\Undo();
|
||||
$undo->setID($activity['id'] ?? "test")
|
||||
->setURL($activity['url'] ?? $activity['id'])
|
||||
->setActor($activity['actor'] ?? null);
|
||||
$undo->setActor($activity['actor'] ?? null)
|
||||
->setID($activity['id'] ?? "test")
|
||||
->setURL($activity['url'] ?? $activity['id']);
|
||||
|
||||
if (array_key_exists('cc', $activity)) {
|
||||
foreach ($activity['cc'] as $cc) {
|
||||
|
@ -284,11 +293,12 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
if (is_array($undone) && isset($undone['type'])) {
|
||||
switch ($undone['type']) {
|
||||
case 'Announce':
|
||||
$published = strtotime($undone['published'] ?? 'now');
|
||||
$announce = new \Federator\Data\ActivityPub\Common\Announce();
|
||||
$announce->setID($undone['id'] ?? null)
|
||||
->setAActor($undone['actor'] ?? null)
|
||||
->setURL($undone['url'] ?? $undone['id'])
|
||||
->setPublished(strtotime($undone['published'] ?? 'now'));
|
||||
$announce->setAActor($undone['actor'] ?? null)
|
||||
->setPublished($published !== false ? $published : time())
|
||||
->setID($undone['id'] ?? null)
|
||||
->setURL($undone['url'] ?? $undone['id']);
|
||||
|
||||
if (array_key_exists('cc', $undone)) {
|
||||
foreach ($undone['cc'] as $cc) {
|
||||
|
@ -313,31 +323,46 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
break;
|
||||
default:
|
||||
error_log("Outbox::post we currently don't support the activity type " . $activity['type'] . "\n");
|
||||
$apObject = new \Federator\Data\ActivityPub\Common\Activity($activity['type']);
|
||||
$apObject->setID($activity['id'] ?? null);
|
||||
$outboxActivity = $apObject;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isset($outboxActivity)) {
|
||||
error_log("Outbox::post couldn't create outboxActivity, aborting");
|
||||
return false;
|
||||
}
|
||||
|
||||
$sendTo = $outboxActivity->getCC();
|
||||
if ($outboxActivity->getType() === 'Undo') {
|
||||
$sendTo = $outboxActivity->getObject()->getCC();
|
||||
$object = $outboxActivity->getObject();
|
||||
if ($object !== null) {
|
||||
$sendTo = $object->getCC();
|
||||
}
|
||||
}
|
||||
|
||||
$users = [];
|
||||
|
||||
foreach ($sendTo as $receiver) {
|
||||
if (!$receiver || !is_string($receiver)) {
|
||||
if ($receiver === '' || !is_string($receiver)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (str_ends_with($receiver, '/followers')) {
|
||||
$users = array_merge($users, $this->fetchAllFollowers($receiver, $host));
|
||||
$followers = $this->fetchAllFollowers($receiver, $host);
|
||||
if (is_array($followers)) {
|
||||
$users = array_merge($users, $followers);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($_user !== false && !in_array($_user, $users)) {
|
||||
if ($_user !== false && !in_array($_user, $users, true)) {
|
||||
$users[] = $_user;
|
||||
}
|
||||
foreach ($users as $user) {
|
||||
if (!$user)
|
||||
if (!isset($user)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->postForUser($user, $outboxActivity);
|
||||
}
|
||||
|
@ -349,11 +374,11 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
*
|
||||
* @param string $_user user to add data to outbox
|
||||
* @param \Federator\Data\ActivityPub\Common\Activity $outboxActivity the activity that we received
|
||||
* @return string|false response
|
||||
* @return boolean response
|
||||
*/
|
||||
private function postForUser($_user, $outboxActivity)
|
||||
{
|
||||
if ($_user) {
|
||||
if (isset($_user)) {
|
||||
$dbh = $this->main->getDatabase();
|
||||
$cache = $this->main->getCache();
|
||||
$connector = $this->main->getConnector();
|
||||
|
@ -387,14 +412,14 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
*
|
||||
* @param string $collectionUrl The url of f.e. the posters followers
|
||||
* @param string $host our current host-url
|
||||
* @return array|false the names of the followers that are hosted on our server
|
||||
* @return string[] the names of the followers that are hosted on our server
|
||||
*/
|
||||
private function fetchAllFollowers(string $collectionUrl, string $host): array
|
||||
private static function fetchAllFollowers(string $collectionUrl, string $host): array
|
||||
{
|
||||
$users = [];
|
||||
|
||||
[$collectionResponse, $collectionInfo] = \Federator\Main::getFromRemote($collectionUrl, ['Accept: application/activity+json']);
|
||||
if ($collectionInfo['http_code'] !== 200) {
|
||||
if ($collectionInfo['http_code'] != 200) {
|
||||
error_log("Outbox::fetchAllFollowers Failed to fetch follower collection metadata from $collectionUrl");
|
||||
return [];
|
||||
}
|
||||
|
@ -402,7 +427,7 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
$collectionData = json_decode($collectionResponse, true);
|
||||
$nextPage = $collectionData['first'] ?? $collectionData['current'] ?? null;
|
||||
|
||||
if (!$nextPage) {
|
||||
if (!isset($nextPage)) {
|
||||
error_log("Outbox::fetchAllFollowers No 'first' or 'current' page in collection at $collectionUrl");
|
||||
return [];
|
||||
}
|
||||
|
@ -410,7 +435,7 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
// Loop through all pages
|
||||
while ($nextPage) {
|
||||
[$pageResponse, $pageInfo] = \Federator\Main::getFromRemote($nextPage, ['Accept: application/activity+json']);
|
||||
if ($pageInfo['http_code'] !== 200) {
|
||||
if ($pageInfo['http_code'] != 200) {
|
||||
error_log("Outbox::fetchAllFollowers Failed to fetch follower page at $nextPage");
|
||||
break;
|
||||
}
|
||||
|
@ -425,7 +450,7 @@ class Outbox implements \Federator\Api\FedUsers\FedUsersInterface
|
|||
}
|
||||
|
||||
[$actorResponse, $actorInfo] = \Federator\Main::getFromRemote($followerUrl, ['Accept: application/activity+json']);
|
||||
if ($actorInfo['http_code'] !== 200) {
|
||||
if ($actorInfo['http_code'] != 200) {
|
||||
error_log("Outbox::fetchAllFollowers Failed to fetch actor data for follower: $followerUrl");
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ class Dummy implements \Federator\Api\APIInterface
|
|||
/**
|
||||
* internal message to output
|
||||
*
|
||||
* @var string $response
|
||||
* @var string $message
|
||||
*/
|
||||
private $message = [];
|
||||
private $message = '';
|
||||
|
||||
/**
|
||||
* constructor
|
||||
|
@ -41,7 +41,7 @@ class Dummy implements \Federator\Api\APIInterface
|
|||
* run given url path
|
||||
*
|
||||
* @param array<string> $paths path array split by /
|
||||
* @param \Federator\Data\User|false $user user who is calling us
|
||||
* @param \Federator\Data\User|false $user user who is calling us @unused-param
|
||||
* @return bool true on success
|
||||
*/
|
||||
public function exec($paths, $user): bool
|
||||
|
@ -151,16 +151,26 @@ class Dummy implements \Federator\Api\APIInterface
|
|||
*/
|
||||
public function getDummy()
|
||||
{
|
||||
$this->message = json_encode([
|
||||
$dummyResponse = json_encode([
|
||||
'r1' => ' (__) ',
|
||||
'r2' => ' `------(oo) ',
|
||||
'r3' => ' || __ (__) ',
|
||||
'r4' => ' ||w || ',
|
||||
'r5' => ' '
|
||||
], JSON_PRETTY_PRINT);
|
||||
if ($dummyResponse !== false) {
|
||||
$this->message = $dummyResponse;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get function for "/v1/dummy/moo"
|
||||
*
|
||||
* @param string $_name user-id which we try to retrieve
|
||||
* @return bool
|
||||
*/
|
||||
public function getUser($_name)
|
||||
{
|
||||
error_log("Someone tried to get user: " . $_name);
|
||||
|
@ -184,7 +194,7 @@ X5FLRXVzpFziJsIpWZ6ojU9KRX8l4yvv9FL4dZIn7edbcosvnNDpnvEl+NsGnf4R
|
|||
1wIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
PEM;
|
||||
$publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n inside
|
||||
$publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n inside
|
||||
$data = [
|
||||
'iconMediaType' => $user->iconMediaType,
|
||||
'iconURL' => $user->iconURL,
|
||||
|
@ -360,9 +370,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -381,9 +395,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -402,9 +420,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -423,9 +445,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -444,9 +470,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -465,9 +495,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -486,9 +520,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -507,9 +545,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -528,9 +570,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -549,9 +595,13 @@ $publicKeyPemJsonSafe = json_encode($publicKeyPem); // gives string with \n insi
|
|||
FILE_APPEND
|
||||
);
|
||||
|
||||
$this->message = json_encode([
|
||||
$successMsg = json_encode([
|
||||
'status' => 'received',
|
||||
]);
|
||||
|
||||
if ($successMsg !== false) {
|
||||
$this->message = $successMsg;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -246,7 +246,7 @@ class Main
|
|||
|
||||
/**
|
||||
* set cache
|
||||
*
|
||||
*
|
||||
* @param \Federator\Cache\Cache $cache the new cache
|
||||
*/
|
||||
public function setCache(Cache\Cache $cache): void
|
||||
|
@ -256,12 +256,12 @@ class Main
|
|||
|
||||
/**
|
||||
* set connector
|
||||
*
|
||||
*
|
||||
* @param \Federator\Connector\Connector $connector the new connector
|
||||
*/
|
||||
public function setConnector(Connector\Connector $connector) : void
|
||||
{
|
||||
if ($this->connector) {
|
||||
if (isset($this->connector)) {
|
||||
# echo "main::setConnector Setting new connector will override old one.\n"; // TODO CHANGE TO LOG WARNING
|
||||
}
|
||||
$this->connector = $connector;
|
||||
|
@ -269,12 +269,12 @@ class Main
|
|||
|
||||
/**
|
||||
* set host
|
||||
*
|
||||
*
|
||||
* @param string $host the new host url
|
||||
*/
|
||||
public function setHost(string $host) : void
|
||||
{
|
||||
if ($this->host) {
|
||||
if (isset($this->host)) {
|
||||
# echo "main::setHost Setting new host will override old one.\n"; // TODO CHANGE TO LOG WARNING
|
||||
}
|
||||
$this->host = $host;
|
||||
|
|
|
@ -60,7 +60,7 @@ class ContentNation implements Connector
|
|||
*/
|
||||
public function getRemotePostsByUser($userId, $min, $max)
|
||||
{
|
||||
if (preg_match("#^([^@]+)@([^/]+)#", $userId, $matches) === 1) {
|
||||
if (preg_match("#^([^@]+)@([^/]+)#", $userId, $matches) == 1) {
|
||||
$userId = $matches[1];
|
||||
}
|
||||
$remoteURL = $this->service . '/api/profile/' . urlencode($userId) . '/activities';
|
||||
|
@ -129,9 +129,12 @@ class ContentNation implements Connector
|
|||
->setURL($idurl);
|
||||
$image = $activity['image'] ?? $activity['profileimg'];
|
||||
$path = $imgpath . $activity['profile'] . '/' . $image;
|
||||
$mediaType = (file_exists($path) && ($type = mime_content_type($path)) && !str_starts_with($type, 'text/'))
|
||||
|
||||
$type = file_exists($path) ? mime_content_type($path) : false;
|
||||
$mediaType = ($type !== false && !str_starts_with($type, 'text/'))
|
||||
? $type
|
||||
: 'image/jpeg';
|
||||
|
||||
$img = new \Federator\Data\ActivityPub\Common\Image();
|
||||
$img->setMediaType($mediaType)
|
||||
->setName($articleimage)
|
||||
|
@ -228,7 +231,7 @@ class ContentNation implements Connector
|
|||
*/
|
||||
public function getRemoteUserByName(string $_name)
|
||||
{
|
||||
if (preg_match("#^([^@]+)@([^/]+)#", $_name, $matches) === 1) {
|
||||
if (preg_match("#^([^@]+)@([^/]+)#", $_name, $matches) == 1) {
|
||||
$_name = $matches[1];
|
||||
}
|
||||
// validate name
|
||||
|
|
Loading…
Add table
Reference in a new issue