Add Exception for empty User::getOwnerDataById(0 return case in Protocol\ActivityPub\Transmitter::getProfile()

- Address https://github.com/friendica/friendica/issues/10473#issuecomment-882781552
- Add try-catch blocks to all references of Protocol\ActivityPub\Transmitter::getProfile()
This commit is contained in:
Hypolite Petovan 2021-07-20 13:04:25 -04:00
parent 71a0c52dc3
commit dfb043ce60
5 changed files with 53 additions and 26 deletions

View File

@ -28,6 +28,7 @@ use Friendica\Core\System;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Database\DBStructure; use Friendica\Database\DBStructure;
use Friendica\DI; use Friendica\DI;
use Friendica\Network\HTTPException;
use Friendica\Network\Probe; use Friendica\Network\Probe;
use Friendica\Protocol\ActivityNamespace; use Friendica\Protocol\ActivityNamespace;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
@ -178,8 +179,12 @@ class APContact
} }
if (Network::isLocalLink($url) && ($local_uid = User::getIdForURL($url))) { if (Network::isLocalLink($url) && ($local_uid = User::getIdForURL($url))) {
$data = Transmitter::getProfile($local_uid); try {
$local_owner = User::getOwnerDataById($local_uid); $data = Transmitter::getProfile($local_uid);
$local_owner = User::getOwnerDataById($local_uid);
} catch(HTTPException\NotFoundException $e) {
$data = null;
}
} }
if (empty($data)) { if (empty($data)) {

View File

@ -29,6 +29,7 @@ use Friendica\Core\System;
use Friendica\Database\PostUpdate; use Friendica\Database\PostUpdate;
use Friendica\DI; use Friendica\DI;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Network\HTTPException;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
/** /**
@ -112,11 +113,13 @@ class Friendica extends BaseModule
public static function rawContent(array $parameters = []) public static function rawContent(array $parameters = [])
{ {
if (ActivityPub::isRequest()) { if (ActivityPub::isRequest()) {
$data = ActivityPub\Transmitter::getProfile(0); try {
if (!empty($data)) { $data = ActivityPub\Transmitter::getProfile(0);
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');
header('Cache-Control: max-age=23200, stale-while-revalidate=23200'); header('Cache-Control: max-age=23200, stale-while-revalidate=23200');
System::jsonExit($data, 'application/activity+json'); System::jsonExit($data, 'application/activity+json');
} catch (HTTPException\NotFoundException $e) {
System::jsonError(404, ['error' => 'Record not found']);
} }
} }

View File

@ -52,12 +52,13 @@ class Profile extends BaseProfile
if (ActivityPub::isRequest()) { if (ActivityPub::isRequest()) {
$user = DBA::selectFirst('user', ['uid'], ['nickname' => $parameters['nickname']]); $user = DBA::selectFirst('user', ['uid'], ['nickname' => $parameters['nickname']]);
if (DBA::isResult($user)) { if (DBA::isResult($user)) {
// The function returns an empty array when the account is removed, expired or blocked try {
$data = ActivityPub\Transmitter::getProfile($user['uid']); $data = ActivityPub\Transmitter::getProfile($user['uid']);
if (!empty($data)) {
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Origin: *');
header('Cache-Control: max-age=23200, stale-while-revalidate=23200'); header('Cache-Control: max-age=23200, stale-while-revalidate=23200');
System::jsonExit($data, 'application/activity+json'); System::jsonExit($data, 'application/activity+json');
} catch (HTTPException\NotFoundException $e) {
System::jsonError(404, ['error' => 'Record not found']);
} }
} }

View File

@ -23,6 +23,7 @@ namespace Friendica\Network;
use DOMDocument; use DOMDocument;
use DomXPath; use DomXPath;
use Exception;
use Friendica\Core\Hook; use Friendica\Core\Hook;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
@ -2198,10 +2199,17 @@ class Probe
* *
* @param string $url * @param string $url
* @return array probed data * @return array probed data
* @throws HTTPException\InternalServerErrorException
* @throws HTTPException\NotFoundException
*/ */
private static function localProbe(string $url) private static function localProbe(string $url): array
{ {
if ($uid = User::getIdForURL($url)) { try {
$uid = User::getIdForURL($url);
if (!$uid) {
throw new HTTPException\NotFoundException('User not found.');
}
$profile = User::getOwnerDataById($uid); $profile = User::getOwnerDataById($uid);
$approfile = ActivityPub\Transmitter::getProfile($uid); $approfile = ActivityPub\Transmitter::getProfile($uid);
@ -2209,25 +2217,30 @@ class Probe
$profile['gsid'] = GServer::getID($approfile['generator']['url']); $profile['gsid'] = GServer::getID($approfile['generator']['url']);
} }
$data = ['name' => $profile['name'], 'nick' => $profile['nick'], 'guid' => $approfile['diaspora:guid'] ?? '', $data = [
'name' => $profile['name'], 'nick' => $profile['nick'], 'guid' => $approfile['diaspora:guid'] ?? '',
'url' => $profile['url'], 'addr' => $profile['addr'], 'alias' => $profile['alias'], 'url' => $profile['url'], 'addr' => $profile['addr'], 'alias' => $profile['alias'],
'photo' => Contact::getAvatarUrlForId($profile['id'], $profile['updated']), 'photo' => Contact::getAvatarUrlForId($profile['id'], $profile['updated']),
'header' => $profile['header'] ? Contact::getHeaderUrlForId($profile['id'], $profile['updated']) : '', 'header' => $profile['header'] ? Contact::getHeaderUrlForId($profile['id'], $profile['updated']) : '',
'account-type' => $profile['contact-type'], 'community' => ($profile['contact-type'] == User::ACCOUNT_TYPE_COMMUNITY), 'account-type' => $profile['contact-type'], 'community' => ($profile['contact-type'] == User::ACCOUNT_TYPE_COMMUNITY),
'keywords' => $profile['keywords'], 'location' => $profile['location'], 'about' => $profile['about'], 'keywords' => $profile['keywords'], 'location' => $profile['location'], 'about' => $profile['about'],
'hide' => !$profile['net-publish'], 'batch' => '', 'notify' => $profile['notify'], 'hide' => !$profile['net-publish'], 'batch' => '', 'notify' => $profile['notify'],
'poll' => $profile['poll'], 'request' => $profile['request'], 'confirm' => $profile['confirm'], 'poll' => $profile['poll'], 'request' => $profile['request'], 'confirm' => $profile['confirm'],
'subscribe' => $approfile['generator']['url'] . '/follow?url={uri}', 'poco' => $profile['poco'], 'subscribe' => $approfile['generator']['url'] . '/follow?url={uri}', 'poco' => $profile['poco'],
'following' => $approfile['following'], 'followers' => $approfile['followers'], 'following' => $approfile['following'], 'followers' => $approfile['followers'],
'inbox' => $approfile['inbox'], 'outbox' => $approfile['outbox'], 'inbox' => $approfile['inbox'], 'outbox' => $approfile['outbox'],
'sharedinbox' => $approfile['endpoints']['sharedInbox'], 'network' => Protocol::DFRN, 'sharedinbox' => $approfile['endpoints']['sharedInbox'], 'network' => Protocol::DFRN,
'pubkey' => $profile['upubkey'], 'baseurl' => $approfile['generator']['url'], 'gsid' => $profile['gsid'], 'pubkey' => $profile['upubkey'], 'baseurl' => $approfile['generator']['url'], 'gsid' => $profile['gsid'],
'manually-approve' => in_array($profile['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP])]; 'manually-approve' => in_array($profile['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP])
} else { ];
} catch (Exception $e) {
// Default values for non existing targets // Default values for non existing targets
$data = ['name' => $url, 'nick' => $url, 'url' => $url, 'network' => Protocol::PHANTOM, $data = [
'photo' => DI::baseUrl() . Contact::DEFAULT_AVATAR_PHOTO]; 'name' => $url, 'nick' => $url, 'url' => $url, 'network' => Protocol::PHANTOM,
'photo' => DI::baseUrl() . Contact::DEFAULT_AVATAR_PHOTO
];
} }
return self::rearrangeData($data);
return self::rearrangeData($data);
} }
} }

View File

@ -23,7 +23,6 @@ namespace Friendica\Protocol\ActivityPub;
use Friendica\Content\Feature; use Friendica\Content\Feature;
use Friendica\Content\Text\BBCode; use Friendica\Content\Text\BBCode;
use Friendica\Content\Text\Plaintext;
use Friendica\Core\Cache\Duration; use Friendica\Core\Cache\Duration;
use Friendica\Core\Logger; use Friendica\Core\Logger;
use Friendica\Core\Protocol; use Friendica\Core\Protocol;
@ -35,12 +34,12 @@ use Friendica\Model\Contact;
use Friendica\Model\Conversation; use Friendica\Model\Conversation;
use Friendica\Model\GServer; use Friendica\Model\GServer;
use Friendica\Model\Item; use Friendica\Model\Item;
use Friendica\Model\ItemURI;
use Friendica\Model\Profile;
use Friendica\Model\Photo; use Friendica\Model\Photo;
use Friendica\Model\Post; use Friendica\Model\Post;
use Friendica\Model\Profile;
use Friendica\Model\Tag; use Friendica\Model\Tag;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Network\HTTPException;
use Friendica\Protocol\Activity; use Friendica\Protocol\Activity;
use Friendica\Protocol\ActivityPub; use Friendica\Protocol\ActivityPub;
use Friendica\Protocol\Relay; use Friendica\Protocol\Relay;
@ -310,13 +309,18 @@ class Transmitter
/** /**
* Return the ActivityPub profile of the given user * Return the ActivityPub profile of the given user
* *
* @param integer $uid User ID * @param int $uid User ID
* @return array with profile data * @return array with profile data
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws HTTPException\NotFoundException
* @throws HTTPException\InternalServerErrorException
*/ */
public static function getProfile($uid) public static function getProfile(int $uid): array
{ {
$owner = User::getOwnerDataById($uid); $owner = User::getOwnerDataById($uid);
if (!isset($owner['id'])) {
DI::logger()->error('Unable to find owner data for uid', ['uid' => $uid, 'callstack' => System::callstack(20)]);
throw new HTTPException\NotFoundException('User not found.');
}
$data = ['@context' => ActivityPub::CONTEXT]; $data = ['@context' => ActivityPub::CONTEXT];
$data['id'] = $owner['url']; $data['id'] = $owner['url'];
@ -1855,10 +1859,11 @@ class Transmitter
* @param string $inbox Target inbox * @param string $inbox Target inbox
* *
* @return boolean was the transmission successful? * @return boolean was the transmission successful?
* @throws \Friendica\Network\HTTPException\InternalServerErrorException * @throws HTTPException\InternalServerErrorException
* @throws HTTPException\NotFoundException
* @throws \ImagickException * @throws \ImagickException
*/ */
public static function sendProfileUpdate($uid, $inbox) public static function sendProfileUpdate(int $uid, string $inbox): bool
{ {
$owner = User::getOwnerDataById($uid); $owner = User::getOwnerDataById($uid);
$profile = APContact::getByURL($owner['url']); $profile = APContact::getByURL($owner['url']);