X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FActivityPub.php;h=522a874fe2bd2842e21efd3b5cb076f874739a7a;hb=f56054ecc140d2f76ea0cb7ea42f94e3fb90cbf6;hp=93204e81d3722da96c65810566a4e27e87cf8181;hpb=a5d679ea959a4317be76efd8cad99bf00ba6e3d0;p=friendica.git diff --git a/src/Protocol/ActivityPub.php b/src/Protocol/ActivityPub.php index 93204e81d3..522a874fe2 100644 --- a/src/Protocol/ActivityPub.php +++ b/src/Protocol/ActivityPub.php @@ -1,6 +1,6 @@ 'http://www.w3.org/2006/vcard/ns#', - 'dfrn' => 'http://purl.org/macgirvin/dfrn/1.0/', - 'diaspora' => 'https://diasporafoundation.org/ns/', - 'litepub' => 'http://litepub.social/ns#', - 'toot' => 'http://joinmastodon.org/ns#', - 'featured' => [ - "@id" => "toot:featured", - "@type" => "@id", - ], - 'schema' => 'http://schema.org#', - 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', - 'sensitive' => 'as:sensitive', 'Hashtag' => 'as:Hashtag', - 'directMessage' => 'litepub:directMessage', - 'discoverable' => 'toot:discoverable', - 'PropertyValue' => 'schema:PropertyValue', - 'value' => 'schema:value', - ]]; + const CONTEXT = [ + 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1', + [ + 'vcard' => 'http://www.w3.org/2006/vcard/ns#', + 'dfrn' => 'http://purl.org/macgirvin/dfrn/1.0/', + 'diaspora' => 'https://diasporafoundation.org/ns/', + 'litepub' => 'http://litepub.social/ns#', + 'toot' => 'http://joinmastodon.org/ns#', + 'featured' => [ + "@id" => "toot:featured", + "@type" => "@id", + ], + 'schema' => 'http://schema.org#', + 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', + 'sensitive' => 'as:sensitive', 'Hashtag' => 'as:Hashtag', + 'quoteUrl' => 'as:quoteUrl', + 'conversation' => 'ostatus:conversation', + 'directMessage' => 'litepub:directMessage', + 'discoverable' => 'toot:discoverable', + 'PropertyValue' => 'schema:PropertyValue', + 'value' => 'schema:value', + ] + ]; const ACCOUNT_TYPES = ['Person', 'Organization', 'Service', 'Group', 'Application', 'Tombstone']; /** * Checks if the web request is done for the AP protocol @@ -85,6 +92,8 @@ class ActivityPub */ public static function isRequest(): bool { + header('Vary: Accept', false); + $isrequest = stristr($_SERVER['HTTP_ACCEPT'] ?? '', 'application/activity+json') || stristr($_SERVER['HTTP_ACCEPT'] ?? '', 'application/json') || stristr($_SERVER['HTTP_ACCEPT'] ?? '', 'application/ld+json'); @@ -113,7 +122,7 @@ class ActivityPub { $accounttype = -1; - switch($apcontact['type']) { + switch ($apcontact['type']) { case 'Person': $accounttype = User::ACCOUNT_TYPE_PERSON; break; @@ -232,12 +241,20 @@ class ActivityPub /** * Fetch items from AP endpoints * - * @param string $url Address of the endpoint - * @param integer $uid Optional user id + * @param string $url Address of the endpoint + * @param integer $uid Optional user id + * @param integer $start_timestamp Internally used parameter to stop fetching after some time * @return array Endpoint items */ - public static function fetchItems(string $url, int $uid = 0): array + public static function fetchItems(string $url, int $uid = 0, int $start_timestamp = 0): array { + $start_timestamp = $start_timestamp ?: time(); + + if ((time() - $start_timestamp) > 60) { + Logger::info('Fetch time limit reached', ['url' => $url, 'uid' => $uid]); + return []; + } + $data = self::fetchContent($url, $uid); if (empty($data)) { return []; @@ -248,13 +265,13 @@ class ActivityPub } elseif (!empty($data['first']['orderedItems'])) { $items = $data['first']['orderedItems']; } elseif (!empty($data['first']) && is_string($data['first']) && ($data['first'] != $url)) { - return self::fetchItems($data['first'], $uid); + return self::fetchItems($data['first'], $uid, $start_timestamp); } else { return []; } if (!empty($data['next']) && is_string($data['next'])) { - $items = array_merge($items, self::fetchItems($data['next'], $uid)); + $items = array_merge($items, self::fetchItems($data['next'], $uid, $start_timestamp)); } return $items; @@ -273,4 +290,38 @@ class ActivityPub { return !empty(APContact::getByURL($url, $update)); } + + public static function isAcceptedRequester(int $uid = 0): bool + { + $called_by = System::callstack(1); + + $signer = HTTPSignature::getSigner('', $_SERVER); + if (!$signer) { + Logger::debug('No signer or invalid signature', ['uid' => $uid, 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'called_by' => $called_by]); + return false; + } + + $apcontact = APContact::getByURL($signer); + if (empty($apcontact)) { + Logger::info('APContact not found', ['uid' => $uid, 'handle' => $signer, 'called_by' => $called_by]); + return false; + } + + if (empty($apcontact['gsid'] || empty($apcontact['baseurl']))) { + Logger::debug('No server found', ['uid' => $uid, 'signer' => $signer, 'called_by' => $called_by]); + return false; + } + + $contact = Contact::getByURL($signer, false, ['id', 'baseurl', 'gsid']); + if (!empty($contact) && Contact\User::isBlocked($contact['id'], $uid)) { + Logger::info('Requesting contact is blocked', ['uid' => $uid, 'id' => $contact['id'], 'signer' => $signer, 'baseurl' => $contact['baseurl'], 'called_by' => $called_by]); + return false; + } + + // @todo Look for user blocked domains + + Logger::debug('Server is an accepted requester', ['uid' => $uid, 'id' => $apcontact['gsid'], 'url' => $apcontact['baseurl'], 'signer' => $signer, 'called_by' => $called_by]); + + return true; + } }